chiark / gitweb /
util: rename write_one_line_file() to write_string_file()
[elogind.git] / src / nspawn / nspawn.c
index d35a8b547bc2da46d4864b76fe4928e8df0a3c9d..01ef12bf67bbbf0dda4095bad7d2bb037988dd15 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
@@ -524,7 +528,7 @@ static int setup_boot_id(const char *dest) {
                  SD_ID128_FORMAT_VAL(rnd));
         char_array_0(as_uuid);
 
-        r = write_one_line_file(from, as_uuid);
+        r = write_string_file(from, as_uuid);
         if (r < 0) {
                 log_error("Failed to write boot id: %s", strerror(-r));
                 return r;
@@ -533,8 +537,8 @@ static int setup_boot_id(const char *dest) {
         if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
                 log_error("Failed to bind mount boot id: %m");
                 r = -errno;
-        } else
-                mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+        } else if (mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL))
+                log_warning("Failed to make boot id read-only: %m");
 
         unlink(from);
         return r;
@@ -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]);