1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/types.h>
26 #include <sys/syscall.h>
27 #include <sys/mount.h>
33 #include <sys/prctl.h>
34 #include <sys/capability.h>
36 #include <sys/epoll.h>
38 #include <sys/signalfd.h>
42 #include <sys/socket.h>
44 #include <systemd/sd-daemon.h>
51 #include "cgroup-util.h"
53 #include "path-util.h"
54 #include "loopback-setup.h"
56 static char *arg_directory = NULL;
57 static char *arg_user = NULL;
58 static char **arg_controllers = NULL;
59 static char *arg_uuid = NULL;
60 static bool arg_private_network = false;
61 static bool arg_read_only = false;
62 static bool arg_boot = false;
64 static int help(void) {
66 printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
67 "Spawn a minimal namespace container for debugging, testing and building.\n\n"
68 " -h --help Show this help\n"
69 " -D --directory=NAME Root directory for the container\n"
70 " -b --boot Boot up full system (i.e. invoke init)\n"
71 " -u --user=USER Run the command under specified user or uid\n"
72 " -C --controllers=LIST Put the container in specified comma-separated cgroup hierarchies\n"
73 " --uuid=UUID Set a specific machine UUID for the container\n"
74 " --private-network Disable network in container\n"
75 " --read-only Mount the root directory read-only\n",
76 program_invocation_short_name);
81 static int parse_argv(int argc, char *argv[]) {
84 ARG_PRIVATE_NETWORK = 0x100,
89 static const struct option options[] = {
90 { "help", no_argument, NULL, 'h' },
91 { "directory", required_argument, NULL, 'D' },
92 { "user", required_argument, NULL, 'u' },
93 { "controllers", required_argument, NULL, 'C' },
94 { "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK },
95 { "boot", no_argument, NULL, 'b' },
96 { "uuid", required_argument, NULL, ARG_UUID },
97 { "read-only", no_argument, NULL, ARG_READ_ONLY },
106 while ((c = getopt_long(argc, argv, "+hD:u:C:b", options, NULL)) >= 0) {
116 arg_directory = canonicalize_file_name(optarg);
117 if (!arg_directory) {
118 log_error("Failed to canonicalize root directory.");
126 if (!(arg_user = strdup(optarg))) {
127 log_error("Failed to duplicate user name.");
134 strv_free(arg_controllers);
135 arg_controllers = strv_split(optarg, ",");
136 if (!arg_controllers) {
137 log_error("Failed to split controllers list.");
140 strv_uniq(arg_controllers);
144 case ARG_PRIVATE_NETWORK:
145 arg_private_network = true;
157 arg_read_only = true;
164 log_error("Unknown option code %c", c);
172 static int mount_all(const char *dest) {
174 typedef struct MountPoint {
183 static const MountPoint mount_table[] = {
184 { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
185 { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */
186 { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
187 { "/sys", "/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */
188 { "/sys", "/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
189 { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true },
190 { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true },
191 { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
193 { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND, false }, /* Bind mount first */
194 { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */
202 for (k = 0; k < ELEMENTSOF(mount_table); k++) {
205 if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) {
206 log_error("Out of memory");
214 t = path_is_mount_point(where, false);
216 log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t));
225 mkdir_p(where, 0755);
227 if (mount(mount_table[k].what,
230 mount_table[k].flags,
231 mount_table[k].options) < 0 &&
232 mount_table[k].fatal) {
234 log_error("mount(%s) failed: %m", where);
246 static int setup_timezone(const char *dest) {
251 /* Fix the timezone, if possible */
252 if (asprintf(&where, "%s/etc/localtime", dest) < 0) {
253 log_error("Out of memory");
257 if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0)
258 mount("/etc/localtime", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
262 if (asprintf(&where, "%s/etc/timezone", dest) < 0) {
263 log_error("Out of memory");
267 if (mount("/etc/timezone", where, "bind", MS_BIND, NULL) >= 0)
268 mount("/etc/timezone", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
275 static int setup_resolv_conf(const char *dest) {
280 if (arg_private_network)
283 /* Fix resolv.conf, if possible */
284 if (asprintf(&where, "%s/etc/resolv.conf", dest) < 0) {
285 log_error("Out of memory");
289 if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0)
290 mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
297 static int copy_devnodes(const char *dest) {
299 static const char devnodes[] =
317 NULSTR_FOREACH(d, devnodes) {
319 char *from = NULL, *to = NULL;
321 asprintf(&from, "/dev/%s", d);
322 asprintf(&to, "%s/dev/%s", dest, d);
325 log_error("Failed to allocate devnode path");
338 if (stat(from, &st) < 0) {
340 if (errno != ENOENT) {
341 log_error("Failed to stat %s: %m", from);
346 } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
348 log_error("%s is not a char or block device, cannot copy.", from);
352 } else if (mknod(to, st.st_mode, st.st_rdev) < 0) {
354 log_error("mknod(%s) failed: %m", dest);
368 static int setup_dev_console(const char *dest, const char *console) {
379 if (stat(console, &st) < 0) {
380 log_error("Failed to stat %s: %m", console);
384 } else if (!S_ISCHR(st.st_mode)) {
385 log_error("/dev/console is not a char device.");
390 r = chmod_and_chown(console, 0600, 0, 0);
392 log_error("Failed to correct access mode for TTY: %s", strerror(-r));
396 if (asprintf(&to, "%s/dev/console", dest) < 0) {
397 log_error("Out of memory");
402 /* We need to bind mount the right tty to /dev/console since
403 * ptys can only exist on pts file systems. To have something
404 * to bind mount things on we create a device node first, that
405 * has the right major/minor (note that the major minor
406 * doesn't actually matter here, since we mount it over
409 if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
410 log_error("mknod() for /dev/console failed: %m");
415 if (mount(console, to, "bind", MS_BIND, NULL) < 0) {
416 log_error("Bind mount for /dev/console failed: %m");
428 static int setup_kmsg(const char *dest, int kmsg_socket) {
429 char *from = NULL, *to = NULL;
433 struct cmsghdr cmsghdr;
434 uint8_t buf[CMSG_SPACE(sizeof(int))];
437 struct cmsghdr *cmsg;
440 assert(kmsg_socket >= 0);
444 /* We create the kmsg FIFO as /dev/kmsg, but immediately
445 * delete it after bind mounting it to /proc/kmsg. While FIFOs
446 * on the reading side behave very similar to /proc/kmsg,
447 * their writing side behaves differently from /dev/kmsg in
448 * that writing blocks when nothing is reading. In order to
449 * avoid any problems with containers deadlocking due to this
450 * we simply make /dev/kmsg unavailable to the container. */
451 if (asprintf(&from, "%s/dev/kmsg", dest) < 0) {
452 log_error("Out of memory");
457 if (asprintf(&to, "%s/proc/kmsg", dest) < 0) {
458 log_error("Out of memory");
463 if (mkfifo(from, 0600) < 0) {
464 log_error("mkfifo() for /dev/kmsg failed: %m");
469 r = chmod_and_chown(from, 0600, 0, 0);
471 log_error("Failed to correct access mode for /dev/kmsg: %s", strerror(-r));
475 if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
476 log_error("Bind mount for /proc/kmsg failed: %m");
481 fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC);
483 log_error("Failed to open fifo: %m");
491 mh.msg_control = &control;
492 mh.msg_controllen = sizeof(control);
494 cmsg = CMSG_FIRSTHDR(&mh);
495 cmsg->cmsg_level = SOL_SOCKET;
496 cmsg->cmsg_type = SCM_RIGHTS;
497 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
498 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
500 mh.msg_controllen = cmsg->cmsg_len;
502 /* Store away the fd in the socket, so that it stays open as
503 * long as we run the child */
504 k = sendmsg(kmsg_socket, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
505 close_nointr_nofail(fd);
508 log_error("Failed to send FIFO fd: %m");
513 /* And now make the FIFO unavailable as /dev/kmsg... */
524 static int setup_hostname(void) {
528 hn = path_get_file_name(arg_directory);
534 hostname_cleanup(hn);
537 if (sethostname(hn, strlen(hn)) < 0)
546 static int drop_capabilities(void) {
547 static const unsigned long retain[] = {
557 CAP_NET_BIND_SERVICE,
573 for (l = 0; l <= cap_last_cap(); l++) {
576 for (i = 0; i < ELEMENTSOF(retain); i++)
580 if (i < ELEMENTSOF(retain))
583 if (prctl(PR_CAPBSET_DROP, l) < 0) {
584 log_error("PR_CAPBSET_DROP failed: %m");
592 static int is_os_tree(const char *path) {
595 /* We use /bin/sh as flag file if something is an OS */
597 if (asprintf(&p, "%s/bin/sh", path) < 0)
603 return r < 0 ? 0 : 1;
606 static int process_pty(int master, sigset_t *mask) {
608 char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
609 size_t in_buffer_full = 0, out_buffer_full = 0;
610 struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev;
611 bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false;
612 int ep = -1, signal_fd = -1, r;
614 fd_nonblock(STDIN_FILENO, 1);
615 fd_nonblock(STDOUT_FILENO, 1);
616 fd_nonblock(master, 1);
618 if ((signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
619 log_error("signalfd(): %m");
624 if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) {
625 log_error("Failed to create epoll: %m");
631 stdin_ev.events = EPOLLIN|EPOLLET;
632 stdin_ev.data.fd = STDIN_FILENO;
635 stdout_ev.events = EPOLLOUT|EPOLLET;
636 stdout_ev.data.fd = STDOUT_FILENO;
639 master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
640 master_ev.data.fd = master;
643 signal_ev.events = EPOLLIN;
644 signal_ev.data.fd = signal_fd;
646 if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 ||
647 epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
648 epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 ||
649 epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) {
650 log_error("Failed to regiser fds in epoll: %m");
656 struct epoll_event ev[16];
660 if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) {
662 if (errno == EINTR || errno == EAGAIN)
665 log_error("epoll_wait(): %m");
672 for (i = 0; i < nfds; i++) {
673 if (ev[i].data.fd == STDIN_FILENO) {
675 if (ev[i].events & (EPOLLIN|EPOLLHUP))
676 stdin_readable = true;
678 } else if (ev[i].data.fd == STDOUT_FILENO) {
680 if (ev[i].events & (EPOLLOUT|EPOLLHUP))
681 stdout_writable = true;
683 } else if (ev[i].data.fd == master) {
685 if (ev[i].events & (EPOLLIN|EPOLLHUP))
686 master_readable = true;
688 if (ev[i].events & (EPOLLOUT|EPOLLHUP))
689 master_writable = true;
691 } else if (ev[i].data.fd == signal_fd) {
692 struct signalfd_siginfo sfsi;
695 if ((n = read(signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
698 log_error("Failed to read from signalfd: invalid block size");
703 if (errno != EINTR && errno != EAGAIN) {
704 log_error("Failed to read from signalfd: %m");
710 if (sfsi.ssi_signo == SIGWINCH) {
713 /* The window size changed, let's forward that. */
714 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
715 ioctl(master, TIOCSWINSZ, &ws);
724 while ((stdin_readable && in_buffer_full <= 0) ||
725 (master_writable && in_buffer_full > 0) ||
726 (master_readable && out_buffer_full <= 0) ||
727 (stdout_writable && out_buffer_full > 0)) {
729 if (stdin_readable && in_buffer_full < LINE_MAX) {
731 if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) {
733 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
734 stdin_readable = false;
736 log_error("read(): %m");
741 in_buffer_full += (size_t) k;
744 if (master_writable && in_buffer_full > 0) {
746 if ((k = write(master, in_buffer, in_buffer_full)) < 0) {
748 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
749 master_writable = false;
751 log_error("write(): %m");
757 assert(in_buffer_full >= (size_t) k);
758 memmove(in_buffer, in_buffer + k, in_buffer_full - k);
763 if (master_readable && out_buffer_full < LINE_MAX) {
765 if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) {
767 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
768 master_readable = false;
770 log_error("read(): %m");
775 out_buffer_full += (size_t) k;
778 if (stdout_writable && out_buffer_full > 0) {
780 if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) {
782 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
783 stdout_writable = false;
785 log_error("write(): %m");
791 assert(out_buffer_full >= (size_t) k);
792 memmove(out_buffer, out_buffer + k, out_buffer_full - k);
793 out_buffer_full -= k;
801 close_nointr_nofail(ep);
804 close_nointr_nofail(signal_fd);
809 int main(int argc, char *argv[]) {
811 int r = EXIT_FAILURE, k;
812 char *oldcg = NULL, *newcg = NULL;
813 char **controller = NULL;
815 const char *console = NULL;
816 struct termios saved_attr, raw_attr;
818 bool saved_attr_valid = false;
820 int kmsg_socket_pair[2] = { -1, -1 };
822 log_parse_environment();
825 if ((r = parse_argv(argc, argv)) <= 0)
831 p = path_make_absolute_cwd(arg_directory);
835 arg_directory = get_current_dir_name();
837 if (!arg_directory) {
838 log_error("Failed to determine path");
842 path_kill_slashes(arg_directory);
844 if (geteuid() != 0) {
845 log_error("Need to be root.");
849 if (sd_booted() <= 0) {
850 log_error("Not running on a systemd system.");
854 if (path_equal(arg_directory, "/")) {
855 log_error("Spawning container on root directory not supported.");
859 if (is_os_tree(arg_directory) <= 0) {
860 log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory);
864 if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) {
865 log_error("Failed to determine current cgroup: %s", strerror(-k));
869 if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) {
870 log_error("Failed to allocate cgroup path.");
874 k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0);
876 log_error("Failed to create cgroup: %s", strerror(-k));
880 STRV_FOREACH(controller,arg_controllers) {
881 k = cg_create_and_attach(*controller, newcg, 0);
883 log_warning("Failed to create cgroup in controller %s: %s", *controller, strerror(-k));
886 if ((master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY)) < 0) {
887 log_error("Failed to acquire pseudo tty: %m");
891 if (!(console = ptsname(master))) {
892 log_error("Failed to determine tty name: %m");
896 log_info("Spawning namespace container on %s (console is %s).", arg_directory, console);
898 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
899 ioctl(master, TIOCSWINSZ, &ws);
901 if (unlockpt(master) < 0) {
902 log_error("Failed to unlock tty: %m");
906 if (tcgetattr(STDIN_FILENO, &saved_attr) < 0) {
907 log_error("Failed to get terminal attributes: %m");
911 saved_attr_valid = true;
913 raw_attr = saved_attr;
914 cfmakeraw(&raw_attr);
915 raw_attr.c_lflag &= ~ECHO;
917 if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
918 log_error("Failed to set terminal attributes: %m");
922 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
923 log_error("Failed to create kmsg socket pair");
927 assert_se(sigemptyset(&mask) == 0);
928 sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
929 assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
931 pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
934 log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
936 log_error("clone() failed: %m");
944 const char *home = NULL;
945 uid_t uid = (uid_t) -1;
946 gid_t gid = (gid_t) -1;
947 const char *envp[] = {
948 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
949 "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
954 NULL, /* container_uuid */
958 envp[2] = strv_find_prefix(environ, "TERM=");
960 close_nointr_nofail(master);
962 close_nointr(STDIN_FILENO);
963 close_nointr(STDOUT_FILENO);
964 close_nointr(STDERR_FILENO);
966 close_all_fds(&kmsg_socket_pair[1], 1);
968 reset_all_signal_handlers();
970 assert_se(sigemptyset(&mask) == 0);
971 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
976 if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0)
979 /* Mark / as private, in case somebody marked it shared */
980 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0)
983 /* Turn directory into bind mount */
984 if (mount(arg_directory, arg_directory, "bind", MS_BIND, NULL) < 0) {
985 log_error("Failed to make bind mount.");
990 if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
991 log_error("Failed to make read-only.");
995 if (mount_all(arg_directory) < 0)
998 if (copy_devnodes(arg_directory) < 0)
1001 if (setup_dev_console(arg_directory, console) < 0)
1004 if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
1007 close_nointr_nofail(kmsg_socket_pair[1]);
1009 if (setup_timezone(arg_directory) < 0)
1012 if (setup_resolv_conf(arg_directory) < 0)
1015 if (chdir(arg_directory) < 0) {
1016 log_error("chdir(%s) failed: %m", arg_directory);
1020 if (open_terminal("dev/console", O_RDWR) != STDIN_FILENO ||
1021 dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
1022 dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
1025 if (mount(arg_directory, "/", "bind", MS_MOVE, NULL) < 0) {
1026 log_error("mount(MS_BIND) failed: %m");
1030 if (chroot(".") < 0) {
1031 log_error("chroot() failed: %m");
1035 if (chdir("/") < 0) {
1036 log_error("chdir() failed: %m");
1044 if (drop_capabilities() < 0)
1049 if (get_user_creds((const char**)&arg_user, &uid, &gid, &home) < 0) {
1050 log_error("get_user_creds() failed: %m");
1054 if (mkdir_parents(home, 0775) < 0) {
1055 log_error("mkdir_parents() failed: %m");
1059 if (safe_mkdir(home, 0775, uid, gid) < 0) {
1060 log_error("safe_mkdir() failed: %m");
1064 if (initgroups((const char*)arg_user, gid) < 0) {
1065 log_error("initgroups() failed: %m");
1069 if (setresgid(gid, gid, gid) < 0) {
1070 log_error("setregid() failed: %m");
1074 if (setresuid(uid, uid, uid) < 0) {
1075 log_error("setreuid() failed: %m");
1080 if ((asprintf((char**)(envp + 3), "HOME=%s", home ? home: "/root") < 0) ||
1081 (asprintf((char**)(envp + 4), "USER=%s", arg_user ? arg_user : "root") < 0) ||
1082 (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
1083 log_error("Out of memory");
1088 if (asprintf((char**)(envp + 6), "container_uuid=%s", arg_uuid) < 0) {
1089 log_error("Out of memory");
1100 /* Automatically search for the init system */
1102 l = 1 + argc - optind;
1103 a = newa(char*, l + 1);
1104 memcpy(a + 1, argv + optind, l * sizeof(char*));
1106 a[0] = (char*) "/usr/lib/systemd/systemd";
1107 execve(a[0], a, (char**) envp);
1109 a[0] = (char*) "/lib/systemd/systemd";
1110 execve(a[0], a, (char**) envp);
1112 a[0] = (char*) "/sbin/init";
1113 execve(a[0], a, (char**) envp);
1114 } else if (argc > optind)
1115 execvpe(argv[optind], argv + optind, (char**) envp);
1117 chdir(home ? home : "/root");
1118 execle("/bin/bash", "-bash", NULL, (char**) envp);
1121 log_error("execv() failed: %m");
1124 _exit(EXIT_FAILURE);
1127 if (process_pty(master, &mask) < 0)
1130 if (saved_attr_valid) {
1131 tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
1132 saved_attr_valid = false;
1135 r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid);
1141 if (saved_attr_valid)
1142 tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
1145 close_nointr_nofail(master);
1147 close_pipe(kmsg_socket_pair);
1150 cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0);
1153 cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true);
1155 free(arg_directory);
1156 strv_free(arg_controllers);