int get_masters(time_t stoptime) { struct catalog_query *cq; struct nvpair *nv; int i = 0; //nvpair pointer array iterator if(!catalog_host) { catalog_host = strdup(CATALOG_HOST); catalog_port = CATALOG_PORT; } cq = catalog_query_create(catalog_host, catalog_port, stoptime ); if(!cq) { fprintf(stderr, "failed to query catalog server %s:%d: %s \n",catalog_host,catalog_port,strerror(errno)); exit(EXIT_FAILURE); return 0; } while((nv = catalog_query_read(cq,stoptime))) { resize_catalog(i); if(strcmp(nvpair_lookup_string(nv, "type"), CATALOG_TYPE_WORK_QUEUE_MASTER) == 0) { global_catalog[i] = nv; //make the global catalog point to this memory that nv references i++; //only increment i when a master nvpair is found }else{ nvpair_delete(nv); //free the memory so something valid can take its place } } resize_catalog(i); global_catalog[i] = NULL; catalog_query_delete(cq); return 1; }
static int server_table_load(time_t stoptime) { struct catalog_query *q; struct jx *j; char *key; void *item; if((last_update + update_interval) > time(0)) { return 1; } if(!server_table) { server_table = hash_table_create(0, 0); if(!server_table) return 0; } if(inhibit_catalog_queries) { debug(D_CHIRP, "catalog queries disabled\n"); return 1; } hash_table_firstkey(server_table); while(hash_table_nextkey(server_table, &key, &item)) { hash_table_remove(server_table, key); jx_delete(item); } debug(D_CHIRP, "querying catalog at %s:%d", CATALOG_HOST, CATALOG_PORT); q = catalog_query_create(CATALOG_HOST, CATALOG_PORT, stoptime); if(!q) return 0; while((j = catalog_query_read(q, stoptime))) { char name[CHIRP_PATH_MAX]; const char *type, *hname; int port; type = jx_lookup_string(j, "type"); if(type && !strcmp(type, "chirp")) { hname = jx_lookup_string(j, "name"); if(hname) { port = jx_lookup_integer(j, "port"); if(!port) port = CHIRP_PORT; sprintf(name, "%s:%d", hname, port); hash_table_insert(server_table, name, j); } else { jx_delete(j); } } else { jx_delete(j); } } catalog_query_delete(q); last_update = time(0); return 1; }
struct list *get_masters_from_catalog(const char *catalog_host, int catalog_port, struct list *regex_list) { struct catalog_query *q; struct nvpair *nv; struct list *ml; struct work_queue_master *m; char *regex; time_t timeout = 60, stoptime; stoptime = time(0) + timeout; q = catalog_query_create(catalog_host, catalog_port, stoptime); if(!q) { fprintf(stderr, "Failed to query catalog server at %s:%d\n", catalog_host, catalog_port); return NULL; } ml = list_create(); if(!ml) return NULL; while((nv = catalog_query_read(q, stoptime))) { if(strcmp(nvpair_lookup_string(nv, "type"), CATALOG_TYPE_WORK_QUEUE_MASTER) == 0) { m = parse_work_queue_master_nvpair(nv); if(m) { if(regex_list) { // Matched preferred masters int match_found = 0; list_first_item(regex_list); while((regex = (char *)list_next_item(regex_list))) { if(whole_string_match_regex(m->proj, regex)) { debug(D_WQ, "Master matched: %s -> %s\n", regex, m->proj); list_push_head(ml, m); match_found = 1; break; } } if(match_found == 0) { free_work_queue_master(m); } } else { list_push_head(ml, m); } } else { fprintf(stderr, "Failed to parse a work queue master record!\n"); } } nvpair_delete(nv); } // Must delete the query otherwise it would occupy 1 tcp connection forever! catalog_query_delete(q); return ml; }
int get_pool_decisions_from_catalog(const char *catalog_host, int catalog_port, const char *proj, struct list *decisions) { struct catalog_query *q; struct nvpair *nv; time_t timeout = 60, stoptime; stoptime = time(0) + timeout; if(!decisions) { fprintf(stderr, "No list to store pool decisions.\n"); return 0; } q = catalog_query_create(catalog_host, catalog_port, stoptime); if(!q) { fprintf(stderr, "Failed to query catalog server at %s:%d\n", catalog_host, catalog_port); return 0; } // multiple pools while((nv = catalog_query_read(q, stoptime))) { if(strcmp(nvpair_lookup_string(nv, "type"), CATALOG_TYPE_WORK_QUEUE_POOL) == 0) { struct work_queue_pool *p; p = parse_work_queue_pool_nvpair(nv); debug(D_WQ, "pool %s's decision: %s\n", p->name, p->decision); int x = workers_by_item(p->decision, proj); if(x >= 0) { struct pool_info *pi; pi = (struct pool_info *)xxmalloc(sizeof(*pi)); strncpy(pi->name, p->name, WORK_QUEUE_POOL_NAME_MAX); pi->count = x; list_push_tail(decisions, pi); } free(p->decision); free(p); } nvpair_delete(nv); } // Must delete the query otherwise it would occupy 1 tcp connection forever! catalog_query_delete(q); return 1; }
int main(int argc, char *argv[]) { struct catalog_query *cq; struct nvpair *nv; work_queue_status_parse_command_line_arguments(argc, argv); if(optind > argc) { work_queue_status_show_help("work_queue_status"); exit(EXIT_FAILURE); } cq = catalog_query_create(CATALOG_HOST, CATALOG_PORT, time(0) + Work_Queue_Status_Timeout); if(!cq) { fprintf(stderr, "couldn't query catalog %s:%d: %s\n", CATALOG_HOST, CATALOG_PORT, strerror(errno)); return 1; } if(Work_Queue_Status_Mode == MODE_TABLE) nvpair_print_table_header(stdout, headers); while((nv = catalog_query_read(cq, time(0) + Work_Queue_Status_Timeout))) { if(strcmp(nvpair_lookup_string(nv, "type"), CATALOG_TYPE_WORK_QUEUE_MASTER) == 0) { if(Work_Queue_Status_Mode == MODE_TABLE) nvpair_print_table(nv, stdout, headers); else nvpair_print_text(nv, stdout); } nvpair_delete(nv); } if(Work_Queue_Status_Mode == MODE_TABLE) nvpair_print_table_footer(stdout, headers); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct catalog_query *q; struct nvpair *n; time_t timeout = 60, stoptime; const char *catalog_host = 0; signed char c; int i; int count = 0; int mode = MODE_TABLE; INT64_T total = 0, avail = 0; const char *filter_name = 0; const char *filter_value = 0; debug_config(argv[0]); static struct option long_options[] = { {"catalog", required_argument, 0, 'c'}, {"debug", required_argument, 0, 'd'}, {"debug-file", required_argument, 0, 'o'}, {"debug-rotate-max", required_argument, 0, 'O'}, {"server-space", required_argument, 0, 'A'}, {"all", no_argument, 0, 'a'}, {"timeout", required_argument, 0, 't'}, {"brief", no_argument, 0, 's'}, {"verbose", no_argument, 0, 'l'}, {"totals", no_argument, 0, 'T'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) { switch (c) { case 'a': show_all_types = 1; break; case 'c': catalog_host = optarg; break; case 'd': debug_flags_set(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'A': minavail = string_metric_parse(optarg); break; case 'o': debug_config_file(optarg); break; case 'O': debug_config_file_size(string_metric_parse(optarg)); break; case 'v': cctools_version_print(stdout, argv[0]); return 1; case 's': mode = MODE_SHORT; break; case 'l': mode = MODE_LONG; break; case 'T': mode = MODE_TOTAL; break; case 'h': default: show_help(argv[0]); return 1; } } cctools_version_debug(D_DEBUG, argv[0]); if(argc - optind == 0) { // fine, keep going } else if((argc - optind) == 1) { filter_name = "name"; filter_value = argv[optind]; } else if((argc - optind) == 2) { filter_name = argv[optind]; filter_value = argv[optind + 1]; } else { show_help(argv[0]); return 1; } stoptime = time(0) + timeout; q = catalog_query_create(catalog_host, 0, stoptime); if(!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } if(mode == MODE_TABLE) { nvpair_print_table_header(stdout, headers); } while((n = catalog_query_read(q, stoptime))) { table[count++] = n; } qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); for(i = 0; i < count; i++) { const char *etype = nvpair_lookup_string(table[i], "type"); if(!show_all_types) { if(etype) { if(!strcmp(etype, "chirp") || !strcmp(etype, "catalog")) { /* ok, keep going */ } else { continue; } } else { continue; } } if(minavail != 0) { if(minavail > nvpair_lookup_integer(table[i], "avail")) { continue; } } if(filter_name) { const char *v = nvpair_lookup_string(table[i], filter_name); if(!v || strcmp(filter_value, v)) continue; } if(mode == MODE_SHORT) { const char *t = nvpair_lookup_string(table[i], "type"); if(t && !strcmp(t, "chirp")) { printf("%s:%d\n", nvpair_lookup_string(table[i], "name"), (int) nvpair_lookup_integer(table[i], "port")); } } else if(mode == MODE_LONG) { nvpair_print_text(table[i], stdout); } else if(mode == MODE_TABLE) { nvpair_print_table(table[i], stdout, headers); } else if(mode == MODE_TOTAL) { avail += nvpair_lookup_integer(table[i], "avail"); total += nvpair_lookup_integer(table[i], "total"); } } if(mode == MODE_TOTAL) { printf("NODES: %4d\n", count); printf("TOTAL: %6sB\n", string_metric(total, -1, 0)); printf("AVAIL: %6sB\n", string_metric(avail, -1, 0)); printf("INUSE: %6sB\n", string_metric(total - avail, -1, 0)); } if(mode == MODE_TABLE) { nvpair_print_table_footer(stdout, headers); } return 0; }
int main(int argc, char *argv[]) { enum { LONGOPT_SERVER_LASTHEARDFROM = INT_MAX-0, LONGOPT_SERVER_PROJECT = INT_MAX-1, LONGOPT_WHERE = INT_MAX-2, }; static const struct option long_options[] = { {"all", no_argument, 0, 'a'}, {"brief", no_argument, 0, 's'}, {"catalog", required_argument, 0, 'c'}, {"debug", required_argument, 0, 'd'}, {"debug-file", required_argument, 0, 'o'}, {"debug-rotate-max", required_argument, 0, 'O'}, {"help", no_argument, 0, 'h'}, {"server-lastheardfrom", required_argument, 0, LONGOPT_SERVER_LASTHEARDFROM}, {"server-project", required_argument, 0, LONGOPT_SERVER_PROJECT}, {"server-space", required_argument, 0, 'A'}, {"timeout", required_argument, 0, 't'}, {"totals", no_argument, 0, 'T'}, {"verbose", no_argument, 0, 'l'}, {"version", no_argument, 0, 'v'}, {"where", required_argument, 0, LONGOPT_WHERE }, {0, 0, 0, 0} }; struct catalog_query *q; struct jx *j; time_t timeout = 60, stoptime; const char *catalog_host = 0; int i; int c; int count = 0; int mode = MODE_TABLE; INT64_T sum_total = 0, sum_avail = 0; const char *filter_name = 0; const char *filter_value = 0; const char *where_expr = "true"; int show_all_types = 0; const char *server_project = NULL; time_t server_lastheardfrom = 0; uint64_t server_avail = 0; debug_config(argv[0]); while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) { switch (c) { case 'a': show_all_types = 1; break; case 'c': catalog_host = optarg; break; case 'd': debug_flags_set(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'A': server_avail = string_metric_parse(optarg); break; case 'o': debug_config_file(optarg); break; case 'O': debug_config_file_size(string_metric_parse(optarg)); break; case 'v': cctools_version_print(stdout, argv[0]); return 1; case 's': mode = MODE_SHORT; break; case 'l': mode = MODE_LONG; break; case 'T': mode = MODE_TOTAL; break; case LONGOPT_SERVER_LASTHEARDFROM: server_lastheardfrom = time(0)-string_time_parse(optarg); break; case LONGOPT_SERVER_PROJECT: server_project = xxstrdup(optarg); break; case LONGOPT_WHERE: where_expr = optarg; break; case 'h': default: show_help(argv[0]); return 1; } } cctools_version_debug(D_DEBUG, argv[0]); if(argc - optind == 0) { // fine, keep going } else if((argc - optind) == 1) { filter_name = "name"; filter_value = argv[optind]; } else if((argc - optind) == 2) { filter_name = argv[optind]; filter_value = argv[optind + 1]; } else { show_help(argv[0]); return 1; } stoptime = time(0) + timeout; const char *query_expr; if(show_all_types) { query_expr = where_expr; } else { query_expr = string_format("%s && (type==\"chirp\" || type==\"catalog\")",where_expr); } struct jx *jexpr = jx_parse_string(query_expr); if(!jexpr) { fprintf(stderr,"invalid expression: %s\n",query_expr); return 1; } q = catalog_query_create(catalog_host, 0, jexpr, stoptime); if(!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } if(mode == MODE_TABLE) { jx_table_print_header(headers,stdout); } else if(mode==MODE_LONG) { printf("[\n"); } while((j = catalog_query_read(q, stoptime))) { table[count++] = j; } catalog_query_delete(q); qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); for(i = 0; i < count; i++) { const char *lastheardfrom = jx_lookup_string(table[i], "lastheardfrom"); if (lastheardfrom && (time_t)strtoul(lastheardfrom, NULL, 10) < server_lastheardfrom) continue; const char *avail = jx_lookup_string(table[i], "avail"); if (avail && strtoul(avail, NULL, 10) < server_avail) continue; const char *project = jx_lookup_string(table[i], "project"); if (server_project && (project == NULL || !(strcmp(project, server_project) == 0))) continue; if(filter_name) { const char *v = jx_lookup_string(table[i], filter_name); if(!v || strcmp(filter_value, v)) continue; } if(mode == MODE_SHORT) { const char *t = jx_lookup_string(table[i], "type"); if(t && !strcmp(t, "chirp")) { printf("%s:%d\n", jx_lookup_string(table[i], "name"), (int) jx_lookup_integer(table[i], "port")); } } else if(mode == MODE_LONG) { if(i!=0) printf(",\n"); jx_print_stream(table[i],stdout); } else if(mode == MODE_TABLE) { jx_table_print(headers, table[i], stdout); } else if(mode == MODE_TOTAL) { sum_avail += jx_lookup_integer(table[i], "avail"); sum_total += jx_lookup_integer(table[i], "total"); } } for(i=0;i<count;i++) { jx_delete(table[i]); } if(mode == MODE_TOTAL) { printf("NODES: %4d\n", count); printf("TOTAL: %6sB\n", string_metric(sum_total, -1, 0)); printf("AVAIL: %6sB\n", string_metric(sum_avail, -1, 0)); printf("INUSE: %6sB\n", string_metric(sum_total - sum_avail, -1, 0)); } else if(mode == MODE_TABLE) { jx_table_print_footer(headers,stdout); } else if(mode==MODE_LONG) { printf("\n]\n"); } return 0; }
/* * Obtains information from the Catalog, format it, and make return it to user. */ int main(int argc, char** argv) { static const struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"project", required_argument, 0, 'N'}, {"server", required_argument, 0, 's'}, {"timeout", required_argument, 0, 't'}, {"username", required_argument, 0, 'u'}, {0, 0, 0, 0} }; struct catalog_query *q; struct jx *j; int c; unsigned int i; time_t timeout = 60; char* catalog_host = NULL; char* username = NULL; char* project = NULL; char* server = NULL; while ((c = getopt_long(argc, argv, "N:t:u:w:s:h", long_options, NULL)) > -1) { switch (c) { case 'N': project = xxstrdup(optarg); break; case 't': timeout = string_time_parse(optarg); break; case 'u': username = xxstrdup(optarg); break; case 's': server = xxstrdup(optarg); break; case 'h': default: show_help(argv[0]); return 1; } } //setup address if(server==NULL){ catalog_host = CATALOG_HOST; } //make query struct jx *jexpr = jx_operator( JX_OP_EQ, jx_symbol("type"), jx_string("makeflow") ); if (project) { jexpr = jx_operator( JX_OP_AND, jexpr, jx_operator( JX_OP_EQ, jx_symbol("project"), jx_string(project) ) ); } if (username) { jexpr = jx_operator( JX_OP_AND, jexpr, jx_operator( JX_OP_EQ, jx_symbol("username"), jx_string(username) ) ); } time_t stoptime = time(0) + timeout; unsigned int count = 0; //create catalog_query from jx q = catalog_query_create(catalog_host, jexpr, stoptime); if (!q) { fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno)); return 1; } while ((j = catalog_query_read(q, stoptime))) { table[count++] = j; } catalog_query_delete(q);//all done with connection //sort qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries); //print them out printf("%-10s %-18s %6s %6s %6s %6s %6s %6s %6s\n", "OWNER", "PROJECT", "JOBS", "WAIT", "RUN", "COMP", "ABRT", "FAIL", "TYPE"); for(i=0; i<count; i++){ printf("%-10s %-18s %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6s\n", jx_lookup_string(table[i], "owner"), jx_lookup_string(table[i], "project"), jx_lookup_integer(table[i], "total"), jx_lookup_integer(table[i], "waiting"), jx_lookup_integer(table[i], "running"), jx_lookup_integer(table[i], "completed"), jx_lookup_integer(table[i], "aborted"), jx_lookup_integer(table[i], "failed"), jx_lookup_string(table[i], "batch_type") ); } printf("\n");//be polite //cleanup for(i=0;i<count;i++) { jx_delete(table[i]); } //done return (EXIT_SUCCESS); }
CONFUGA_IAPI int confugaS_catalog_sync (confuga *C) { static const char SQL[] = "SELECT COUNT(*) FROM Confuga.StorageNode WHERE strftime('%s', 'now', '-2 minutes') <= lastheardfrom;" "BEGIN IMMEDIATE TRANSACTION;" "UPDATE Confuga.StorageNode" " SET address = ?, avail = ?, backend = ?, bytes_read = ?, bytes_written = ?, cpu = ?, cpus = ?, lastheardfrom = ?, load1 = ?, load5 = ?, load15 = ?, memory_avail = ?, memory_total = ?, minfree = ?, name = ?, opsys = ?, opsysversion = ?, owner = ?, port = ?, starttime = ?, total = ?, total_ops = ?, url = ?, version = ?" " WHERE hostport = ? || ':' || ? OR" " hostport = ? || ':' || ? OR" " 'chirp://' || hostport = ?;" "END TRANSACTION;"; int rc; sqlite3 *db = C->db; sqlite3_stmt *stmt = NULL; const char *current = SQL; time_t stoptime = time(NULL)+15; struct catalog_query *Q = NULL; struct nvpair *nv = NULL; sqlcatch(sqlite3_prepare_v2(db, current, -1, &stmt, ¤t)); sqlcatchcode(sqlite3_step(stmt), SQLITE_ROW); if (sqlite3_column_int(stmt, 0) > 0) { rc = 0; goto out; } sqlcatch(sqlite3_finalize(stmt); stmt = NULL); debug(D_DEBUG|D_CONFUGA, "syncing with catalog"); Q = catalog_query_create(C->catalog_host, C->catalog_port, stoptime); CATCH(Q == NULL ? errno : 0); /* FIXME sqlcatch is silent about EAGAIN, what should we do? */ sqlcatch(sqlite3_prepare_v2(db, current, -1, &stmt, ¤t)); sqlcatchcode(sqlite3_step(stmt), SQLITE_DONE); sqlcatch(sqlite3_finalize(stmt); stmt = NULL); sqlcatch(sqlite3_prepare_v2(db, current, -1, &stmt, ¤t)); while ((nv = catalog_query_read(Q, stoptime))) { const char *type = nvpair_lookup_string(nv, "type"); if (type && strcmp(type, "chirp") == 0) { int n = 1; /* UPDATE */ sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "address"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "avail"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "backend"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "bytes_read"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "bytes_written"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "cpu"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "cpus"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "lastheardfrom"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "load1"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "load5"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "load15"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "memory_avail"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "memory_total"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "minfree"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "name"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "opsys"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "opsysversion"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "owner"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "port"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "starttime"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "total"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "total_ops"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "url"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "version"), -1, SQLITE_TRANSIENT)); /* WHERE hostport = ? */ sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "name"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "port"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "address"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "port"), -1, SQLITE_TRANSIENT)); sqlcatch(sqlite3_bind_text(stmt, n++, nvpair_lookup_string(nv, "url"), -1, SQLITE_TRANSIENT)); sqlcatchcode(sqlite3_step(stmt), SQLITE_DONE); sqlcatch(sqlite3_reset(stmt)); sqlcatch(sqlite3_clear_bindings(stmt)); } } sqlcatch(sqlite3_finalize(stmt); stmt = NULL); sqlcatch(sqlite3_prepare_v2(db, current, -1, &stmt, ¤t)); sqlcatchcode(sqlite3_step(stmt), SQLITE_DONE); sqlcatch(sqlite3_finalize(stmt); stmt = NULL); rc = 0; goto out; out: if (Q) catalog_query_delete(Q); sqlite3_finalize(stmt); sqlend(db); return rc; }