Example #1
0
int main(int argc, char *argv[])
{
	int ret;
	pid_t pid;
	lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
	lxc_attach_command_t command;

	ret = lxc_caps_init();
	if (ret)
		return ret;

	ret = lxc_arguments_parse(&my_args, argc, argv);
	if (ret)
		return ret;

	if (!my_args.log_file)
		my_args.log_file = "none";

	ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			   my_args.progname, my_args.quiet, my_args.lxcpath[0]);
	if (ret)
		return ret;
	lxc_log_options_no_override();

	if (remount_sys_proc)
		attach_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS;
	if (elevated_privileges)
		attach_options.attach_flags &= ~(elevated_privileges);
	attach_options.namespaces = namespace_flags;
	attach_options.personality = new_personality;
	attach_options.env_policy = env_policy;
	attach_options.extra_env_vars = extra_env;
	attach_options.extra_keep_env = extra_keep;

	if (my_args.argc) {
		command.program = my_args.argv[0];
		command.argv = (char**)my_args.argv;
		ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_command, &command, &attach_options, &pid);
	} else {
		ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_shell, NULL, &attach_options, &pid);
	}

	if (ret < 0)
		return -1;

	ret = lxc_wait_for_pid_status(pid);
	if (ret < 0)
		return -1;

	if (WIFEXITED(ret))
		return WEXITSTATUS(ret);

	return -1;
}
Example #2
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool ret;

	if (lxc_arguments_parse(&my_args, argc, argv))
		exit(1);

	if (!my_args.log_file)
		my_args.log_file = "none";

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		exit(1);

	lxc_log_options_no_override();

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "System error loading %s\n", my_args.name);
		exit(1);
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name);
		lxc_container_put(c);
		exit(1);
	}

	if (!c->is_defined(c)) {
		fprintf(stderr, "%s is not defined\n", my_args.name);
		lxc_container_put(c);
		exit(1);
	}


	if (do_restore)
		ret = restore(c);
	else if (do_pre_checkpoint)
		ret = pre_checkpoint(c);
	else
		ret = checkpoint(c);

	return !ret;
}
Example #3
0
File: lxc_stop.c Project: Blub/lxc
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool s;
	int ret = EXIT_FAILURE;

	if (lxc_arguments_parse(&my_args, argc, argv))
		exit(ret);

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		exit(ret);
	lxc_log_options_no_override();

	/* Set default timeout */
	if (my_args.timeout == -2) {
		if (my_args.hardstop)
			my_args.timeout = 0;
		else
			my_args.timeout = 60;
	}

	if (my_args.nowait)
		my_args.timeout = 0;

	/* some checks */
	if (!my_args.hardstop && my_args.timeout < -1) {
		fprintf(stderr, "invalid timeout\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.nokill) {
		fprintf(stderr, "-k can't be used with --nokill\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.reboot) {
		fprintf(stderr, "-k can't be used with -r\n");
		exit(ret);
	}

	if (my_args.hardstop && my_args.timeout) {
		fprintf(stderr, "-k doesn't allow timeouts\n");
		exit(ret);
	}

	if (my_args.nolock && !my_args.hardstop) {
		fprintf(stderr, "--nolock may only be used with -k\n");
		exit(ret);
	}

	/* shortcut - if locking is bogus, we should be able to kill
	 * containers at least */
	if (my_args.nolock) {
		ret = lxc_cmd_stop(my_args.name, my_args.lxcpath[0]);
		exit(ret);
	}

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "Error opening container\n");
		goto out;
	}

	if (my_args.rcfile) {
		c->clear_config(c);
		if (!c->load_config(c, my_args.rcfile)) {
			fprintf(stderr, "Failed to load rcfile\n");
			goto out;
		}
		c->configfile = strdup(my_args.rcfile);
		if (!c->configfile) {
			fprintf(stderr, "Out of memory setting new config filename\n");
			goto out;
		}
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
		goto out;
	}

	if (!c->is_running(c)) {
		fprintf(stderr, "%s is not running\n", c->name);
		/* Per our manpage we need to exit with exit code:
		 * 2: The specified container exists but was not running.
		 */
		ret = 2;
		goto out;
	}

	/* kill */
	if (my_args.hardstop) {
		ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE;
		goto out;
	}

	/* reboot */
	if (my_args.reboot) {
		ret = do_reboot_and_check(&my_args, c) < 0 ? EXIT_SUCCESS : EXIT_FAILURE;
		goto out;
	}

	/* shutdown */
	s = c->shutdown(c, my_args.timeout);
	if (!s) {
		if (my_args.timeout == 0)
			ret = EXIT_SUCCESS;
		else if (my_args.nokill)
			ret = EXIT_FAILURE;
		else
			ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE;
	} else {
		ret = EXIT_SUCCESS;
	}

out:
	lxc_container_put(c);
	exit(ret);
}
Example #4
0
int main(int argc, char *argv[])
{
	int count = 0;
	int i = 0;
	int ret = 0;
	struct lxc_container **containers = NULL;
	struct lxc_list *cmd_groups_list = NULL;
	struct lxc_list *c_groups_list = NULL;
	struct lxc_list *it, *next;
	char *const default_start_args[] = {
		"/sbin/init",
		NULL,
	};

	if (lxc_arguments_parse(&my_args, argc, argv))
		return 1;

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		return 1;
	lxc_log_options_no_override();

	count = list_defined_containers(NULL, NULL, &containers);

	if (count < 0)
		return 1;

	qsort(&containers[0], count, sizeof(struct lxc_container *), cmporder);

	if (my_args.groups && !my_args.all)
		cmd_groups_list = get_list((char*)my_args.groups, ",");

	for (i = 0; i < count; i++) {
		struct lxc_container *c = containers[i];

		if (!c->may_control(c)) {
			lxc_container_put(c);
			continue;
		}

		if (!my_args.ignore_auto &&
		    get_config_integer(c, "lxc.start.auto") != 1) {
			lxc_container_put(c);
			continue;
		}

		if (!my_args.all) {
			/* Filter by group */
			c_groups_list = get_config_list(c, "lxc.group");

			ret = lists_contain_common_entry(cmd_groups_list, c_groups_list);

			if (c_groups_list) {
				lxc_list_for_each_safe(it, c_groups_list, next) {
					lxc_list_del(it);
					free(it->elem);
					free(it);
				}
				free(c_groups_list);
			}

			if (ret == 0) {
				lxc_container_put(c);
				continue;
			}
		}
Example #5
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",
		       (strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH ) );
	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);
	lxc_log_options_no_override();

	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("pid:%d monitoring lxcpath %s", getpid(), mon.lxcpath);
	for(;;) {
		ret = lxc_mainloop(&mon.descr, 1000 * 30);
		if (mon.clientfds_cnt <= 0)
		{
			NOTICE("no remaining clients, exiting");
			break;
		}
	}

	lxc_mainloop_close(&mon.descr);
	lxc_monitord_cleanup();
	ret = EXIT_SUCCESS;
	NOTICE("monitor exiting");
out:
	if (ret == 0)
		return 0;
	return 1;
}
Example #6
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	char *cmd, *dev_name, *dst_name;
	int ret = 1;

	if (geteuid() != 0) {
		ERROR("%s must be run as root", argv[0]);
		exit(1);
	}

	if (lxc_arguments_parse(&my_args, argc, argv))
		goto err;

	if (!my_args.log_file)
		my_args.log_file = "none";

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		goto err;
	lxc_log_options_no_override();

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		ERROR("%s doesn't exist", my_args.name);
		goto err;
	}

	if (!c->is_running(c)) {
		ERROR("Container %s is not running.", c->name);
		goto err1;
	}

	if (my_args.argc < 2) {
		ERROR("Error: no command given (Please see --help output)");
		goto err1;
	}

	cmd = my_args.argv[0];
	dev_name = my_args.argv[1];
	if (my_args.argc < 3)
		dst_name = dev_name;
	else
		dst_name = my_args.argv[2];

	if (strcmp(cmd, "add") == 0) {
		if (is_interface(dev_name, 1)) {
			ret = c->attach_interface(c, dev_name, dst_name);
		} else {
			ret = c->add_device_node(c, dev_name, dst_name);
		}
		if (ret != true) {
			ERROR("Failed to add %s to %s.", dev_name, c->name);
			ret = 1;
			goto err1;
		}
		INFO("Add %s to %s.", dev_name, c->name);
	} else if (strcmp(cmd, "del") == 0) {
		if (is_interface(dev_name, c->init_pid(c))) {
			ret = c->detach_interface(c, dev_name, dst_name);
		} else {
			ret = c->remove_device_node(c, dev_name, dst_name);
		}
		if (ret != true) {
			ERROR("Failed to del %s from %s.", dev_name, c->name);
			ret = 1;
			goto err1;
		}
		INFO("Delete %s from %s.", dev_name, c->name);
	} else {
		ERROR("Error: Please use add or del (Please see --help output)");
		goto err1;
	}
	exit(0);
err1:
	lxc_container_put(c);
err:
	exit(ret);
}
Example #7
0
int main(int argc, char *argv[])
{
	pid_t pid;
	int err;
	char **aargv;
	sigset_t mask, omask;
	int i, have_status = 0, shutdown = 0;
	int opt;
	char *lxcpath = NULL, *name = NULL, *logpriority = NULL;

	while ((opt = getopt_long(argc, argv, "n:l:qP:", options, NULL)) != -1) {
		switch(opt) {
		case 'n':
			name = optarg;
			break;
		case 'l':
			logpriority = optarg;
			break;
		case 'q':
			quiet = 1;
 			break;
		case 'P':
			lxcpath = optarg;
			break;
		default: /* '?' */
			usage();
			exit(EXIT_FAILURE);
		}
	}

	if (lxc_caps_init())
		exit(EXIT_FAILURE);

	err = lxc_log_init(name, name ? NULL : "none", logpriority,
			   basename(argv[0]), quiet, lxcpath);
	if (err < 0)
		exit(EXIT_FAILURE);
	lxc_log_options_no_override();

	if (!argv[optind]) {
		ERROR("missing command to launch");
		exit(EXIT_FAILURE);
	}

	aargv = &argv[optind];

        /*
	 * mask all the signals so we are safe to install a
	 * signal handler and to fork
	 */
	if (sigfillset(&mask) ||
	    sigdelset(&mask, SIGILL) ||
	    sigdelset(&mask, SIGSEGV) ||
	    sigdelset(&mask, SIGBUS) ||
	    sigprocmask(SIG_SETMASK, &mask, &omask)) {
		SYSERROR("failed to set signal mask");
		exit(EXIT_FAILURE);
	}

	for (i = 1; i < NSIG; i++) {
		struct sigaction act;

		/* Exclude some signals: ILL, SEGV and BUS are likely to
		 * reveal a bug and we want a core. STOP and KILL cannot be
		 * handled anyway: they're here for documentation.
		 */
		if (i == SIGILL ||
		    i == SIGSEGV ||
		    i == SIGBUS ||
		    i == SIGSTOP ||
		    i == SIGKILL ||
		    i == 32 || i == 33)
			continue;

		if (sigfillset(&act.sa_mask) ||
		    sigdelset(&act.sa_mask, SIGILL) ||
		    sigdelset(&act.sa_mask, SIGSEGV) ||
		    sigdelset(&act.sa_mask, SIGBUS) ||
		    sigdelset(&act.sa_mask, SIGSTOP) ||
		    sigdelset(&act.sa_mask, SIGKILL)) {
			ERROR("failed to set signal");
			exit(EXIT_FAILURE);
		}

		act.sa_flags = 0;
		act.sa_handler = interrupt_handler;
		if (sigaction(i, &act, NULL) && errno != EINVAL) {
			SYSERROR("failed to sigaction");
			exit(EXIT_FAILURE);
		}
	}

	lxc_setup_fs();

	if (lxc_caps_reset())
		exit(EXIT_FAILURE);

	pid = fork();

	if (pid < 0)
		exit(EXIT_FAILURE);

	if (!pid) {

		/* restore default signal handlers */
		for (i = 1; i < NSIG; i++)
			signal(i, SIG_DFL);

		if (sigprocmask(SIG_SETMASK, &omask, NULL)) {
			SYSERROR("failed to set signal mask");
			exit(EXIT_FAILURE);
		}

		NOTICE("about to exec '%s'", aargv[0]);

		execvp(aargv[0], aargv);
		ERROR("failed to exec: '%s' : %m", aargv[0]);
		exit(err);
	}

	/* let's process the signals now */
	if (sigdelset(&omask, SIGALRM) ||
	    sigprocmask(SIG_SETMASK, &omask, NULL)) {
		SYSERROR("failed to set signal mask");
		exit(EXIT_FAILURE);
	}

	/* no need of other inherited fds but stderr */
	close(fileno(stdin));
	close(fileno(stdout));

	err = EXIT_SUCCESS;
	for (;;) {
		int status;
		pid_t waited_pid;

		switch (was_interrupted) {

		case 0:
			break;

		case SIGTERM:
			if (!shutdown) {
				shutdown = 1;
				kill(-1, SIGTERM);
				alarm(1);
			}
			break;

		case SIGALRM:
			kill(-1, SIGKILL);
			break;

		default:
			kill(pid, was_interrupted);
			break;
		}

		was_interrupted = 0;
		waited_pid = wait(&status);
		if (waited_pid < 0) {
			if (errno == ECHILD)
				goto out;
			if (errno == EINTR)
				continue;

			ERROR("failed to wait child : %s",
			      strerror(errno));
			goto out;
		}

		/* reset timer each time a process exited */
		if (shutdown)
			alarm(1);

		/*
		 * keep the exit code of started application
		 * (not wrapped pid) and continue to wait for
		 * the end of the orphan group.
		 */
		if (waited_pid == pid && !have_status) {
			err = lxc_error_set_and_log(waited_pid, status);
			have_status = 1;
		}
	}
out:
	return err;
}
Example #8
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);
}
Example #9
0
int main(int argc, char *argv[])
{
	struct lxc_container *c;
	bool s;
	int ret = 1;

	if (lxc_arguments_parse(&my_args, argc, argv))
		return 1;

	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
		return 1;
	lxc_log_options_no_override();

	/* Set default timeout */
	if (my_args.timeout == -2) {
		if (my_args.hardstop) {
			my_args.timeout = 0;
		}
		else {
			my_args.timeout = 60;
		}
	}

	if (my_args.nowait) {
		my_args.timeout = 0;
	}

	/* some checks */
	if (!my_args.hardstop && my_args.timeout < -1) {
		fprintf(stderr, "invalid timeout\n");
		return 1;
	}

	if (my_args.hardstop && my_args.nokill) {
		fprintf(stderr, "-k can't be used with --nokill\n");
		return 1;
	}

	if (my_args.hardstop && my_args.reboot) {
		fprintf(stderr, "-k can't be used with -r\n");
		return 1;
	}

	if (my_args.hardstop && my_args.timeout) {
		fprintf(stderr, "-k doesn't allow timeouts\n");
		return 1;
	}

	if (my_args.nolock && !my_args.hardstop) {
		fprintf(stderr, "--nolock may only be used with -k\n");
		return 1;
	}

	/* shortcut - if locking is bogus, we should be able to kill
	 * containers at least */
	if (my_args.nolock)
		return lxc_cmd_stop(my_args.name, my_args.lxcpath[0]);

	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
	if (!c) {
		fprintf(stderr, "Error opening container\n");
		goto out;
	}

	if (!c->may_control(c)) {
		fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
		goto out;
	}

	if (!c->is_running(c)) {
		fprintf(stderr, "%s is not running\n", c->name);
		ret = 2;
		goto out;
	}

	/* kill */
	if (my_args.hardstop) {
		ret = c->stop(c) ? 0 : 1;
		goto out;
	}

	/* reboot */
	if (my_args.reboot) {
		ret = do_reboot_and_check(&my_args, c);
		goto out;
	}

	/* shutdown */
	s = c->shutdown(c, my_args.timeout);
	if (!s) {
		if (my_args.timeout == 0)
			ret = 0;
		else if (my_args.nokill)
			ret = 1;
		else
			ret = c->stop(c) ? 0 : 1;
	} else
		ret = 0;

out:
	lxc_container_put(c);
	return ret;
}