]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf: always send response to parent waiting for devptfs_fd 3558/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 20 Oct 2020 11:02:00 +0000 (13:02 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 20 Oct 2020 11:34:24 +0000 (13:34 +0200)
When no devpts devices are requested we used to return early but did not send a
response to the parent. This is a problem because the parent will be waiting
for a devpts fd to be sent. Make sure to always send a response.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/start.c

index b8058ffdceffd57616513387efb27bb68e84905e..e006ea43915dde595b4dd45da8330687aa2c533f 100644 (file)
@@ -1477,7 +1477,23 @@ static const struct id_map *find_mapped_nsid_entry(const struct lxc_conf *conf,
        return retmap;
 }
 
-static int lxc_setup_devpts(struct lxc_handler *handler)
+int lxc_setup_devpts_parent(struct lxc_handler *handler)
+{
+       int ret;
+
+       if (handler->conf->pty_max <= 0)
+               return 0;
+
+       ret = lxc_abstract_unix_recv_fds(handler->data_sock[1], &handler->conf->devpts_fd, 1,
+                                        &handler->conf->devpts_fd, sizeof(handler->conf->devpts_fd));
+       if (ret < 0)
+               return log_error_errno(-1, errno, "Failed to receive devpts fd from child");
+
+       TRACE("Received devpts file descriptor %d from child", handler->conf->devpts_fd);
+       return 0;
+}
+
+static int lxc_setup_devpts_child(struct lxc_handler *handler)
 {
        __do_close int devpts_fd = -EBADF;
        int ret;
@@ -1533,13 +1549,7 @@ static int lxc_setup_devpts(struct lxc_handler *handler)
        if (devpts_fd < 0) {
                devpts_fd = -EBADF;
                TRACE("Failed to create detached devpts mount");
-               ret = lxc_abstract_unix_send_fds(sock, NULL, 0, &devpts_fd, sizeof(int));
-       } else {
-               ret = lxc_abstract_unix_send_fds(sock, &devpts_fd, 1, NULL, 0);
        }
-       if (ret < 0)
-               return log_error_errno(-1, errno, "Failed to send devpts fd to parent");
-       TRACE("Sent devpts file descriptor %d to parent", devpts_fd);
 
        /* Remove any pre-existing /dev/ptmx file. */
        ret = remove("/dev/ptmx");
@@ -1575,6 +1585,14 @@ static int lxc_setup_devpts(struct lxc_handler *handler)
                return log_error_errno(-1, errno, "Failed to create symlink from \"/dev/ptmx\" to \"/dev/pts/ptmx\"");
        DEBUG("Created symlink from \"/dev/ptmx\" to \"/dev/pts/ptmx\"");
 
+       if (devpts_fd < 0)
+               ret = lxc_abstract_unix_send_fds(sock, NULL, 0, &devpts_fd, sizeof(int));
+       else
+               ret = lxc_abstract_unix_send_fds(sock, &devpts_fd, 1, NULL, 0);
+       if (ret < 0)
+               return log_error_errno(-1, errno, "Failed to send devpts fd to parent");
+
+       TRACE("Sent devpts file descriptor %d to parent", devpts_fd);
        return 0;
 }
 
@@ -3392,7 +3410,7 @@ int lxc_setup(struct lxc_handler *handler)
        if (lxc_conf->autodev > 0)
                (void)lxc_setup_boot_id();
 
-       ret = lxc_setup_devpts(handler);
+       ret = lxc_setup_devpts_child(handler);
        if (ret < 0)
                return log_error(-1, "Failed to setup new devpts instance");
 
index cd54b3fe0fd006ebb79f4dfadbf388a17d4c4018..ba06d42dc0c99ac8f9dfcccbe9efe0fd01a1981d 100644 (file)
@@ -490,4 +490,6 @@ 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);
+
 #endif /* __LXC_CONF_H */
index 7b29d40834833a1ae6996e03a64f027a2be7d90b..7bf7f8a2fb132a5d803192ec82b8b723a4b5f142 100644 (file)
@@ -1953,14 +1953,11 @@ static int lxc_spawn(struct lxc_handler *handler)
                }
        }
 
-       ret = lxc_abstract_unix_recv_fds(data_sock1, &handler->conf->devpts_fd, 1,
-                                        &handler->conf->devpts_fd,
-                                        sizeof(handler->conf->devpts_fd));
+       ret = lxc_setup_devpts_parent(handler);
        if (ret < 0) {
                SYSERROR("Failed to receive devpts fd from child");
                goto out_delete_net;
        }
-       TRACE("Received devpts file descriptor %d from child", handler->conf->devpts_fd);
 
        /* Now all networks are created, network devices are moved into place,
         * and the correct names and ifindices in the respective namespaces have