diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index d7c2aa3a4f..2387eb07fa 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -197,9 +197,20 @@ static int context_copy(const Context *source, Context *ret) { } static int context_open_root(Context *c) { + int r; + assert(c); assert(c->rfd < 0); + if (isempty(arg_root)) + return 0; + + r = path_is_root(arg_root); + if (r < 0) + return log_error_errno(r, "Failed to determine if '%s' is the root directory: %m", arg_root); + if (r > 0) + return 0; + c->rfd = open(empty_to_root(arg_root), O_CLOEXEC | O_DIRECTORY | O_PATH); if (c->rfd < 0) return log_error_errno(errno, "Failed to open root directory '%s': %m", empty_to_root(arg_root)); @@ -301,7 +312,7 @@ static int context_set_version(Context *c, const char *s) { return context_set_string(s, "command line", "kernel version", &c->version); } -static int context_set_path(Context *c, int rfd, const char *s, const char *source, const char *name, char **dest) { +static int context_set_path(Context *c, const char *s, const char *source, const char *name, char **dest) { char *p; int r; @@ -313,13 +324,17 @@ static int context_set_path(Context *c, int rfd, const char *s, const char *sour if (*dest || !s) return 0; - if (rfd >= 0) - r = chaseat(rfd, s, CHASE_AT_RESOLVE_IN_ROOT, &p, /* ret_fd = */ NULL); - else - r = chase(s, /* root = */ NULL, 0, &p, /* ret_fd = */ NULL); - if (r < 0) - return log_warning_errno(r, "Failed to chase path %s for %s specified via %s, ignoring: %m", - s, name, source); + if (c->rfd >= 0) { + r = chaseat(c->rfd, s, CHASE_AT_RESOLVE_IN_ROOT, &p, /* ret_fd = */ NULL); + if (r < 0) + return log_warning_errno(r, "Failed to chase path %s for %s specified via %s, ignoring: %m", + s, name, source); + } else { + r = path_make_absolute_cwd(s, &p); + if (r < 0) + return log_warning_errno(r, "Failed to make path '%s' for %s specified via %s absolute, ignoring: %m", + s, name, source); + } log_debug("%s (%s) set via %s.", name, p, source); @@ -329,21 +344,20 @@ static int context_set_path(Context *c, int rfd, const char *s, const char *sour static int context_set_boot_root(Context *c, const char *s, const char *source) { assert(c); - return context_set_path(c, c->rfd, s, source, "BOOT_ROOT", &c->boot_root); + return context_set_path(c, s, source, "BOOT_ROOT", &c->boot_root); } static int context_set_conf_root(Context *c, const char *s, const char *source) { assert(c); - return context_set_path(c, c->rfd, s, source, "CONF_ROOT", &c->conf_root); + return context_set_path(c, s, source, "CONF_ROOT", &c->conf_root); } static int context_set_kernel(Context *c, const char *s) { assert(c); - /* The path specified via command line should be relative to CWD. */ - return context_set_path(c, AT_FDCWD, s, "command line", "kernel image file", &c->kernel); + return context_set_path(c, s, "command line", "kernel image file", &c->kernel); } -static int context_set_path_strv(Context *c, int rfd, char* const* strv, const char *source, const char *name, char ***dest) { +static int context_set_path_strv(Context *c, char* const* strv, const char *source, const char *name, char ***dest) { _cleanup_strv_free_ char **w = NULL; int r; @@ -358,14 +372,17 @@ static int context_set_path_strv(Context *c, int rfd, char* const* strv, const c STRV_FOREACH(s, strv) { char *p; - if (rfd >= 0) - r = chaseat(rfd, *s, CHASE_AT_RESOLVE_IN_ROOT, &p, /* ret_fd = */ NULL); - else - r = chase(*s, /* root = */ NULL, 0, &p, /* ret_fd = */ NULL); - if (r < 0) - return log_warning_errno(r, "Failed to chase path %s for %s specified via %s: %m", - *s, name, source); - + if (c->rfd >= 0) { + r = chaseat(c->rfd, *s, CHASE_AT_RESOLVE_IN_ROOT, &p, /* ret_fd = */ NULL); + if (r < 0) + return log_warning_errno(r, "Failed to chase path %s for %s specified via %s: %m", + *s, name, source); + } else { + r = path_make_absolute_cwd(*s, &p); + if (r < 0) + return log_warning_errno(r, "Failed to make path '%s' for %s specified via %s absolute, ignoring: %m", + *s, name, source); + } r = strv_consume(&w, p); if (r < 0) return log_oom(); @@ -392,12 +409,12 @@ static int context_set_plugins(Context *c, const char *s, const char *source) { if (!v) return log_oom(); - return context_set_path_strv(c, c->rfd, v, source, "plugins", &c->plugins); + return context_set_path_strv(c, v, source, "plugins", &c->plugins); } static int context_set_initrds(Context *c, char* const* strv) { assert(c); - return context_set_path_strv(c, AT_FDCWD, strv, "command line", "initrds", &c->initrds); + return context_set_path_strv(c, strv, "command line", "initrds", &c->initrds); } static int context_load_environment(Context *c) { @@ -641,9 +658,15 @@ static int context_ensure_boot_root(Context *c) { return r; /* If all else fails, use /boot. */ - r = chaseat(c->rfd, "/boot", CHASE_AT_RESOLVE_IN_ROOT, &c->boot_root, /* ret_fd = */ NULL); - if (r < 0) - return log_error_errno(r, "Failed to chase '/boot': %m"); + if (c->rfd >= 0) { + r = chaseat(c->rfd, "/boot", CHASE_AT_RESOLVE_IN_ROOT, &c->boot_root, /* ret_fd = */ NULL); + if (r < 0) + return log_error_errno(r, "Failed to chase '/boot': %m"); + } else { + c->boot_root = strdup("/boot"); + if (!c->boot_root) + return log_oom(); + } log_debug("KERNEL_INSTALL_BOOT_ROOT autodetection yielded no candidates, using \"%s\".", c->boot_root); return 0; @@ -1667,7 +1690,7 @@ static int run(int argc, char* argv[]) { {} }; _cleanup_(context_done) Context c = { - .rfd = -EBADF, + .rfd = AT_FDCWD, .action = _ACTION_INVALID, .kernel_image_type = KERNEL_IMAGE_TYPE_UNKNOWN, .layout = _LAYOUT_INVALID,