Example #1
0
int main(int argc, char *argv[])
{
	int ret,pipefd;
	char *lxcpath = argv[1];
	char logpath[PATH_MAX];
	sigset_t mask;

	if (argc != 3) {
		fprintf(stderr,
			"Usage: lxc-monitord lxcpath sync-pipe-fd\n\n"
			"NOTE: lxc-monitord is intended for use by lxc internally\n"
			"      and does not need to be run by hand\n\n");
		exit(EXIT_FAILURE);
	}

	ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log",
		       lxcpath);
	if (ret < 0 || ret >= sizeof(logpath))
		return EXIT_FAILURE;

	ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath);
	if (ret)
		INFO("Failed to open log file %s, log will be lost", lxcpath);

	pipefd = atoi(argv[2]);

	if (sigfillset(&mask) ||
	    sigdelset(&mask, SIGILL)  ||
	    sigdelset(&mask, SIGSEGV) ||
	    sigdelset(&mask, SIGBUS)  ||
	    sigdelset(&mask, SIGTERM) ||
	    sigprocmask(SIG_BLOCK, &mask, NULL)) {
		SYSERROR("failed to set signal mask");
		return -1;
	}

	signal(SIGILL,  lxc_monitord_sig_handler);
	signal(SIGSEGV, lxc_monitord_sig_handler);
	signal(SIGBUS,  lxc_monitord_sig_handler);
	signal(SIGTERM, lxc_monitord_sig_handler);

	ret = EXIT_FAILURE;
	memset(&mon, 0, sizeof(mon));
	mon.lxcpath = lxcpath;
	if (lxc_mainloop_open(&mon.descr)) {
		ERROR("failed to create mainloop");
		goto out;
	}

	if (lxc_monitord_create(&mon)) {
		goto out;
	}

	/* sync with parent, we're ignoring the return from write
	 * because regardless if it works or not, the following
	 * close will sync us with the parent process. the
	 * if-empty-statement construct is to quiet the
	 * warn-unused-result warning.
	 */
	if (write(pipefd, "S", 1)) ;
	close(pipefd);

	if (lxc_monitord_mainloop_add(&mon)) {
		ERROR("failed to add mainloop handlers");
		goto out;
	}

	NOTICE("monitoring lxcpath %s", mon.lxcpath);
	for(;;) {
		ret = lxc_mainloop(&mon.descr, 1000 * 30);
		if (mon.clientfds_cnt <= 0)
		{
			NOTICE("no clients for 30 seconds, exiting");
			break;
		}
	}

	lxc_mainloop_close(&mon.descr);
	lxc_monitord_cleanup();
	ret = EXIT_SUCCESS;
	NOTICE("monitor exiting");
out:
	return ret;
}
Example #2
0
int main(int argc, char *argv[])
{
	int ret, pipefd;
	char logpath[PATH_MAX];
	sigset_t mask;
	char *lxcpath = argv[1];
	bool mainloop_opened = false;
	bool monitord_created = false;
	struct lxc_log log;

	if (argc != 3) {
		fprintf(stderr,
			"Usage: lxc-monitord lxcpath sync-pipe-fd\n\n"
			"NOTE: lxc-monitord is intended for use by lxc internally\n"
			"      and does not need to be run by hand\n\n");
		exit(EXIT_FAILURE);
	}

	ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log",
		       (strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH));
	if (ret < 0 || ret >= sizeof(logpath))
		exit(EXIT_FAILURE);

	log.name = NULL;
	log.file = logpath;
	log.level = "DEBUG";
	log.prefix = "lxc-monitord";
	log.quiet = 0;
	log.lxcpath = lxcpath;

	ret = lxc_log_init(&log);
	if (ret)
		INFO("Failed to open log file %s, log will be lost", lxcpath);
	lxc_log_options_no_override();

	if (lxc_safe_int(argv[2], &pipefd) < 0)
		exit(EXIT_FAILURE);

	if (sigfillset(&mask) ||
	    sigdelset(&mask, SIGILL)  ||
	    sigdelset(&mask, SIGSEGV) ||
	    sigdelset(&mask, SIGBUS)  ||
	    sigdelset(&mask, SIGTERM) ||
	    pthread_sigmask(SIG_BLOCK, &mask, NULL)) {
		SYSERROR("Failed to set signal mask");
		exit(EXIT_FAILURE);
	}

	signal(SIGILL,  lxc_monitord_sig_handler);
	signal(SIGSEGV, lxc_monitord_sig_handler);
	signal(SIGBUS,  lxc_monitord_sig_handler);
	signal(SIGTERM, lxc_monitord_sig_handler);

	if (sigsetjmp(mark, 1) != 0)
		goto on_signal;

	ret = EXIT_FAILURE;

	memset(&mon, 0, sizeof(mon));
	mon.lxcpath = lxcpath;
	if (lxc_mainloop_open(&mon.descr)) {
		ERROR("Failed to create mainloop");
		goto on_error;
	}
	mainloop_opened = true;

	if (lxc_monitord_create(&mon))
		goto on_error;
	monitord_created = true;

	/* sync with parent, we're ignoring the return from write
	 * because regardless if it works or not, the following
	 * close will sync us with the parent process. the
	 * if-empty-statement construct is to quiet the
	 * warn-unused-result warning.
	 */
	if (lxc_write_nointr(pipefd, "S", 1))
		;
	close(pipefd);

	if (lxc_monitord_mainloop_add(&mon)) {
		ERROR("Failed to add mainloop handlers");
		goto on_error;
	}

	NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s",
	       lxc_raw_getpid(), mon.lxcpath);

	for (;;) {
		ret = lxc_mainloop(&mon.descr, 1000 * 30);
		if (ret) {
			ERROR("mainloop returned an error");
			break;
		}

		if (mon.clientfds_cnt <= 0) {
			NOTICE("No remaining clients. lxc-monitord is exiting");
			break;
		}

		if (quit == LXC_MAINLOOP_CLOSE) {
			NOTICE("Got quit command. lxc-monitord is exitting");
			break;
		}
	}

on_signal:
	ret = EXIT_SUCCESS;

on_error:
	if (monitord_created)
		lxc_monitord_cleanup();

	if (mainloop_opened)
		lxc_mainloop_close(&mon.descr);

	exit(ret);
}