X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=b91b0b8a91f4bccc9011028e20a101bb9506fbf7;hp=0a46313636bd0183739fb6607dd20bb6345c2131;hb=77b6e19458f37cfde127ec6aa9494c0ac45ad890;hpb=aa96c6cb44a6eeccc506ae055aae2519a7f914e1 diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0a4631363..b91b0b8a9 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -43,6 +42,10 @@ #include #include +#ifdef HAVE_XATTR +#include +#endif + #include #include "log.h" @@ -928,6 +931,7 @@ static int setup_cgroup(const char *path) { } static int save_attributes(const char *cgroup, pid_t pid, const char *uuid, const char *directory) { +#ifdef HAVE_XATTR _cleanup_free_ char *path = NULL; char buf[DECIMAL_STR_MAX(pid_t)]; int r = 0, k; @@ -936,7 +940,6 @@ static int save_attributes(const char *cgroup, pid_t pid, const char *uuid, cons assert(pid >= 0); assert(arg_directory); -#ifdef HAVE_XATTR assert_se(snprintf(buf, sizeof(buf), "%lu", (unsigned long) pid) < (int) sizeof(buf)); r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup, NULL, &path); @@ -964,8 +967,10 @@ static int save_attributes(const char *cgroup, pid_t pid, const char *uuid, cons if (r == 0) r = k; } -#endif return r; +#else + return 0; +#endif } static int drop_capabilities(void) { @@ -1214,10 +1219,22 @@ finish: return r; } +static bool audit_enabled(void) { + int fd; + + fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); + if (fd >= 0) { + close_nointr_nofail(fd); + return true; + } + + return false; +} + int main(int argc, char *argv[]) { pid_t pid = 0; int r = EXIT_FAILURE, k; - _cleanup_free_ char *machine_root = NULL, *name = NULL, *escaped = NULL, *newcg = NULL; + _cleanup_free_ char *newcg = NULL; _cleanup_close_ int master = -1; int n_fd_passed; const char *console = NULL; @@ -1231,9 +1248,13 @@ int main(int argc, char *argv[]) { log_parse_environment(); log_open(); - r = parse_argv(argc, argv); - if (r <= 0) + k = parse_argv(argc, argv); + if (k < 0) + goto finish; + else if (k == 0) { + r = EXIT_SUCCESS; goto finish; + } if (arg_directory) { char *p; @@ -1258,7 +1279,7 @@ int main(int argc, char *argv[]) { goto finish; } - hostname_cleanup(arg_machine); + hostname_cleanup(arg_machine, false); if (isempty(arg_machine)) { log_error("Failed to determine machine name automatically, please use -M."); goto finish; @@ -1275,13 +1296,20 @@ int main(int argc, char *argv[]) { goto finish; } + if (audit_enabled()) { + log_warning("The kernel auditing subsystem is known to be incompatible with containers.\n" + "Please make sure to turn off auditing with 'audit=0' on the kernel command\n" + "line before using systemd-nspawn. Sleeping for 5s...\n"); + sleep(5); + } + if (path_equal(arg_directory, "/")) { log_error("Spawning container on root directory not supported."); goto finish; } if (path_is_os_tree(arg_directory) <= 0) { - log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory); + log_error("Directory %s doesn't look like an OS root directory (/etc/os-release is missing). Refusing.", arg_directory); goto finish; } @@ -1297,32 +1325,14 @@ int main(int argc, char *argv[]) { fdset_close_others(fds); log_open(); - k = cg_get_machine_path(&machine_root); + k = cg_get_machine_path(arg_machine, &newcg); if (k < 0) { log_error("Failed to determine machine cgroup path: %s", strerror(-k)); goto finish; } - name = strappend(arg_machine, ".nspawn"); - if (!name) { - log_oom(); - goto finish; - } - - escaped = cg_escape(name); - if (!escaped) { - log_oom(); - goto finish; - } - - newcg = strjoin(machine_root, "/", escaped, NULL); - if (!newcg) { - log_oom(); - goto finish; - } - - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, newcg, false); - if (r <= 0 && r != -ENOENT) { + k = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, newcg, true); + if (k <= 0 && k != -ENOENT) { log_error("Container already running."); free(newcg); @@ -1366,6 +1376,8 @@ int main(int argc, char *argv[]) { goto finish; } + sd_notify(0, "READY=1"); + assert_se(sigemptyset(&mask) == 0); sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1); assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0); @@ -1701,16 +1713,16 @@ int main(int argc, char *argv[]) { if (saved_attr_valid) tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); - r = wait_for_terminate(pid, &status); - if (r < 0) { + k = wait_for_terminate(pid, &status); + if (k < 0) { r = EXIT_FAILURE; break; } if (status.si_code == CLD_EXITED) { + r = status.si_status; if (status.si_status != 0) { log_error("Container failed with error code %i.", status.si_status); - r = status.si_status; break; }