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 "loopback-setup.h"
55 static char *arg_directory = NULL;
56 static char *arg_user = NULL;
57 static char **arg_controllers = NULL;
58 static char *arg_uuid = NULL;
59 static bool arg_private_network = false;
60 static bool arg_boot = false;
62 static int help(void) {
64 printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
65 "Spawn a minimal namespace container for debugging, testing and building.\n\n"
66 " -h --help Show this help\n"
67 " -D --directory=NAME Root directory for the container\n"
68 " -b --boot Boot up full system (i.e. invoke init)\n"
69 " -u --user=USER Run the command under specified user or uid\n"
70 " -C --controllers=LIST Put the container in specified comma-separated cgroup hierarchies\n"
71 " --uuid=UUID Set a specific machine UUID for the container\n"
72 " --private-network Disable network in container\n",
73 program_invocation_short_name);
78 static int parse_argv(int argc, char *argv[]) {
81 ARG_PRIVATE_NETWORK = 0x100,
85 static const struct option options[] = {
86 { "help", no_argument, NULL, 'h' },
87 { "directory", required_argument, NULL, 'D' },
88 { "user", required_argument, NULL, 'u' },
89 { "controllers", required_argument, NULL, 'C' },
90 { "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK },
91 { "boot", no_argument, NULL, 'b' },
92 { "uuid", required_argument, NULL, ARG_UUID },
101 while ((c = getopt_long(argc, argv, "+hD:u:C:b", options, NULL)) >= 0) {
111 arg_directory = canonicalize_file_name(optarg);
112 if (!arg_directory) {
113 log_error("Failed to canonicalize root directory.");
121 if (!(arg_user = strdup(optarg))) {
122 log_error("Failed to duplicate user name.");
129 strv_free(arg_controllers);
130 arg_controllers = strv_split(optarg, ",");
131 if (!arg_controllers) {
132 log_error("Failed to split controllers list.");
135 strv_uniq(arg_controllers);
139 case ARG_PRIVATE_NETWORK:
140 arg_private_network = true;
155 log_error("Unknown option code %c", c);
163 static int mount_all(const char *dest) {
165 typedef struct MountPoint {
174 static const MountPoint mount_table[] = {
175 { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
176 { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */
177 { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
178 { "/sys", "/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */
179 { "/sys", "/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
180 { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true },
181 { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true },
182 { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
184 { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND, false }, /* Bind mount first */
185 { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */
193 for (k = 0; k < ELEMENTSOF(mount_table); k++) {
196 if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) {
197 log_error("Out of memory");
205 t = path_is_mount_point(where, false);
207 log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t));
216 mkdir_p(where, 0755);
218 if (mount(mount_table[k].what,
221 mount_table[k].flags,
222 mount_table[k].options) < 0 &&
223 mount_table[k].fatal) {
225 log_error("mount(%s) failed: %m", where);
237 static int setup_timezone(const char *dest) {
242 /* Fix the timezone, if possible */
243 if (asprintf(&where, "%s/etc/localtime", dest) < 0) {
244 log_error("Out of memory");
248 if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0)
249 mount("/etc/localtime", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
253 if (asprintf(&where, "%s/etc/timezone", dest) < 0) {
254 log_error("Out of memory");
258 if (mount("/etc/timezone", where, "bind", MS_BIND, NULL) >= 0)
259 mount("/etc/timezone", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
266 static int setup_resolv_conf(const char *dest) {
271 if (arg_private_network)
274 /* Fix resolv.conf, if possible */
275 if (asprintf(&where, "%s/etc/resolv.conf", dest) < 0) {
276 log_error("Out of memory");
280 if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0)
281 mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
288 static int copy_devnodes(const char *dest) {
290 static const char devnodes[] =
308 NULSTR_FOREACH(d, devnodes) {
310 char *from = NULL, *to = NULL;
312 asprintf(&from, "/dev/%s", d);
313 asprintf(&to, "%s/dev/%s", dest, d);
316 log_error("Failed to allocate devnode path");
329 if (stat(from, &st) < 0) {
331 if (errno != ENOENT) {
332 log_error("Failed to stat %s: %m", from);
337 } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
339 log_error("%s is not a char or block device, cannot copy.", from);
343 } else if (mknod(to, st.st_mode, st.st_rdev) < 0) {
345 log_error("mknod(%s) failed: %m", dest);
359 static int setup_dev_console(const char *dest, const char *console) {
370 if (stat(console, &st) < 0) {
371 log_error("Failed to stat %s: %m", console);
375 } else if (!S_ISCHR(st.st_mode)) {
376 log_error("/dev/console is not a char device.");
381 r = chmod_and_chown(console, 0600, 0, 0);
383 log_error("Failed to correct access mode for TTY: %s", strerror(-r));
387 if (asprintf(&to, "%s/dev/console", dest) < 0) {
388 log_error("Out of memory");
393 /* We need to bind mount the right tty to /dev/console since
394 * ptys can only exist on pts file systems. To have something
395 * to bind mount things on we create a device node first, that
396 * has the right major/minor (note that the major minor
397 * doesn't actually matter here, since we mount it over
400 if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
401 log_error("mknod() for /dev/console failed: %m");
406 if (mount(console, to, "bind", MS_BIND, NULL) < 0) {
407 log_error("Bind mount for /dev/console failed: %m");
419 static int setup_kmsg(const char *dest, int kmsg_socket) {
420 char *from = NULL, *to = NULL;
424 struct cmsghdr cmsghdr;
425 uint8_t buf[CMSG_SPACE(sizeof(int))];
428 struct cmsghdr *cmsg;
431 assert(kmsg_socket >= 0);
435 /* We create the kmsg FIFO as /dev/kmsg, but immediately
436 * delete it after bind mounting it to /proc/kmsg. While FIFOs
437 * on the reading side behave very similar to /proc/kmsg,
438 * their writing side behaves differently from /dev/kmsg in
439 * that writing blocks when nothing is reading. In order to
440 * avoid any problems with containers deadlocking due to this
441 * we simply make /dev/kmsg unavailable to the container. */
442 if (asprintf(&from, "%s/dev/kmsg", dest) < 0) {
443 log_error("Out of memory");
448 if (asprintf(&to, "%s/proc/kmsg", dest) < 0) {
449 log_error("Out of memory");
454 if (mkfifo(from, 0600) < 0) {
455 log_error("mkfifo() for /dev/kmsg failed: %m");
460 r = chmod_and_chown(from, 0600, 0, 0);
462 log_error("Failed to correct access mode for /dev/kmsg: %s", strerror(-r));
466 if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
467 log_error("Bind mount for /proc/kmsg failed: %m");
472 fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC);
474 log_error("Failed to open fifo: %m");
482 mh.msg_control = &control;
483 mh.msg_controllen = sizeof(control);
485 cmsg = CMSG_FIRSTHDR(&mh);
486 cmsg->cmsg_level = SOL_SOCKET;
487 cmsg->cmsg_type = SCM_RIGHTS;
488 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
489 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
491 mh.msg_controllen = cmsg->cmsg_len;
493 /* Store away the fd in the socket, so that it stays open as
494 * long as we run the child */
495 k = sendmsg(kmsg_socket, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
496 close_nointr_nofail(fd);
499 log_error("Failed to send FIFO fd: %m");
504 /* And now make the FIFO unavailable as /dev/kmsg... */
515 static int setup_hostname(void) {
519 hn = file_name_from_path(arg_directory);
525 hostname_cleanup(hn);
528 if (sethostname(hn, strlen(hn)) < 0)
537 static int drop_capabilities(void) {
538 static const unsigned long retain[] = {
548 CAP_NET_BIND_SERVICE,
564 for (l = 0; l <= cap_last_cap(); l++) {
567 for (i = 0; i < ELEMENTSOF(retain); i++)
571 if (i < ELEMENTSOF(retain))
574 if (prctl(PR_CAPBSET_DROP, l) < 0) {
575 log_error("PR_CAPBSET_DROP failed: %m");
583 static int is_os_tree(const char *path) {
586 /* We use /bin/sh as flag file if something is an OS */
588 if (asprintf(&p, "%s/bin/sh", path) < 0)
594 return r < 0 ? 0 : 1;
597 static int process_pty(int master, sigset_t *mask) {
599 char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
600 size_t in_buffer_full = 0, out_buffer_full = 0;
601 struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev;
602 bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false;
603 int ep = -1, signal_fd = -1, r;
605 fd_nonblock(STDIN_FILENO, 1);
606 fd_nonblock(STDOUT_FILENO, 1);
607 fd_nonblock(master, 1);
609 if ((signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
610 log_error("signalfd(): %m");
615 if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) {
616 log_error("Failed to create epoll: %m");
622 stdin_ev.events = EPOLLIN|EPOLLET;
623 stdin_ev.data.fd = STDIN_FILENO;
626 stdout_ev.events = EPOLLOUT|EPOLLET;
627 stdout_ev.data.fd = STDOUT_FILENO;
630 master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
631 master_ev.data.fd = master;
634 signal_ev.events = EPOLLIN;
635 signal_ev.data.fd = signal_fd;
637 if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 ||
638 epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
639 epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 ||
640 epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) {
641 log_error("Failed to regiser fds in epoll: %m");
647 struct epoll_event ev[16];
651 if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) {
653 if (errno == EINTR || errno == EAGAIN)
656 log_error("epoll_wait(): %m");
663 for (i = 0; i < nfds; i++) {
664 if (ev[i].data.fd == STDIN_FILENO) {
666 if (ev[i].events & (EPOLLIN|EPOLLHUP))
667 stdin_readable = true;
669 } else if (ev[i].data.fd == STDOUT_FILENO) {
671 if (ev[i].events & (EPOLLOUT|EPOLLHUP))
672 stdout_writable = true;
674 } else if (ev[i].data.fd == master) {
676 if (ev[i].events & (EPOLLIN|EPOLLHUP))
677 master_readable = true;
679 if (ev[i].events & (EPOLLOUT|EPOLLHUP))
680 master_writable = true;
682 } else if (ev[i].data.fd == signal_fd) {
683 struct signalfd_siginfo sfsi;
686 if ((n = read(signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
689 log_error("Failed to read from signalfd: invalid block size");
694 if (errno != EINTR && errno != EAGAIN) {
695 log_error("Failed to read from signalfd: %m");
701 if (sfsi.ssi_signo == SIGWINCH) {
704 /* The window size changed, let's forward that. */
705 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
706 ioctl(master, TIOCSWINSZ, &ws);
715 while ((stdin_readable && in_buffer_full <= 0) ||
716 (master_writable && in_buffer_full > 0) ||
717 (master_readable && out_buffer_full <= 0) ||
718 (stdout_writable && out_buffer_full > 0)) {
720 if (stdin_readable && in_buffer_full < LINE_MAX) {
722 if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) {
724 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
725 stdin_readable = false;
727 log_error("read(): %m");
732 in_buffer_full += (size_t) k;
735 if (master_writable && in_buffer_full > 0) {
737 if ((k = write(master, in_buffer, in_buffer_full)) < 0) {
739 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
740 master_writable = false;
742 log_error("write(): %m");
748 assert(in_buffer_full >= (size_t) k);
749 memmove(in_buffer, in_buffer + k, in_buffer_full - k);
754 if (master_readable && out_buffer_full < LINE_MAX) {
756 if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) {
758 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
759 master_readable = false;
761 log_error("read(): %m");
766 out_buffer_full += (size_t) k;
769 if (stdout_writable && out_buffer_full > 0) {
771 if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) {
773 if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
774 stdout_writable = false;
776 log_error("write(): %m");
782 assert(out_buffer_full >= (size_t) k);
783 memmove(out_buffer, out_buffer + k, out_buffer_full - k);
784 out_buffer_full -= k;
792 close_nointr_nofail(ep);
795 close_nointr_nofail(signal_fd);
800 int main(int argc, char *argv[]) {
802 int r = EXIT_FAILURE, k;
803 char *oldcg = NULL, *newcg = NULL;
804 char **controller = NULL;
806 const char *console = NULL;
807 struct termios saved_attr, raw_attr;
809 bool saved_attr_valid = false;
811 int kmsg_socket_pair[2] = { -1, -1 };
813 log_parse_environment();
816 if ((r = parse_argv(argc, argv)) <= 0)
822 p = path_make_absolute_cwd(arg_directory);
826 arg_directory = get_current_dir_name();
828 if (!arg_directory) {
829 log_error("Failed to determine path");
833 path_kill_slashes(arg_directory);
835 if (geteuid() != 0) {
836 log_error("Need to be root.");
840 if (sd_booted() <= 0) {
841 log_error("Not running on a systemd system.");
845 if (path_equal(arg_directory, "/")) {
846 log_error("Spawning container on root directory not supported.");
850 if (is_os_tree(arg_directory) <= 0) {
851 log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory);
855 if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) {
856 log_error("Failed to determine current cgroup: %s", strerror(-k));
860 if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) {
861 log_error("Failed to allocate cgroup path.");
865 k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0);
867 log_error("Failed to create cgroup: %s", strerror(-k));
871 STRV_FOREACH(controller,arg_controllers) {
872 k = cg_create_and_attach(*controller, newcg, 0);
874 log_warning("Failed to create cgroup in controller %s: %s", *controller, strerror(-k));
877 if ((master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY)) < 0) {
878 log_error("Failed to acquire pseudo tty: %m");
882 if (!(console = ptsname(master))) {
883 log_error("Failed to determine tty name: %m");
887 log_info("Spawning namespace container on %s (console is %s).", arg_directory, console);
889 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
890 ioctl(master, TIOCSWINSZ, &ws);
892 if (unlockpt(master) < 0) {
893 log_error("Failed to unlock tty: %m");
897 if (tcgetattr(STDIN_FILENO, &saved_attr) < 0) {
898 log_error("Failed to get terminal attributes: %m");
902 saved_attr_valid = true;
904 raw_attr = saved_attr;
905 cfmakeraw(&raw_attr);
906 raw_attr.c_lflag &= ~ECHO;
908 if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
909 log_error("Failed to set terminal attributes: %m");
913 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
914 log_error("Failed to create kmsg socket pair");
918 assert_se(sigemptyset(&mask) == 0);
919 sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
920 assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
922 pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
925 log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
927 log_error("clone() failed: %m");
935 const char *home = NULL;
936 uid_t uid = (uid_t) -1;
937 gid_t gid = (gid_t) -1;
938 const char *envp[] = {
939 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
940 "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
945 NULL, /* container_uuid */
949 envp[2] = strv_find_prefix(environ, "TERM=");
951 close_nointr_nofail(master);
953 close_nointr(STDIN_FILENO);
954 close_nointr(STDOUT_FILENO);
955 close_nointr(STDERR_FILENO);
957 close_all_fds(&kmsg_socket_pair[1], 1);
959 reset_all_signal_handlers();
961 assert_se(sigemptyset(&mask) == 0);
962 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
967 if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0)
970 /* Mark / as private, in case somebody marked it shared */
971 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0)
974 if (mount_all(arg_directory) < 0)
977 if (copy_devnodes(arg_directory) < 0)
980 if (setup_dev_console(arg_directory, console) < 0)
983 if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
986 close_nointr_nofail(kmsg_socket_pair[1]);
988 if (setup_timezone(arg_directory) < 0)
991 if (setup_resolv_conf(arg_directory) < 0)
994 if (chdir(arg_directory) < 0) {
995 log_error("chdir(%s) failed: %m", arg_directory);
999 if (open_terminal("dev/console", O_RDWR) != STDIN_FILENO ||
1000 dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
1001 dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
1004 if (mount(arg_directory, "/", "bind", MS_BIND, NULL) < 0) {
1005 log_error("mount(MS_MOVE) failed: %m");
1009 if (chroot(".") < 0) {
1010 log_error("chroot() failed: %m");
1014 if (chdir("/") < 0) {
1015 log_error("chdir() failed: %m");
1023 if (drop_capabilities() < 0)
1028 if (get_user_creds((const char**)&arg_user, &uid, &gid, &home) < 0) {
1029 log_error("get_user_creds() failed: %m");
1033 if (mkdir_parents(home, 0775) < 0) {
1034 log_error("mkdir_parents() failed: %m");
1038 if (safe_mkdir(home, 0775, uid, gid) < 0) {
1039 log_error("safe_mkdir() failed: %m");
1043 if (initgroups((const char*)arg_user, gid) < 0) {
1044 log_error("initgroups() failed: %m");
1048 if (setresgid(gid, gid, gid) < 0) {
1049 log_error("setregid() failed: %m");
1053 if (setresuid(uid, uid, uid) < 0) {
1054 log_error("setreuid() failed: %m");
1059 if ((asprintf((char**)(envp + 3), "HOME=%s", home ? home: "/root") < 0) ||
1060 (asprintf((char**)(envp + 4), "USER=%s", arg_user ? arg_user : "root") < 0) ||
1061 (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
1062 log_error("Out of memory");
1067 if (asprintf((char**)(envp + 6), "container_uuid=%s", arg_uuid) < 0) {
1068 log_error("Out of memory");
1079 /* Automatically search for the init system */
1081 l = 1 + argc - optind;
1082 a = newa(char*, l + 1);
1083 memcpy(a + 1, argv + optind, l * sizeof(char*));
1085 a[0] = (char*) "/usr/lib/systemd/systemd";
1086 execve(a[0], a, (char**) envp);
1088 a[0] = (char*) "/lib/systemd/systemd";
1089 execve(a[0], a, (char**) envp);
1091 a[0] = (char*) "/sbin/init";
1092 execve(a[0], a, (char**) envp);
1093 } else if (argc > optind)
1094 execvpe(argv[optind], argv + optind, (char**) envp);
1096 chdir(home ? home : "/root");
1097 execle("/bin/bash", "-bash", NULL, (char**) envp);
1100 log_error("execv() failed: %m");
1103 _exit(EXIT_FAILURE);
1106 if (process_pty(master, &mask) < 0)
1109 if (saved_attr_valid) {
1110 tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
1111 saved_attr_valid = false;
1114 r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid);
1120 if (saved_attr_valid)
1121 tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
1124 close_nointr_nofail(master);
1126 close_pipe(kmsg_socket_pair);
1129 cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0);
1132 cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true);
1134 free(arg_directory);
1135 strv_free(arg_controllers);