Example #1
0
struct iobroker_set *iobroker_create(void)
{
	iobroker_set *iobs = NULL;

	iobs = calloc(1, sizeof(*iobs));
	if (!iobs) {
		goto error_out;
	}

	iobs->max_fds = iobroker_max_usable_fds();
	iobs->iobroker_fds = calloc(iobs->max_fds, sizeof(iobroker_fd *));
	if (!iobs->iobroker_fds) {
		goto error_out;
	}

#ifdef IOBROKER_USES_EPOLL
	{
		int flags;

		iobs->ep_events = calloc(iobs->max_fds, sizeof(struct epoll_event));
		if (!iobs->ep_events) {
			goto error_out;
		}

		iobs->epfd = epoll_create(iobs->max_fds);
		if (iobs->epfd < 0) {
			goto error_out;
		}

		flags = fcntl(iobs->epfd, F_GETFD);
		flags |= FD_CLOEXEC;
		fcntl(iobs->epfd, F_SETFD, flags);
	}
#elif !defined(IOBROKER_USES_SELECT)
	iobs->pfd = calloc(iobs->max_fds, sizeof(struct pollfd));
	if (!iobs->pfd)
		goto error_out;
#endif

	return iobs;

error_out:
	if (iobs) {
		int errsv = errno;
#ifdef IOBROKER_USES_EPOLL
		close(iobs->epfd);
		if (iobs->ep_events)
			free(iobs->ep_events);
#endif
		if (iobs->iobroker_fds)
			free(iobs->iobroker_fds);
		free(iobs);
		errno = errsv;
	}
	return NULL;
}
Example #2
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);
}
Example #3
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;
}