#include "log.h"
#include "util.h"
#include "missing.h"
+#include "cgroup-util.h"
+#include "sd-daemon.h"
static char *arg_directory = NULL;
const char *type;
const char *options;
unsigned long flags;
+ bool fatal;
} MountPoint;
static const MountPoint mount_table[] = {
- { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV },
- { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND }, /* Bind mount first */
- { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT }, /* Then, make it r/o */
- { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY },
- { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID },
- { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND },
- { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV },
+ { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
+ { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */
+ { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
+ { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true },
+ { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID, true },
+ { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true },
+ { "tmpfs", "/dev/.run", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
+#ifdef HAVE_SELINUX
+ { "selinux", "/selinux", "selinuxfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false },
+#endif
};
unsigned k;
where,
mount_table[k].type,
mount_table[k].flags,
- mount_table[k].options) < 0) {
+ mount_table[k].options) < 0 &&
+ mount_table[k].fatal) {
log_error("mount(%s) failed: %m", where);
int main(int argc, char *argv[]) {
pid_t pid = 0;
- int r = EXIT_FAILURE;
+ int r = EXIT_FAILURE, k;
+ char *oldcg = NULL, *newcg = NULL;
log_parse_environment();
log_open();
goto finish;
}
+ if (sd_booted() <= 0) {
+ log_error("Not running on a systemd system.");
+ goto finish;
+ }
+
if (path_equal(arg_directory, "/")) {
log_error("Spawning container on root directory not supported.");
goto finish;
log_info("Spawning namespace container on %s.", arg_directory);
+ if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) {
+ log_error("Failed to determine current cgroup: %s", strerror(-k));
+ goto finish;
+ }
+
+ if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) {
+ log_error("Failed to allocate cgroup path.");
+ goto finish;
+ }
+
+ if ((k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0)) < 0) {
+ log_error("Failed to create cgroup: %s", strerror(-k));
+ goto finish;
+ }
+
if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS, NULL)) < 0) {
log_error("clone() failed: %m");
goto finish;
r = EXIT_FAILURE;
finish:
- free(arg_directory);
+ if (oldcg)
+ cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0);
+
+ if (newcg)
+ cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true);
- if (pid > 0)
- kill(pid, SIGTERM);
+ free(arg_directory);
+ free(oldcg);
+ free(newcg);
return r;
}