return retmap;
}
-int lxc_setup_devpts_parent(struct lxc_handler *handler)
+static int lxc_setup_devpts_parent(struct lxc_handler *handler)
{
int ret;
}
}
+static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
+{
+ int i;
+ struct lxc_terminal_info *tty;
+ int ret = -1;
+ int sock = handler->data_sock[1];
+ struct lxc_conf *conf = handler->conf;
+ struct lxc_tty_info *ttys = &conf->ttys;
+
+ if (!conf->ttys.max)
+ return 0;
+
+ ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
+ if (!ttys->tty)
+ return -1;
+
+ for (i = 0; i < conf->ttys.max; i++) {
+ int ttyx = -EBADF, ttyy = -EBADF;
+
+ ret = lxc_abstract_unix_recv_two_fds(sock, &ttyx, &ttyy);
+ if (ret < 0)
+ break;
+
+ tty = &ttys->tty[i];
+ tty->busy = -1;
+ tty->ptx = ttyx;
+ tty->pty = ttyy;
+ TRACE("Received pty with ptx fd %d and pty fd %d from child", tty->ptx, tty->pty);
+ }
+
+ if (ret < 0)
+ SYSERROR("Failed to receive %zu ttys from child", ttys->max);
+ else
+ TRACE("Received %zu ttys from child", ttys->max);
+
+ return ret;
+}
+
+int lxc_sync_fds_parent(struct lxc_handler *handler)
+{
+ int ret;
+
+ ret = lxc_seccomp_recv_notifier_fd(&handler->conf->seccomp, handler->data_sock[1]);
+ if (ret < 0)
+ return syserror_ret(ret, "Failed to receive seccomp notify fd from child");
+
+ ret = lxc_setup_devpts_parent(handler);
+ if (ret < 0)
+ return syserror_ret(ret, "Failed to receive devpts fd from child");
+
+ /* Read tty fds allocated by child. */
+ ret = lxc_recv_ttys_from_child(handler);
+ if (ret < 0)
+ return syserror_ret(ret, "Failed to receive tty info from child process");
+
+ if (handler->ns_clone_flags & CLONE_NEWNET) {
+ ret = lxc_network_recv_name_and_ifindex_from_child(handler);
+ if (ret < 0)
+ return syserror_ret(ret, "Failed to receive names and ifindices for network devices from child");
+ }
+
+ TRACE("Finished syncing file descriptors with child");
+ return 0;
+}
+
int lxc_setup(struct lxc_handler *handler)
{
int ret;
return userns_exec_mapped_root(path, -EBADF, conf);
}
-__hidden int lxc_setup_devpts_parent(struct lxc_handler *handler);
+__hidden extern int lxc_sync_fds_parent(struct lxc_handler *handler);
static inline const char *get_rootfs_mnt(const struct lxc_rootfs *rootfs)
{
return -1;
}
-static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
-{
- int i;
- struct lxc_terminal_info *tty;
- int ret = -1;
- int sock = handler->data_sock[1];
- struct lxc_conf *conf = handler->conf;
- struct lxc_tty_info *ttys = &conf->ttys;
-
- if (!conf->ttys.max)
- return 0;
-
- ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
- if (!ttys->tty)
- return -1;
-
- for (i = 0; i < conf->ttys.max; i++) {
- int ttyx = -EBADF, ttyy = -EBADF;
-
- ret = lxc_abstract_unix_recv_two_fds(sock, &ttyx, &ttyy);
- if (ret < 0)
- break;
-
- tty = &ttys->tty[i];
- tty->busy = -1;
- tty->ptx = ttyx;
- tty->pty = ttyy;
- TRACE("Received pty with ptx fd %d and pty fd %d from child", tty->ptx, tty->pty);
- }
-
- if (ret < 0)
- SYSERROR("Failed to receive %zu ttys from child", ttys->max);
- else
- TRACE("Received %zu ttys from child", ttys->max);
-
- return ret;
-}
-
int resolve_clone_flags(struct lxc_handler *handler)
{
int i;
if (!lxc_sync_wake_child(handler, START_SYNC_FDS))
goto out_delete_net;
- ret = lxc_seccomp_recv_notifier_fd(&handler->conf->seccomp, data_sock1);
+ ret = lxc_sync_fds_parent(handler);
if (ret < 0) {
- SYSERROR("Failed to receive seccomp notify fd from child");
+ SYSERROR("Failed to sync file descriptors with child");
goto out_delete_net;
}
- ret = lxc_setup_devpts_parent(handler);
- if (ret < 0) {
- SYSERROR("Failed to receive devpts fd from child");
- goto out_delete_net;
- }
-
- /* Read tty fds allocated by child. */
- ret = lxc_recv_ttys_from_child(handler);
- if (ret < 0) {
- ERROR("Failed to receive tty info from child process");
- goto out_delete_net;
- }
-
- if (handler->ns_clone_flags & CLONE_NEWNET) {
- ret = lxc_network_recv_name_and_ifindex_from_child(handler);
- if (ret < 0) {
- ERROR("Failed to receive names and ifindices for network devices from child");
- goto out_delete_net;
- }
- }
-
/*
* Tell the child to complete its initialization and wait for it to
* exec or return an error. (The child will never return