Example #1
0
/* 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;
}
Example #2
0
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;
}