kernel-install: make version/kernel image parameters optional for "add"

Let's make kernel-install a bit easier to use:

If the kernel version is not specified, let's imply "uname -r", so that
we regnerate the entries for the current kernel.

If the kernel image is not specified let's imply using
/usr/lib/modules/$version/vmlinuz, i.e. the location distros like Fedora
drop the kernel into, which we generally recommend people to use.

If the kernel is not found there, don't try to automatically pick the
kernel path, and fail, as before.
This commit is contained in:
Lennart Poettering 2023-11-06 10:47:10 +01:00
parent 658e6cc4ae
commit 9d9e99a8f0
2 changed files with 52 additions and 12 deletions

View file

@ -86,15 +86,17 @@
<variablelist>
<varlistentry>
<term>
<command>add</command>
<replaceable>KERNEL-VERSION</replaceable>
<replaceable>KERNEL-IMAGE</replaceable> [<replaceable>INITRD-FILE</replaceable> ...]
<command>add [[[<replaceable>KERNEL-VERSION</replaceable>] <replaceable>KERNEL-IMAGE</replaceable>] [<replaceable>INITRD-FILE</replaceable> ...]]</command>
</term>
<listitem>
<para>This command expects a kernel version string and a path to a kernel image file as arguments.
Optionally, one or more initrd images may be specified as well (note that plugins might generate
additional ones).</para>
<para>This command takes a kernel version string and a path to a kernel image file as arguments. If
the former is omitted, specified as an empty string or as "-" it defaults to the current kernel
version, i.e. the same string <command>uname -r</command> returns. If the latter is omitted,
specified as an empty string or as "-" defaults to
<filename>/usr/lib/modules/<replaceable>KERNEL_VERSION</replaceable>/vmlinuz</filename>. Optionally,
one or more initrd images may be specified as well (note that plugins might generate additional
ones).</para>
<para>The executable files from <filename>/usr/lib/kernel/install.d/*.install</filename> and
<filename>/etc/kernel/install.d/*.install</filename> (i.e. the plugins) are called with the

View file

@ -2,6 +2,7 @@
#include <getopt.h>
#include <stdbool.h>
#include <sys/utsname.h>
#include "boot-entry.h"
#include "build.h"
@ -15,6 +16,7 @@
#include "fileio.h"
#include "find-esp.h"
#include "format-table.h"
#include "fs-util.h"
#include "id128-util.h"
#include "image-policy.h"
#include "kernel-image.h"
@ -1024,9 +1026,12 @@ static bool bypass(void) {
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(argc >= 3);
assert(argv);
if (arg_root)
@ -1037,15 +1042,44 @@ static int verb_add(int argc, char *argv[], void *userdata) {
c->action = ACTION_ADD;
r = context_set_version(c, argv[1]);
/* 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
* optional, not the 2nd. */
version = argc > 2 ? empty_or_dash_to_null(argv[1]) : NULL;
kernel = argc > 2 ? empty_or_dash_to_null(argv[2]) :
(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) {
vmlinuz = path_join("/usr/lib/modules/", version, "/vmlinuz");
if (!vmlinuz)
return log_oom();
r = laccess(vmlinuz, F_OK);
if (r < 0) {
if (r == -ENOENT)
return log_error_errno(r, "Kernel image not installed to '%s', requiring manual kernel image path specification.", vmlinuz);
return log_error_errno(r, "Failed to determin if kernel image is installed to '%s': %m", vmlinuz);
}
kernel = vmlinuz;
}
r = context_set_version(c, version);
if (r < 0)
return r;
r = context_set_kernel(c, argv[2]);
r = context_set_kernel(c, kernel);
if (r < 0)
return r;
r = context_set_initrds(c, strv_skip(argv, 3));
r = context_set_initrds(c, initrds);
if (r < 0)
return r;
@ -1085,6 +1119,10 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
c->action = ACTION_REMOVE;
/* 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]);
if (r < 0)
return r;
@ -1259,7 +1297,7 @@ static int help(void) {
printf("%1$s [OPTIONS...] COMMAND ...\n\n"
"%5$sAdd and remove kernel and initrd images to and from /boot/%6$s\n"
"\n%3$sUsage:%4$s\n"
" kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD ...]\n"
" kernel-install [OPTIONS...] add [[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]\n"
" kernel-install [OPTIONS...] remove KERNEL-VERSION\n"
" kernel-install [OPTIONS...] inspect [KERNEL-VERSION] KERNEL-IMAGE [INITRD ...]\n"
" kernel-install [OPTIONS...] list\n"
@ -1421,7 +1459,7 @@ static int parse_argv(int argc, char *argv[], Context *c) {
static int run(int argc, char* argv[]) {
static const Verb verbs[] = {
{ "add", 3, VERB_ANY, 0, verb_add },
{ "add", 1, VERB_ANY, 0, verb_add },
{ "remove", 2, VERB_ANY, 0, verb_remove },
{ "inspect", 1, VERB_ANY, VERB_DEFAULT, verb_inspect },
{ "list", 1, 1, 0, verb_list },