chiark / gitweb /
nspawn: don't make assumptions about the size of pid_t
[elogind.git] / src / nspawn / nspawn.c
index d35a8b547bc2da46d4864b76fe4928e8df0a3c9d..9268cbc246c6797d9030de4ee4d4f3f1694e5cf4 100644 (file)
 #include "build.h"
 #include "fileio.h"
 
+#ifndef TTY_GID
+#define TTY_GID 5
+#endif
+
 typedef enum LinkJournal {
         LINK_NO,
         LINK_AUTO,
@@ -335,7 +339,7 @@ static int mount_all(const char *dest) {
                 { NULL,        "/proc/sys", NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
                 { "sysfs",     "/sys",      "sysfs", NULL,       MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
                 { "tmpfs",     "/dev",      "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,     true  },
-                { "/dev/pts",  "/dev/pts",  NULL,    NULL,       MS_BIND,                      true  },
+                { "devpts",    "/dev/pts",  "devpts","newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, true },
                 { "tmpfs",     "/dev/shm",  "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
                 { "tmpfs",     "/run",      "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
 #ifdef HAVE_SELINUX
@@ -548,8 +552,7 @@ static int copy_devnodes(const char *dest) {
                 "full\0"
                 "random\0"
                 "urandom\0"
-                "tty\0"
-                "ptmx\0";
+                "tty\0";
 
         const char *d;
         int r = 0;
@@ -600,6 +603,21 @@ static int copy_devnodes(const char *dest) {
         return r;
 }
 
+static int setup_ptmx(const char *dest) {
+        _cleanup_free_ char *p = NULL;
+
+        p = strappend(dest, "/dev/ptmx");
+        if (!p)
+                return log_oom();
+
+        if (symlink("pts/ptmx", p) < 0) {
+                log_error("Failed to create /dev/ptmx symlink: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
 static int setup_dev_console(const char *dest, const char *console) {
         struct stat st;
         char _cleanup_free_ *to = NULL;
@@ -1276,7 +1294,7 @@ int main(int argc, char *argv[]) {
                 siginfo_t status;
                 int pipefd[2];
 
-                if(pipe2(pipefd, O_NONBLOCK|O_CLOEXEC) < 0) {
+                if (pipe2(pipefd, O_NONBLOCK|O_CLOEXEC) < 0) {
                         log_error("pipe2(): %m");
                         goto finish;
                 }
@@ -1296,7 +1314,7 @@ int main(int argc, char *argv[]) {
                         const char *home = NULL;
                         uid_t uid = (uid_t) -1;
                         gid_t gid = (gid_t) -1;
-                        unsigned n_env = 0;
+                        unsigned n_env = 2;
                         const char *envp[] = {
                                 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                                 "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
@@ -1310,8 +1328,9 @@ int main(int argc, char *argv[]) {
                                 NULL
                         };
 
-                        envp[2] = strv_find_prefix(environ, "TERM=");
-                        n_env = 3;
+                        envp[n_env] = strv_find_prefix(environ, "TERM=");
+                        if (envp[n_env])
+                                n_env ++;
 
                         close_nointr_nofail(pipefd[1]);
                         fd_wait_for_event(pipefd[0], POLLHUP, -1);
@@ -1392,6 +1411,9 @@ int main(int argc, char *argv[]) {
                         if (copy_devnodes(arg_directory) < 0)
                                 goto child_fail;
 
+                        if (setup_ptmx(arg_directory) < 0)
+                                goto child_fail;
+
                         dev_setup(arg_directory);
 
                         if (setup_dev_console(arg_directory, console) < 0)
@@ -1567,7 +1589,7 @@ int main(int argc, char *argv[]) {
                         _exit(EXIT_FAILURE);
                 }
 
-                log_info("Init process in the container running as PID %d", pid);
+                log_info("Init process in the container running as PID %lu.", (unsigned long) pid);
                 close_nointr_nofail(pipefd[0]);
                 close_nointr_nofail(pipefd[1]);