Skip to content

Commit

Permalink
conf: move file descriptor synchronization with child into single fun…
Browse files Browse the repository at this point in the history
…ction

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
  • Loading branch information
Christian Brauner committed May 28, 2021
1 parent 1c662b8 commit e8e538a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 63 deletions.
67 changes: 66 additions & 1 deletion src/lxc/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,7 +1635,7 @@ static const struct id_map *find_mapped_nsid_entry(const struct lxc_conf *conf,
return retmap;
}

int lxc_setup_devpts_parent(struct lxc_handler *handler)
static int lxc_setup_devpts_parent(struct lxc_handler *handler)
{
int ret;

Expand Down Expand Up @@ -4013,6 +4013,71 @@ int lxc_idmapped_mounts_parent(struct lxc_handler *handler)
}
}

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;
Expand Down
2 changes: 1 addition & 1 deletion src/lxc/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ static inline int chown_mapped_root(const char *path, const struct lxc_conf *con
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)
{
Expand Down
63 changes: 2 additions & 61 deletions src/lxc/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,44 +1464,6 @@ static int do_start(void *data)
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;
Expand Down Expand Up @@ -1959,33 +1921,12 @@ static int lxc_spawn(struct lxc_handler *handler)
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
Expand Down

0 comments on commit e8e538a

Please sign in to comment.