kernel-install refactorings (#40610)
This contains the first two commits from #38764. While @daandemeyer convinced me to base systemd-sysinstall on a new "bootctl link" rather than "kernel-install", I think the refactorings I prepped as part of the original work still make a lot of sense on their own, and I hope I didn't do them for /dev/null.
This commit is contained in:
+168
-129
@@ -51,12 +51,16 @@ static char *arg_root = NULL;
|
||||
static char *arg_image = NULL;
|
||||
static ImagePolicy *arg_image_policy = NULL;
|
||||
static bool arg_legend = true;
|
||||
static BootEntryTokenType arg_entry_token_type = BOOT_ENTRY_TOKEN_AUTO;
|
||||
static char *arg_entry_token = NULL;
|
||||
static BootEntryType arg_boot_entry_type = _BOOT_ENTRY_TYPE_INVALID;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_entry_token, freep);
|
||||
|
||||
typedef enum Action {
|
||||
ACTION_ADD,
|
||||
@@ -109,7 +113,15 @@ typedef struct Context {
|
||||
char **envp;
|
||||
} Context;
|
||||
|
||||
#define CONTEXT_NULL (Context) { .rfd = -EBADF }
|
||||
#define CONTEXT_NULL \
|
||||
(Context) { \
|
||||
.rfd = XAT_FDROOT, \
|
||||
.action = _ACTION_INVALID, \
|
||||
.kernel_image_type = _KERNEL_IMAGE_TYPE_INVALID, \
|
||||
.layout = _LAYOUT_INVALID, \
|
||||
.entry_type = _BOOT_ENTRY_TYPE_INVALID, \
|
||||
.entry_token_type = _BOOT_ENTRY_TOKEN_TYPE_INVALID, \
|
||||
}
|
||||
|
||||
static void context_done(Context *c) {
|
||||
assert(c);
|
||||
@@ -429,20 +441,6 @@ static int context_set_initrds(Context *c, char* const* strv) {
|
||||
return context_set_path_strv(c, strv, "command line", "initrds", &c->initrds);
|
||||
}
|
||||
|
||||
static int context_set_entry_type(Context *c, const char *s) {
|
||||
assert(c);
|
||||
BootEntryType e;
|
||||
if (isempty(s) || streq(s, "all")) {
|
||||
c->entry_type = _BOOT_ENTRY_TYPE_INVALID;
|
||||
return 0;
|
||||
}
|
||||
e = boot_entry_type_from_string(s);
|
||||
if (e < 0)
|
||||
return log_error_errno(e, "Invalid entry type: %s", s);
|
||||
c->entry_type = e;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int context_load_environment(Context *c) {
|
||||
assert(c);
|
||||
|
||||
@@ -695,11 +693,16 @@ static int context_load_plugins(Context *c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_init(Context *c) {
|
||||
static int context_setup(Context *c) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->kernel_image_type < 0)
|
||||
c->kernel_image_type = KERNEL_IMAGE_TYPE_UNKNOWN;
|
||||
if (c->entry_token_type < 0)
|
||||
c->entry_token_type = BOOT_ENTRY_TOKEN_AUTO;
|
||||
|
||||
r = context_open_root(c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -735,6 +738,24 @@ static int context_init(Context *c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_from_cmdline(Context *c, Action action) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
c->action = action;
|
||||
|
||||
c->entry_type = arg_boot_entry_type;
|
||||
|
||||
r = free_and_strdup_warn(&c->entry_token, arg_entry_token);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->entry_token_type = arg_entry_token_type;
|
||||
|
||||
return context_setup(c);
|
||||
}
|
||||
|
||||
static int context_inspect_kernel(Context *c) {
|
||||
assert(c);
|
||||
|
||||
@@ -768,9 +789,18 @@ static int context_ensure_layout(Context *c) {
|
||||
if (!srel_path)
|
||||
return log_oom();
|
||||
|
||||
_cleanup_free_ char *srel = NULL;
|
||||
r = read_one_line_file_at(c->rfd, srel_path, &srel);
|
||||
if (r >= 0) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
r = chase_and_fopenat_unlocked(c->rfd, srel_path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, "re", /* ret_path= */ NULL, &f);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to open '%s': %m", srel_path);
|
||||
} else {
|
||||
_cleanup_free_ char *srel = NULL;
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &srel);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read %s: %m", srel_path);
|
||||
|
||||
if (streq(srel, "type1"))
|
||||
/* The loader/entries.srel file clearly indicates that the installed boot loader
|
||||
* implements the proper standard upstream boot loader spec for Type #1 entries.
|
||||
@@ -784,17 +814,17 @@ static int context_ensure_layout(Context *c) {
|
||||
|
||||
log_debug("%s with '%s' found, using layout=%s.", srel_path, srel, layout_to_string(c->layout));
|
||||
return 0;
|
||||
} else if (r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to read %s: %m", srel_path);
|
||||
}
|
||||
|
||||
_cleanup_free_ char *entry_token_path = path_join(c->boot_root, c->entry_token);
|
||||
if (!entry_token_path)
|
||||
return log_oom();
|
||||
|
||||
r = is_dir_at(c->rfd, entry_token_path, /* follow= */ false);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to check if '%s' is a directory: %m", entry_token_path);
|
||||
if (r > 0) {
|
||||
r = chaseat(c->rfd, entry_token_path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_DIRECTORY, /* ret_path= */ NULL, /* ret_fd= */ NULL);
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -ENOENT, -ENOTDIR))
|
||||
return log_error_errno(r, "Failed to check if '%s' exists and is a directory: %m", entry_token_path);
|
||||
} else {
|
||||
/* If the metadata in $BOOT_ROOT doesn't tell us anything, then check if the entry token
|
||||
* directory already exists. If so, let's assume it's the standard boot loader spec, too. */
|
||||
c->layout = LAYOUT_BLS;
|
||||
@@ -1091,6 +1121,26 @@ static bool bypass(void) {
|
||||
return should_bypass("KERNEL_INSTALL");
|
||||
}
|
||||
|
||||
static int kernel_from_version(const char *version, char **ret_kernel) {
|
||||
_cleanup_free_ char *vmlinuz = NULL;
|
||||
int r;
|
||||
|
||||
assert(version);
|
||||
|
||||
vmlinuz = path_join("/usr/lib/modules/", version, "/vmlinuz");
|
||||
if (!vmlinuz)
|
||||
return log_oom();
|
||||
|
||||
r = access_nofollow(vmlinuz, F_OK);
|
||||
if (r == -ENOENT)
|
||||
return log_error_errno(r, "Kernel image not installed to '%s', specify kernel kernel image path explicitly.", vmlinuz);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine if kernel image is installed to '%s': %m", vmlinuz);
|
||||
|
||||
*ret_kernel = TAKE_PTR(vmlinuz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_add(
|
||||
Context *c,
|
||||
const char *version,
|
||||
@@ -1100,8 +1150,21 @@ static int do_add(
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(version);
|
||||
assert(kernel);
|
||||
|
||||
struct utsname un;
|
||||
if (!version) {
|
||||
assert_se(uname(&un) >= 0);
|
||||
version = un.release;
|
||||
}
|
||||
|
||||
_cleanup_free_ char *vmlinuz = NULL;
|
||||
if (!kernel) {
|
||||
r = kernel_from_version(version, &vmlinuz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
kernel = vmlinuz;
|
||||
}
|
||||
|
||||
r = context_set_version(c, version);
|
||||
if (r < 0)
|
||||
@@ -1122,32 +1185,9 @@ static int do_add(
|
||||
return context_execute(c);
|
||||
}
|
||||
|
||||
static int kernel_from_version(const char *version, char **ret_kernel) {
|
||||
_cleanup_free_ char *vmlinuz = NULL;
|
||||
int r;
|
||||
|
||||
assert(version);
|
||||
|
||||
vmlinuz = path_join("/usr/lib/modules/", version, "/vmlinuz");
|
||||
if (!vmlinuz)
|
||||
return log_oom();
|
||||
|
||||
r = access_nofollow(vmlinuz, F_OK);
|
||||
if (r == -ENOENT)
|
||||
return log_error_errno(r, "Kernel image not installed to '%s', requiring manual kernel image path specification.", vmlinuz);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine if kernel image is installed to '%s': %m", vmlinuz);
|
||||
|
||||
*ret_kernel = TAKE_PTR(vmlinuz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verb_add(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
_cleanup_free_ char *vmlinuz = NULL;
|
||||
const char *version, *kernel;
|
||||
char **initrds;
|
||||
struct utsname un;
|
||||
int r;
|
||||
|
||||
assert(argv);
|
||||
@@ -1158,7 +1198,10 @@ static int verb_add(int argc, char *argv[], void *userdata) {
|
||||
if (bypass())
|
||||
return 0;
|
||||
|
||||
c->action = ACTION_ADD;
|
||||
_cleanup_(context_done) Context c = CONTEXT_NULL;
|
||||
r = context_from_cmdline(&c, ACTION_ADD);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* We use the same order of arguments that "inspect" introduced, i.e. if only on argument is
|
||||
* specified we take it as the kernel path, not the version, i.e. it's the first argument that is
|
||||
@@ -1168,24 +1211,10 @@ static int verb_add(int argc, char *argv[], void *userdata) {
|
||||
(argc > 1 ? empty_or_dash_to_null(argv[1]) : NULL);
|
||||
initrds = strv_skip(argv, 3);
|
||||
|
||||
if (!version) {
|
||||
assert_se(uname(&un) >= 0);
|
||||
version = un.release;
|
||||
}
|
||||
|
||||
if (!kernel) {
|
||||
r = kernel_from_version(version, &vmlinuz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
kernel = vmlinuz;
|
||||
}
|
||||
|
||||
return do_add(c, version, kernel, initrds);
|
||||
return do_add(&c, version, kernel, initrds);
|
||||
}
|
||||
|
||||
static int verb_add_all(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
size_t n = 0;
|
||||
int ret = 0, r;
|
||||
@@ -1198,9 +1227,12 @@ static int verb_add_all(int argc, char *argv[], void *userdata) {
|
||||
if (bypass())
|
||||
return 0;
|
||||
|
||||
c->action = ACTION_ADD;
|
||||
_cleanup_(context_done) Context c = CONTEXT_NULL;
|
||||
r = context_from_cmdline(&c, ACTION_ADD);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fd = chase_and_openat(c->rfd, "/usr/lib/modules", CHASE_AT_RESOLVE_IN_ROOT, O_DIRECTORY|O_RDONLY|O_CLOEXEC, NULL);
|
||||
fd = chase_and_openat(c.rfd, "/usr/lib/modules", CHASE_AT_RESOLVE_IN_ROOT, O_DIRECTORY|O_RDONLY|O_CLOEXEC, NULL);
|
||||
if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to open %s/usr/lib/modules/: %m", strempty(arg_root));
|
||||
|
||||
@@ -1234,7 +1266,7 @@ static int verb_add_all(int argc, char *argv[], void *userdata) {
|
||||
|
||||
_cleanup_(context_done) Context copy = CONTEXT_NULL;
|
||||
|
||||
r = context_copy(c, ©);
|
||||
r = context_copy(&c, ©);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy execution context: %m");
|
||||
|
||||
@@ -1262,18 +1294,17 @@ static int verb_add_all(int argc, char *argv[], void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int run_as_installkernel(int argc, char *argv[], Context *c) {
|
||||
static int run_as_installkernel(int argc, char *argv[]) {
|
||||
/* kernel's install.sh invokes us as
|
||||
* /sbin/installkernel <version> <vmlinuz> <map> <installation-dir>
|
||||
* We ignore the last two arguments. */
|
||||
if (optind + 2 > argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "'installkernel' command requires at least two arguments.");
|
||||
|
||||
return verb_add(3, STRV_MAKE("add", argv[optind], argv[optind+1]), c);
|
||||
return verb_add(3, STRV_MAKE("add", argv[optind], argv[optind+1]), /* userdata= */ NULL);
|
||||
}
|
||||
|
||||
static int verb_remove(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(argc >= 2);
|
||||
@@ -1289,25 +1320,27 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
|
||||
if (bypass())
|
||||
return 0;
|
||||
|
||||
c->action = ACTION_REMOVE;
|
||||
_cleanup_(context_done) Context c = CONTEXT_NULL;
|
||||
r = context_from_cmdline(&c, ACTION_REMOVE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Note, we do not automatically derive the kernel version to remove from uname() here (unlike we do
|
||||
* it for the "add" verb), since we don't want to make it too easy to uninstall your running
|
||||
* kernel, as a safety precaution */
|
||||
|
||||
r = context_set_version(c, argv[1]);
|
||||
r = context_set_version(&c, argv[1]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_prepare_execution(c);
|
||||
r = context_prepare_execution(&c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return context_execute(c);
|
||||
return context_execute(&c);
|
||||
}
|
||||
|
||||
static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
_cleanup_(table_unrefp) Table *t = NULL;
|
||||
_cleanup_free_ char *vmlinuz = NULL;
|
||||
const char *version, *kernel;
|
||||
@@ -1315,7 +1348,10 @@ static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
struct utsname un;
|
||||
int r;
|
||||
|
||||
c->action = ACTION_INSPECT;
|
||||
_cleanup_(context_done) Context c = CONTEXT_NULL;
|
||||
r = context_from_cmdline(&c, ACTION_INSPECT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* When only a single parameter is specified 'inspect' it's the kernel image path, and not the kernel
|
||||
* version. i.e. it's the first argument that is optional, not the 2nd. That's a bit unfortunate, but
|
||||
@@ -1340,19 +1376,19 @@ static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
kernel = vmlinuz;
|
||||
}
|
||||
|
||||
r = context_set_version(c, version);
|
||||
r = context_set_version(&c, version);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_set_kernel(c, kernel);
|
||||
r = context_set_kernel(&c, kernel);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_set_initrds(c, initrds);
|
||||
r = context_set_initrds(&c, initrds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = context_prepare_execution(c);
|
||||
r = context_prepare_execution(&c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1362,40 +1398,40 @@ static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
|
||||
r = table_add_many(t,
|
||||
TABLE_FIELD, "Machine ID",
|
||||
TABLE_ID128, c->machine_id,
|
||||
TABLE_ID128, c.machine_id,
|
||||
TABLE_FIELD, "Kernel Image Type",
|
||||
TABLE_STRING, kernel_image_type_to_string(c->kernel_image_type),
|
||||
TABLE_STRING, kernel_image_type_to_string(c.kernel_image_type),
|
||||
TABLE_FIELD, "Layout",
|
||||
TABLE_STRING, context_get_layout(c),
|
||||
TABLE_STRING, context_get_layout(&c),
|
||||
TABLE_FIELD, "Boot Root",
|
||||
TABLE_STRING, c->boot_root,
|
||||
TABLE_STRING, c.boot_root,
|
||||
TABLE_FIELD, "Entry Token Type",
|
||||
TABLE_STRING, boot_entry_token_type_to_string(c->entry_token_type),
|
||||
TABLE_STRING, boot_entry_token_type_to_string(c.entry_token_type),
|
||||
TABLE_FIELD, "Entry Token",
|
||||
TABLE_STRING, c->entry_token,
|
||||
TABLE_STRING, c.entry_token,
|
||||
TABLE_FIELD, "Entry Directory",
|
||||
TABLE_STRING, c->entry_dir,
|
||||
TABLE_STRING, c.entry_dir,
|
||||
TABLE_FIELD, "Kernel Version",
|
||||
TABLE_VERSION, c->version,
|
||||
TABLE_VERSION, c.version,
|
||||
TABLE_FIELD, "Kernel",
|
||||
TABLE_STRING, c->kernel,
|
||||
TABLE_STRING, c.kernel,
|
||||
TABLE_FIELD, "Initrds",
|
||||
TABLE_STRV, c->initrds,
|
||||
TABLE_STRV, c.initrds,
|
||||
TABLE_FIELD, "Initrd Generator",
|
||||
TABLE_STRING, c->initrd_generator,
|
||||
TABLE_STRING, c.initrd_generator,
|
||||
TABLE_FIELD, "UKI Generator",
|
||||
TABLE_STRING, c->uki_generator,
|
||||
TABLE_STRING, c.uki_generator,
|
||||
TABLE_FIELD, "Plugins",
|
||||
TABLE_STRV, c->plugins,
|
||||
TABLE_STRV, c.plugins,
|
||||
TABLE_FIELD, "Plugin Environment",
|
||||
TABLE_STRV, c->envp);
|
||||
TABLE_STRV, c.envp);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
if (!sd_json_format_enabled(arg_json_format_flags)) {
|
||||
r = table_add_many(t,
|
||||
TABLE_FIELD, "Plugin Arguments",
|
||||
TABLE_STRV, strv_skip(c->argv, 1));
|
||||
TABLE_STRV, strv_skip(c.argv, 1));
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
}
|
||||
@@ -1418,11 +1454,15 @@ static int verb_inspect(int argc, char *argv[], void *userdata) {
|
||||
}
|
||||
|
||||
static int verb_list(int argc, char *argv[], void *userdata) {
|
||||
Context *c = ASSERT_PTR(userdata);
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
fd = chase_and_openat(c->rfd, "/usr/lib/modules", CHASE_AT_RESOLVE_IN_ROOT, O_DIRECTORY|O_RDONLY|O_CLOEXEC, NULL);
|
||||
_cleanup_(context_done) Context c = CONTEXT_NULL;
|
||||
r = context_from_cmdline(&c, ACTION_INSPECT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fd = chase_and_openat(c.rfd, "/usr/lib/modules", CHASE_AT_RESOLVE_IN_ROOT, O_DIRECTORY|O_RDONLY|O_CLOEXEC, NULL);
|
||||
if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to open %s/usr/lib/modules/: %m", strempty(arg_root));
|
||||
|
||||
@@ -1532,7 +1572,7 @@ static int help(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_NO_LEGEND,
|
||||
@@ -1568,7 +1608,6 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
assert(c);
|
||||
|
||||
while ((t = getopt_long(argc, argv, "hv", options, NULL)) >= 0)
|
||||
switch (t) {
|
||||
@@ -1612,7 +1651,7 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
break;
|
||||
|
||||
case ARG_ENTRY_TOKEN:
|
||||
r = parse_boot_entry_token_type(optarg, &c->entry_token_type, &c->entry_token);
|
||||
r = parse_boot_entry_token_type(optarg, &arg_entry_token_type, &arg_entry_token);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
@@ -1645,11 +1684,18 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_BOOT_ENTRY_TYPE:
|
||||
r = context_set_entry_type(c, optarg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
case ARG_BOOT_ENTRY_TYPE: {
|
||||
if (isempty(optarg) || streq(optarg, "all")) {
|
||||
arg_boot_entry_type = _BOOT_ENTRY_TYPE_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
BootEntryType e = boot_entry_type_from_string(optarg);
|
||||
if (e < 0)
|
||||
return log_error_errno(e, "Invalid entry type: %s", optarg);
|
||||
arg_boot_entry_type = e;
|
||||
break;
|
||||
}
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
@@ -1664,33 +1710,30 @@ static int parse_argv(int argc, char *argv[], Context *c) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int run(int argc, char* argv[]) {
|
||||
static int kernel_install_main(int argc, char *argv[]) {
|
||||
static const Verb verbs[] = {
|
||||
{ "add", 1, VERB_ANY, 0, verb_add },
|
||||
{ "add-all", 1, 1, 0, verb_add_all },
|
||||
{ "remove", 2, VERB_ANY, 0, verb_remove },
|
||||
{ "inspect", 1, VERB_ANY, VERB_DEFAULT, verb_inspect },
|
||||
{ "list", 1, 1, 0, verb_list },
|
||||
{ "add", 1, VERB_ANY, 0, verb_add },
|
||||
{ "add-all", 1, 1, 0, verb_add_all },
|
||||
{ "remove", 2, VERB_ANY, 0, verb_remove },
|
||||
{ "inspect", 1, VERB_ANY, VERB_DEFAULT, verb_inspect },
|
||||
{ "list", 1, 1, 0, verb_list },
|
||||
{}
|
||||
};
|
||||
_cleanup_(context_done) Context c = {
|
||||
.rfd = AT_FDCWD,
|
||||
.action = _ACTION_INVALID,
|
||||
.kernel_image_type = KERNEL_IMAGE_TYPE_UNKNOWN,
|
||||
.layout = _LAYOUT_INVALID,
|
||||
.entry_type = _BOOT_ENTRY_TYPE_INVALID,
|
||||
.entry_token_type = BOOT_ENTRY_TOKEN_AUTO,
|
||||
};
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||
_cleanup_(umount_and_freep) char *mounted_dir = NULL;
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, /* userdata= */ NULL);
|
||||
}
|
||||
|
||||
static int run(int argc, char* argv[]) {
|
||||
int r;
|
||||
|
||||
log_setup();
|
||||
|
||||
r = parse_argv(argc, argv, &c);
|
||||
r = parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||
_cleanup_(umount_and_freep) char *mounted_dir = NULL;
|
||||
if (arg_image) {
|
||||
assert(!arg_root);
|
||||
|
||||
@@ -1713,14 +1756,10 @@ static int run(int argc, char* argv[]) {
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = context_init(&c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (invoked_as(argv, "installkernel"))
|
||||
return run_as_installkernel(argc, argv, &c);
|
||||
return run_as_installkernel(argc, argv);
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, &c);
|
||||
return kernel_install_main(argc, argv);
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
|
||||
|
||||
Reference in New Issue
Block a user