X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=09153c87ce2694de46835467aa19f99838ae75b8;hp=7b415710345eafc4501d3dcf3ad82d8851ea3786;hb=e724b0639c43c2821613fc4f7f755f87c49a22e8;hpb=ae018d9bc900d6355dea4af05119b49c67945184 diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 7b4157103..09153c87c 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" @@ -173,7 +176,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hD:u:C:bj", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "+hD:u:C:bM:j", options, NULL)) >= 0) { switch (c) { @@ -222,6 +225,11 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_UUID: + if (!id128_is_valid(optarg)) { + log_error("Invalid UUID: %s", optarg); + return -EINVAL; + } + arg_uuid = optarg; break; @@ -923,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; @@ -931,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); @@ -959,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) { @@ -1212,7 +1222,7 @@ finish: 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; @@ -1226,9 +1236,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; @@ -1253,7 +1267,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; @@ -1276,7 +1290,7 @@ int main(int argc, char *argv[]) { } 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; } @@ -1292,32 +1306,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); @@ -1361,6 +1357,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); @@ -1696,16 +1694,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; }