/* a service for registering workers */ static int register_worker(int sd, char *buf, unsigned int len) { int i, is_global = 1; struct kvvec *info; struct wproc_worker *worker; logit(NSLOG_INFO_MESSAGE, TRUE, "wproc: Registry request: %s\n", buf); if (!(worker = calloc(1, sizeof(*worker)))) { logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: Failed to allocate worker: %s\n", strerror(errno)); return 500; } info = buf2kvvec(buf, len, '=', ';', 0); if (info == NULL) { free(worker); logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: Failed to parse registration request\n"); return 500; } worker->sd = sd; worker->ioc = iocache_create(1 * 1024 * 1024); iobroker_unregister(nagios_iobs, sd); iobroker_register(nagios_iobs, sd, worker, handle_worker_result); for(i = 0; i < info->kv_pairs; i++) { struct key_value *kv = &info->kv[i]; if (!strcmp(kv->key, "name")) { worker->name = strdup(kv->value); } else if (!strcmp(kv->key, "pid")) { worker->pid = atoi(kv->value); } else if (!strcmp(kv->key, "max_jobs")) { worker->max_jobs = atoi(kv->value); } else if (!strcmp(kv->key, "plugin")) { struct wproc_list *command_handlers; is_global = 0; if (!(command_handlers = dkhash_get(specialized_workers, kv->value, NULL))) { command_handlers = calloc(1, sizeof(struct wproc_list)); command_handlers->wps = calloc(1, sizeof(struct wproc_worker**)); command_handlers->len = 1; command_handlers->wps[0] = worker; dkhash_insert(specialized_workers, strdup(kv->value), NULL, command_handlers); } else { command_handlers->len++; command_handlers->wps = realloc(command_handlers->wps, command_handlers->len * sizeof(struct wproc_worker**)); command_handlers->wps[command_handlers->len - 1] = worker; } worker->wp_list = command_handlers; } } if (!worker->max_jobs) { /* * each worker uses two filedescriptors per job, one to * connect to the master and about 13 to handle libraries * and memory allocation, so this guesstimate shouldn't * be too far off (for local workers, at least). */ worker->max_jobs = (iobroker_max_usable_fds() / 2) - 50; } worker->jobs = fanout_create(worker->max_jobs); if (is_global) { workers.len++; workers.wps = realloc(workers.wps, workers.len * sizeof(struct wproc_worker *)); workers.wps[workers.len - 1] = worker; worker->wp_list = &workers; } wproc_num_workers_online++; kvvec_destroy(info, 0); nsock_printf_nul(sd, "OK"); /* signal query handler to release its iocache for this one */ return QH_TAKEOVER; }
int main(int argc, char **argv) { dkhash_table *tx, *t; unsigned int x; int ret, r2; struct test_data s; char *p1, *p2; char *strs[10]; char tmp[32]; t_set_colors(0); t_start("dkhash basic test"); t = dkhash_create(512); p1 = strdup("a not-so secret value"); dkhash_insert(t, "nisse", NULL, p1); ok_int(dkhash_num_entries_max(t), 1, "Added one entry, so that's max"); ok_int(dkhash_num_entries_added(t), 1, "Added one entry, so one added"); ok_int(dkhash_table_size(t), 512, "Table must be sized properly"); ok_int(dkhash_collisions(t), 0, "One entry, so zero collisions"); p2 = dkhash_get(t, "nisse", NULL); test(p1 == p2, "get should get what insert set"); dkhash_insert(t, "kalle", "bananas", p1); p2 = dkhash_get(t, "kalle", "bezinga"); test(p1 != p2, "we should never get the wrong key"); ok_int(2, dkhash_num_entries(t), "should be 2 entries after 2 inserts"); p2 = dkhash_remove(t, "kalle", "bezinga"); ok_int(2, dkhash_num_entries(t), "should be 2 entries after 2 inserts and 1 failed remove"); ok_int(0, dkhash_num_entries_removed(t), "should be 0 removed entries after failed remove"); p2 = dkhash_remove(t, "kalle", "bananas"); test(p1 == p2, "dkhash_remove() should return removed data"); ok_int(dkhash_num_entries(t), 1, "should be 1 entries after 2 inserts and 1 successful remove"); p2 = dkhash_remove(t, "nisse", NULL); test(p1 == p2, "dkhash_remove() should return removed data"); ret = t_end(); t_reset(); /* lots of tests below, so we shut up while they're running */ t_verbose = 0; t_start("dkhash_walk_data() test"); memset(&s, 0, sizeof(s)); /* first we set up the dkhash-tables */ tx = dkhash_create(16); for (x = 0; x < ARRAY_SIZE(keys); x++) { dkhash_insert(tx, keys[x].k1, NULL, ddup(x, 0, 0)); dkhash_insert(tx, keys[x].k2, NULL, ddup(x, 0, 0)); dkhash_insert(tx, keys[x].k1, keys[x].k2, ddup(x, 0, 0)); s.x += 3; ok_int(s.x, dkhash_num_entries(tx), "x table adding"); } ok_int(s.x, dkhash_num_entries(tx), "x table done adding"); for (x = 0; x < ARRAY_SIZE(keys); x++) { del.x = x; del.i = del.j = 0; ok_int(s.x, dkhash_num_entries(tx), "x table pre-delete"); s.x -= 3; dkhash_walk_data(tx, del_matching); ok_int(s.x, dkhash_num_entries(tx), "x table post-delete"); } test(0 == dkhash_num_entries(tx), "x table post all ops"); test(0 == dkhash_check_table(tx), "x table consistency post all ops"); dkhash_debug_table(tx, 0); r2 = t_end(); ret = r2 ? r2 : ret; t_reset(); for (x = 0; x < 10; x++) { sprintf(tmp, "string %d", x); strs[x] = strdup(tmp); } t_start("dkhash single bucket add remove forward"); t = dkhash_create(1); for (x = 0; x < 10; x++) { dkhash_insert(t, strs[x], NULL, strs[x]); } for (x = 0; x < 10; x++) { p1 = strs[x]; p2 = dkhash_remove(t, p1, NULL); test(p1 == p2, "remove should return a value"); } r2 = t_end(); ret = r2 ? r2 : ret; t_reset(); t_start("dkhash single bucket add remove backward"); t = dkhash_create(1); for (x = 0; x < 10; x++) { dkhash_insert(t, strs[x], NULL, strs[x]); } for (x = 9; x; x--) { p1 = strs[x]; p2 = dkhash_remove(t, p1, NULL); test(p1 == p2, "remove should return a value"); } dkhash_destroy(t); r2 = t_end(); return r2 ? r2 : ret; }