Esempio n. 1
0
/* daemon-specific node manipulation */
static void post_process_nodes(void)
{
	uint i, x;

	ldebug("post processing %d masters, %d pollers, %d peers",
	       num_masters, num_pollers, num_peers);

	for (i = 0; i < num_nodes; i++) {
		merlin_node *node = node_table[i];

		if (!node) {
			lerr("node is null. i is %d. num_nodes is %d. wtf?", i, num_nodes);
			continue;
		}

		if (!node->sain.sin_port)
			node->sain.sin_port = htons(default_port);

		node->action = node_action_handler;

		node->ioc = iocache_create(MERLIN_IOC_BUFSIZE);
		if (node->ioc == NULL) {
			lerr("Failed to malloc(%i) for io cache for node %s. Aborting",
				 MERLIN_IOC_BUFSIZE, node->name);
		}

		/*
		 * this lets us support multiple merlin instances on
		 * a single system, but all instances on the same
		 * system will be marked at the same time, so we skip
		 * them on the second pass here.
		 */
		if (node->flags & MERLIN_NODE_FIXED_SRCPORT) {
			continue;
		}

		if (node->sain.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
			node->flags |= MERLIN_NODE_FIXED_SRCPORT;
			ldebug("Using fixed source-port for local %s node %s",
				   node_type(node), node->name);
			continue;
		}
		for (x = i + 1; x < num_nodes; x++) {
			merlin_node *nx = node_table[x];
			if (node->sain.sin_addr.s_addr == nx->sain.sin_addr.s_addr) {
				ldebug("Using fixed source-port for %s node %s",
				       node_type(node), node->name);
				ldebug("Using fixed source-port for %s node %s",
				       node_type(nx), nx->name);
				node->flags |= MERLIN_NODE_FIXED_SRCPORT;
				nx->flags |= MERLIN_NODE_FIXED_SRCPORT;

				if (node->sain.sin_port == nx->sain.sin_port) {
					lwarn("Nodes %s and %s have same ip *and* same port. Voodoo?",
					      node->name, nx->name);
				}
			}
		}
	}
}
Esempio n. 2
0
static int test_delimiter(const char *delim, unsigned int delim_len)
{
	struct strcode sc[] = {
		ADDSTR("Charlie Chaplin"),
		ADDSTR("Madonna Something something"),
		ADDSTR("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla turpis augue, laoreet eleifend ultricies et, tincidunt non felis. Suspendisse vitae accumsan dolor. Vivamus posuere venenatis dictum. Integer hendrerit est eget turpis scelerisque porttitor. Donec ullamcorper sodales purus, sed bibendum odio porttitor sit amet. Donec pretium sem ac sapien iaculis feugiat. Quisque commodo consequat quam, ac cursus est sodales euismod. Sed nec massa felis, sit amet varius dui. Morbi fermentum varius tellus, eget tempus felis imperdiet quis. Praesent congue auctor ligula, a tempor ipsum malesuada at. Proin pharetra tempor adipiscing. Aenean egestas tellus vitae arcu sagittis non ultrices turpis cursus."),
		ADDSTR("Emma Blomqvist"),
		ADDSTR("Random message"),
		ADDSTR("Random\0message\0with\0nuls\0embedded"),
		{ NULL, 0, },
	};
	int i;
	iocache *ioc;

	ioc = iocache_create(512 * 1024);
	if (!test(ioc != NULL, "iocache_create must work"))
		crash("can't test with no available memory");

	for (i = 0; sc[i].str; i++) {
		memcpy(&ioc->ioc_buf[ioc->ioc_buflen], sc[i].str, sc[i].len);
		ioc->ioc_buflen += sc[i].len;
		memcpy(ioc->ioc_buf + ioc->ioc_buflen, delim, delim_len);
		ioc->ioc_buflen += delim_len;
	}

	for (i = 0; sc[i].str; i++) {
		char *ptr;
		unsigned long len;
		int error = 0;
		ptr = iocache_use_delim(ioc, delim, delim_len, &len);
		t_req(ptr != NULL);
		if (!ptr) {
			printf("Null pointer. What weird shit is this??\n");
			exit(1);
		}
		test(len == sc[i].len, "len check, string %d, delim_len %d", i, delim_len);
		test(!memcmp(ptr, sc[i].str, len), "memcmp() check, string %d, delim_len %d", i, delim_len);
		if (error) {
			printf("delim_len: %d. i: %d; len: %lu; sc[i].len: %d\n",
				   delim_len, i, len, sc[i].len);
			printf("sc[i].str: %s\n", sc[i].str);
			printf("ptr      : %s\n", ptr);
			printf("strlen(sc[i].str): %lu\n", strlen(sc[i].str));
			printf("strlen(ptr)      : %lu\n", strlen(ptr));
			exit(1);
		}
	}
	iocache_destroy(ioc);
	return 0;
}
Esempio n. 3
0
struct worker_process *spawn_worker(void (*init_func)(void *), void *init_arg)
{
	int sv[2];
	int pid;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0)
		return NULL;

	pid = fork();
	if (pid < 0) {
		close(sv[0]);
		close(sv[1]);
		return NULL;
	}

	/* parent leaves the child */
	if (pid) {
		worker_process *worker = calloc(1, sizeof(worker_process));
		close(sv[1]);
		if (!worker) {
			kill(SIGKILL, pid);
			close(sv[0]);
			return NULL;
		}
		worker->sd = sv[0];
		worker->pid = pid;
		worker->ioc = iocache_create(1 * 1024 * 1024);

		/* 1 socket for master, 2 fd's for each child */
		worker->max_jobs = (iobroker_max_usable_fds() - 1) / 2;
		worker->jobs = calloc(worker->max_jobs, sizeof(worker_job *));

		return worker;
	}

	/* child closes parent's end of socket and gets busy */
	close(sv[0]);

	if (init_func) {
		init_func(init_arg);
	}
	enter_worker(sv[1]);

	/* not reached, ever */
	exit(EXIT_FAILURE);
}
Esempio n. 4
0
static simple_worker *spawn_worker(void (*init_func)(void *), void *init_arg)
{
	int sv[2];
	int pid;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0)
		return NULL;

	pid = fork();
	if (pid < 0) {
		close(sv[0]);
		close(sv[1]);
		return NULL;
	}

	/* parent leaves the child */
	if (pid) {
		simple_worker *worker = calloc(1, sizeof(simple_worker));
		close(sv[1]);
		if (!worker) {
			kill(SIGKILL, pid);
			close(sv[0]);
			return NULL;
		}
		worker->sd = sv[0];
		worker->pid = pid;
		worker->ioc = iocache_create(1 * 1024 * 1024);
		return worker;
	}

	/* child closes parent's end of socket and gets busy */
	close(sv[0]);

	if (init_func) {
		init_func(init_arg);
	}
	enter_worker(sv[1], start_cmd);

	/* not reached, ever */
	exit(EXIT_FAILURE);
}
Esempio n. 5
0
static int receive_command(int sd, int events, void *discard)
{
	int ioc_ret;
	char *buf;
	unsigned long size;

	if (!ioc) {
		ioc = iocache_create(512 * 1024);
	}
	ioc_ret = iocache_read(ioc, sd);

	/* master closed the connection, so we exit */
	if (ioc_ret == 0) {
		iobroker_close(iobs, sd);
		exit_worker();
	}
	if (ioc_ret < 0) {
		/* XXX: handle this somehow */
	}

#if 0
	/* debug-volley */
	buf = iocache_use_size(ioc, ioc_ret);
	write(master_sd, buf, ioc_ret);
	return 0;
#endif
	/*
	 * now loop over all inbound messages in the iocache.
	 * Since KV_TERMINATOR is a nul-byte, they're separated by 3 nuls
	 */
	while ((buf = iocache_use_delim(ioc, MSG_DELIM, MSG_DELIM_LEN_RECV, &size))) {
		struct kvvec *kvv;
		/* we must copy vars here, as we preserve them for the response */
		kvv = buf2kvvec(buf, (unsigned int)size, KV_SEP, PAIR_SEP, KVVEC_COPY);
		if (kvv)
			spawn_job(kvv);
	}

	return 0;
}
Esempio n. 6
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;
}