return 0;
}
-/*
- * Build a space-separate list of ptys to pass to systemd.
- */
+/* Build a space-separate list of ptys to pass to systemd. */
static bool append_ptyname(char **pp, char *name)
{
char *p;
return true;
}
-static int lxc_setup_tty(struct lxc_conf *conf)
+static int lxc_setup_ttys(struct lxc_conf *conf)
{
int i, ret;
const struct lxc_tty_info *tty_info = &conf->tty_info;
return 0;
}
+int lxc_allocate_ttys(const char *name, struct lxc_conf *conf)
+{
+ struct lxc_tty_info *tty_info = &conf->tty_info;
+ int i, ret;
+
+ /* no tty in the configuration */
+ if (!conf->tty)
+ return 0;
+
+ tty_info->pty_info = malloc(sizeof(*tty_info->pty_info) * conf->tty);
+ if (!tty_info->pty_info) {
+ SYSERROR("failed to allocate struct *pty_info");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < conf->tty; i++) {
+ struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
+
+ process_lock();
+ ret = openpty(&pty_info->master, &pty_info->slave,
+ pty_info->name, NULL, NULL);
+ process_unlock();
+ if (ret) {
+ SYSERROR("failed to create pty device number %d", i);
+ tty_info->nbtty = i;
+ lxc_delete_tty(tty_info);
+ return -ENOTTY;
+ }
+
+ DEBUG("allocated pty \"%s\" with master fd %d and slave fd %d",
+ pty_info->name, pty_info->master, pty_info->slave);
+
+ /* Prevent leaking the file descriptors to the container */
+ ret = fcntl(pty_info->master, F_SETFD, FD_CLOEXEC);
+ if (ret < 0)
+ WARN("failed to set FD_CLOEXEC flag on master fd %d of "
+ "pty device \"%s\": %s",
+ pty_info->master, pty_info->name, strerror(errno));
+
+ ret = fcntl(pty_info->slave, F_SETFD, FD_CLOEXEC);
+ if (ret < 0)
+ WARN("failed to set FD_CLOEXEC flag on slave fd %d of "
+ "pty device \"%s\": %s",
+ pty_info->slave, pty_info->name, strerror(errno));
+
+ pty_info->busy = 0;
+ }
+
+ tty_info->nbtty = conf->tty;
+
+ INFO("finished allocating %d pts devices", conf->tty);
+ return 0;
+}
+
+void lxc_delete_tty(struct lxc_tty_info *tty_info)
+{
+ int i;
+
+ for (i = 0; i < tty_info->nbtty; i++) {
+ struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
+
+ close(pty_info->master);
+ close(pty_info->slave);
+ }
+
+ free(tty_info->pty_info);
+ tty_info->pty_info = NULL;
+ tty_info->nbtty = 0;
+}
+
+static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
+{
+ int i;
+ struct lxc_conf *conf = handler->conf;
+ struct lxc_tty_info *tty_info = &conf->tty_info;
+ int sock = handler->data_sock[0];
+ int ret = -1;
+
+ if (!conf->tty)
+ return 0;
+
+ for (i = 0; i < conf->tty; i++) {
+ int ttyfds[2];
+ struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
+
+ ttyfds[0] = pty_info->master;
+ ttyfds[1] = pty_info->slave;
+
+ ret = lxc_abstract_unix_send_fds(sock, ttyfds, 2, NULL, 0);
+ if (ret < 0)
+ break;
+
+ TRACE("Send pty \"%s\" with master fd %d and slave fd %d to "
+ "parent", pty_info->name, pty_info->master, pty_info->slave);
+ }
+
+ if (ret < 0)
+ ERROR("Failed to send %d ttys to parent: %s", conf->tty,
+ strerror(errno));
+ else
+ TRACE("Sent %d ttys to parent", conf->tty);
+
+ return ret;
+}
+
+static int lxc_create_ttys(struct lxc_handler *handler)
+{
+ int ret = -1;
+ struct lxc_conf *conf = handler->conf;
+
+ ret = lxc_allocate_ttys(handler->name, conf);
+ if (ret < 0) {
+ ERROR("Failed to allocate ttys");
+ goto on_error;
+ }
+
+ ret = lxc_send_ttys_to_parent(handler);
+ if (ret < 0) {
+ ERROR("Failed to send ttys to parent");
+ goto on_error;
+ }
+
+ if (!conf->is_execute) {
+ ret = lxc_setup_ttys(conf);
+ if (ret < 0) {
+ ERROR("Failed to setup ttys");
+ goto on_error;
+ }
+ }
+
+ if (conf->pty_names) {
+ ret = setenv("container_ttys", conf->pty_names, 1);
+ if (ret < 0)
+ SYSERROR("Failed to set \"container_ttys=%s\"", conf->pty_names);
+ }
+
+ ret = 0;
+
+on_error:
+ lxc_delete_tty(&conf->tty_info);
+
+ return ret;
+}
+
static int setup_rootfs_pivot_root(const char *rootfs)
{
int oldroot = -1, newroot = -1;
return freeid;
}
-int lxc_create_tty(const char *name, struct lxc_conf *conf)
-{
- struct lxc_tty_info *tty_info = &conf->tty_info;
- int i, ret;
-
- /* no tty in the configuration */
- if (!conf->tty)
- return 0;
-
- tty_info->pty_info = malloc(sizeof(*tty_info->pty_info) * conf->tty);
- if (!tty_info->pty_info) {
- SYSERROR("failed to allocate struct *pty_info");
- return -ENOMEM;
- }
-
- for (i = 0; i < conf->tty; i++) {
- struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
-
- process_lock();
- ret = openpty(&pty_info->master, &pty_info->slave,
- pty_info->name, NULL, NULL);
- process_unlock();
- if (ret) {
- SYSERROR("failed to create pty device number %d", i);
- tty_info->nbtty = i;
- lxc_delete_tty(tty_info);
- return -ENOTTY;
- }
-
- DEBUG("allocated pty \"%s\" with master fd %d and slave fd %d",
- pty_info->name, pty_info->master, pty_info->slave);
-
- /* Prevent leaking the file descriptors to the container */
- ret = fcntl(pty_info->master, F_SETFD, FD_CLOEXEC);
- if (ret < 0)
- WARN("failed to set FD_CLOEXEC flag on master fd %d of "
- "pty device \"%s\": %s",
- pty_info->master, pty_info->name, strerror(errno));
-
- ret = fcntl(pty_info->slave, F_SETFD, FD_CLOEXEC);
- if (ret < 0)
- WARN("failed to set FD_CLOEXEC flag on slave fd %d of "
- "pty device \"%s\": %s",
- pty_info->slave, pty_info->name, strerror(errno));
-
- pty_info->busy = 0;
- }
-
- tty_info->nbtty = conf->tty;
-
- INFO("finished allocating %d pts devices", conf->tty);
- return 0;
-}
-
-void lxc_delete_tty(struct lxc_tty_info *tty_info)
-{
- int i;
-
- for (i = 0; i < tty_info->nbtty; i++) {
- struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
-
- close(pty_info->master);
- close(pty_info->slave);
- }
-
- free(tty_info->pty_info);
- tty_info->pty_info = NULL;
- tty_info->nbtty = 0;
-}
-
-
int chown_mapped_root_exec_wrapper(void *args)
{
execvp("lxc-usernsexec", args);
return true;
}
-static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
-{
- int i;
- struct lxc_conf *conf = handler->conf;
- struct lxc_tty_info *tty_info = &conf->tty_info;
- int sock = handler->data_sock[0];
- int ret = -1;
-
- if (!conf->tty)
- return 0;
-
- for (i = 0; i < conf->tty; i++) {
- int ttyfds[2];
- struct lxc_pty_info *pty_info = &tty_info->pty_info[i];
-
- ttyfds[0] = pty_info->master;
- ttyfds[1] = pty_info->slave;
-
- ret = lxc_abstract_unix_send_fds(sock, ttyfds, 2, NULL, 0);
- if (ret < 0)
- break;
-
- TRACE("Send pty \"%s\" with master fd %d and slave fd %d to "
- "parent", pty_info->name, pty_info->master, pty_info->slave);
- }
-
- if (ret < 0)
- ERROR("Failed to send %d ttys to parent: %s", conf->tty,
- strerror(errno));
- else
- TRACE("Sent %d ttys to parent", conf->tty);
-
- lxc_delete_tty(tty_info);
-
- return ret;
-}
-
int lxc_setup(struct lxc_handler *handler)
{
+ int ret;
const char *name = handler->name;
struct lxc_conf *lxc_conf = handler->conf;
const char *lxcpath = handler->lxcpath;
return -1;
}
- if (lxc_create_tty(name, lxc_conf)) {
- ERROR("failed to create the ttys");
- return -1;
- }
-
- if (lxc_send_ttys_to_parent(handler) < 0) {
- ERROR("failure sending console info to parent");
- return -1;
- }
-
- if (!lxc_conf->is_execute && lxc_setup_tty(lxc_conf)) {
- ERROR("failed to setup the ttys for '%s'", name);
+ ret = lxc_create_ttys(handler);
+ if (ret < 0)
return -1;
- }
-
- if (lxc_conf->pty_names && setenv("container_ttys", lxc_conf->pty_names, 1))
- SYSERROR("failed to set environment variable for container ptys");
-
if (setup_personality(lxc_conf->personality)) {
ERROR("failed to setup personality");