Example #1
0
File: start.c Project: rowhit/lxc
void lxc_fini(const char *name, struct lxc_handler *handler)
{
	/* The STOPPING state is there for future cleanup code
	 * which can take awhile
	 */
	lxc_set_state(name, handler, STOPPING);
	lxc_set_state(name, handler, STOPPED);

	if (run_lxc_hooks(name, "post-stop", handler->conf, handler->lxcpath, NULL))
		ERROR("failed to run post-stop hooks for container '%s'.", name);

	/* reset mask set by setup_signal_fd */
	if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
		WARN("failed to restore sigprocmask");

	lxc_console_delete(&handler->conf->console);
	lxc_delete_tty(&handler->conf->tty_info);
	close(handler->conf->maincmd_fd);
	handler->conf->maincmd_fd = -1;
	free(handler->name);
	if (handler->ttysock[0] != -1) {
		close(handler->ttysock[0]);
		close(handler->ttysock[1]);
	}
	cgroup_destroy(handler);
	free(handler);
}
Example #2
0
void lxc_fini(const char *name, struct lxc_handler *handler)
{
	int i, rc;
	pid_t self = getpid();
	char *namespaces[LXC_NS_MAX+1];
	size_t namespace_count = 0;

	/* The STOPPING state is there for future cleanup code
	 * which can take awhile
	 */
	lxc_set_state(name, handler, STOPPING);

	for (i = 0; i < LXC_NS_MAX; i++) {
		if (handler->nsfd[i] != -1) {
			rc = asprintf(&namespaces[namespace_count], "%s:/proc/%d/fd/%d",
			              ns_info[i].proc_name, self, handler->nsfd[i]);
			if (rc == -1) {
				SYSERROR("failed to allocate memory");
				break;
			}
			++namespace_count;
		}
	}
	namespaces[namespace_count] = NULL;
	if (run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces))
		ERROR("failed to run stop hooks for container '%s'.", name);
	while (namespace_count--)
		free(namespaces[namespace_count]);
	for (i = 0; i < LXC_NS_MAX; i++) {
		if (handler->nsfd[i] != -1) {
			close(handler->nsfd[i]);
			handler->nsfd[i] = -1;
		}
	}
	lxc_set_state(name, handler, STOPPED);

	if (run_lxc_hooks(name, "post-stop", handler->conf, handler->lxcpath, NULL))
		ERROR("failed to run post-stop hooks for container '%s'.", name);

	/* reset mask set by setup_signal_fd */
	if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
		WARN("failed to restore sigprocmask");

	lxc_console_delete(&handler->conf->console);
	lxc_delete_tty(&handler->conf->tty_info);
	close(handler->conf->maincmd_fd);
	handler->conf->maincmd_fd = -1;
	free(handler->name);
	if (handler->ttysock[0] != -1) {
		close(handler->ttysock[0]);
		close(handler->ttysock[1]);
	}
	if (handler->conf->ephemeral == 1 && handler->conf->reboot != 1) {
		lxc_destroy_container_on_signal(handler, name);
	}
	cgroup_destroy(handler);
	free(handler);
}
Example #3
0
File: start.c Project: rowhit/lxc
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char *lxcpath)
{
	struct lxc_handler *handler;

	handler = malloc(sizeof(*handler));
	if (!handler)
		return NULL;

	memset(handler, 0, sizeof(*handler));

	handler->ttysock[0] = handler->ttysock[1] = -1;
	handler->conf = conf;
	handler->lxcpath = lxcpath;
	handler->pinfd = -1;

	lsm_init();

	handler->name = strdup(name);
	if (!handler->name) {
		ERROR("failed to allocate memory");
		goto out_free;
	}

	if (lxc_cmd_init(name, handler, lxcpath))
		goto out_free_name;

	if (lxc_read_seccomp_config(conf) != 0) {
		ERROR("failed loading seccomp policy");
		goto out_close_maincmd_fd;
	}

	/* Begin by setting the state to STARTING */
	if (lxc_set_state(name, handler, STARTING)) {
		ERROR("failed to set state '%s'", lxc_state2str(STARTING));
		goto out_close_maincmd_fd;
	}

	/* Start of environment variable setup for hooks */
	if (name && setenv("LXC_NAME", name, 1)) {
		SYSERROR("failed to set environment variable for container name");
	}
	if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) {
		SYSERROR("failed to set environment variable for config path");
	}
	if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) {
		SYSERROR("failed to set environment variable for rootfs mount");
	}
	if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) {
		SYSERROR("failed to set environment variable for rootfs mount");
	}
	if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) {
		SYSERROR("failed to set environment variable for console path");
	}
	if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) {
		SYSERROR("failed to set environment variable for console log");
	}
	/* End of environment variable setup for hooks */

	if (run_lxc_hooks(name, "pre-start", conf, handler->lxcpath, NULL)) {
		ERROR("failed to run pre-start hooks for container '%s'.", name);
		goto out_aborting;
	}

	/* the signal fd has to be created before forking otherwise
	 * if the child process exits before we setup the signal fd,
	 * the event will be lost and the command will be stuck */
	handler->sigfd = setup_signal_fd(&handler->oldmask);
	if (handler->sigfd < 0) {
		ERROR("failed to set sigchild fd handler");
		goto out_delete_tty;
	}

	/* do this after setting up signals since it might unblock SIGWINCH */
	if (lxc_console_create(conf)) {
		ERROR("failed to create console");
		goto out_restore_sigmask;
	}

	if (ttys_shift_ids(conf) < 0) {
		ERROR("Failed to shift tty into container");
		goto out_restore_sigmask;
	}

	INFO("'%s' is initialized", name);
	return handler;

out_restore_sigmask:
	sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
out_delete_tty:
	lxc_delete_tty(&conf->tty_info);
out_aborting:
	lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd:
	close(conf->maincmd_fd);
	conf->maincmd_fd = -1;
out_free_name:
	free(handler->name);
	handler->name = NULL;
out_free:
	free(handler);
	return NULL;
}
Example #4
0
File: start.c Project: hfuCN/lxc
void lxc_fini(const char *name, struct lxc_handler *handler)
{
	int i, rc;
	pid_t self = getpid();
	char *namespaces[LXC_NS_MAX+1];
	size_t namespace_count = 0;

	/* The STOPPING state is there for future cleanup code which can take
	 * awhile.
	 */
	lxc_set_state(name, handler, STOPPING);

	for (i = 0; i < LXC_NS_MAX; i++) {
		if (handler->nsfd[i] != -1) {
			rc = asprintf(&namespaces[namespace_count], "%s:/proc/%d/fd/%d",
			              ns_info[i].proc_name, self, handler->nsfd[i]);
			if (rc == -1) {
				SYSERROR("Failed to allocate memory.");
				break;
			}
			++namespace_count;
		}
	}
	namespaces[namespace_count] = NULL;

	if (handler->conf->reboot && setenv("LXC_TARGET", "reboot", 1))
		SYSERROR("Failed to set environment variable: LXC_TARGET=reboot.");

	if (!handler->conf->reboot && setenv("LXC_TARGET", "stop", 1))
		SYSERROR("Failed to set environment variable: LXC_TARGET=stop.");

	if (run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces))
		ERROR("Failed to run lxc.hook.stop for container \"%s\".", name);

	while (namespace_count--)
		free(namespaces[namespace_count]);
	for (i = 0; i < LXC_NS_MAX; i++) {
		if (handler->nsfd[i] != -1) {
			close(handler->nsfd[i]);
			handler->nsfd[i] = -1;
		}
	}

	if (handler->netnsfd >= 0) {
		close(handler->netnsfd);
		handler->netnsfd = -1;
	}

	lxc_set_state(name, handler, STOPPED);

	if (run_lxc_hooks(name, "post-stop", handler->conf, handler->lxcpath, NULL)) {
		ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", name);
		if (handler->conf->reboot) {
			WARN("Container will be stopped instead of rebooted.");
			handler->conf->reboot = 0;
			if (setenv("LXC_TARGET", "stop", 1))
				WARN("Failed to set environment variable: LXC_TARGET=stop.");
		}
	}

	/* Reset mask set by setup_signal_fd. */
	if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
		WARN("Failed to restore signal mask.");

	lxc_console_delete(&handler->conf->console);
	lxc_delete_tty(&handler->conf->tty_info);
	close(handler->conf->maincmd_fd);
	handler->conf->maincmd_fd = -1;
	free(handler->name);
	if (handler->ttysock[0] != -1) {
		close(handler->ttysock[0]);
		close(handler->ttysock[1]);
	}

	if (handler->conf->ephemeral == 1 && handler->conf->reboot != 1)
		lxc_destroy_container_on_signal(handler, name);

	cgroup_destroy(handler);
	free(handler);
}
Example #5
0
File: start.c Project: hfuCN/lxc
struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char *lxcpath)
{
	int i;
	struct lxc_handler *handler;

	handler = malloc(sizeof(*handler));
	if (!handler)
		return NULL;

	memset(handler, 0, sizeof(*handler));

	handler->ttysock[0] = handler->ttysock[1] = -1;
	handler->conf = conf;
	handler->lxcpath = lxcpath;
	handler->pinfd = -1;

	for (i = 0; i < LXC_NS_MAX; i++)
		handler->nsfd[i] = -1;

	lsm_init();

	handler->name = strdup(name);
	if (!handler->name) {
		ERROR("Failed to allocate memory.");
		goto out_free;
	}

	if (lxc_cmd_init(name, handler, lxcpath))
		goto out_free_name;

	if (lxc_read_seccomp_config(conf) != 0) {
		ERROR("Failed loading seccomp policy.");
		goto out_close_maincmd_fd;
	}

	/* Begin by setting the state to STARTING. */
	if (lxc_set_state(name, handler, STARTING)) {
		ERROR("Failed to set state for container \"%s\" to \"%s\".", name, lxc_state2str(STARTING));
		goto out_close_maincmd_fd;
	}

	/* Start of environment variable setup for hooks. */
	if (name && setenv("LXC_NAME", name, 1))
		SYSERROR("Failed to set environment variable: LXC_NAME=%s.", name);

	if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1))
		SYSERROR("Failed to set environment variable: LXC_CONFIG_FILE=%s.", conf->rcfile);

	if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1))
		SYSERROR("Failed to set environment variable: LXC_ROOTFS_MOUNT=%s.", conf->rootfs.mount);

	if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1))
		SYSERROR("Failed to set environment variable: LXC_ROOTFS_PATH=%s.", conf->rootfs.path);

	if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1))
		SYSERROR("Failed to set environment variable: LXC_CONSOLE=%s.", conf->console.path);

	if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1))
		SYSERROR("Failed to set environment variable: LXC_CONSOLE_LOGPATH=%s.", conf->console.log_path);

	if (setenv("LXC_CGNS_AWARE", "1", 1))
		SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1.");
	/* End of environment variable setup for hooks. */

	if (run_lxc_hooks(name, "pre-start", conf, handler->lxcpath, NULL)) {
		ERROR("Failed to run lxc.hook.pre-start for container \"%s\".", name);
		goto out_aborting;
	}

	/* The signal fd has to be created before forking otherwise if the child
	 * process exits before we setup the signal fd, the event will be lost
	 * and the command will be stuck.
	 */
	handler->sigfd = setup_signal_fd(&handler->oldmask);
	if (handler->sigfd < 0) {
		ERROR("Failed to setup SIGCHLD fd handler.");
		goto out_delete_tty;
	}

	/* Do this after setting up signals since it might unblock SIGWINCH. */
	if (lxc_console_create(conf)) {
		ERROR("Failed to create console for container \"%s\".", name);
		goto out_restore_sigmask;
	}

	if (ttys_shift_ids(conf) < 0) {
		ERROR("Failed to shift tty into container.");
		goto out_restore_sigmask;
	}

	INFO("Container \"%s\" is initialized.", name);
	return handler;

out_restore_sigmask:
	sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
out_delete_tty:
	lxc_delete_tty(&conf->tty_info);
out_aborting:
	lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd:
	close(conf->maincmd_fd);
	conf->maincmd_fd = -1;
out_free_name:
	free(handler->name);
	handler->name = NULL;
out_free:
	free(handler);
	return NULL;
}