Exemple #1
0
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;
}
Exemple #2
0
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;
}