]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add --entry-type=type1|type2 option to kernel-install.
authorLi Tian <litian@redhat.com>
Tue, 8 Jul 2025 06:44:35 +0000 (14:44 +0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 10 Jul 2025 16:07:23 +0000 (18:07 +0200)
Both kernel-core and kernel-uki-virt call kernel-install upon removal. Need an additional argument to avoid complete removal for both traditional kernel and UKI.

Signed-off-by: Li Tian <litian@redhat.com>
shell-completion/bash/kernel-install
src/kernel-install/50-depmod.install
src/kernel-install/90-loaderentry.install.in
src/kernel-install/kernel-install.c
src/kernel-install/test-kernel-install.sh
src/shared/bootspec.c
src/shared/bootspec.h

index d3a9d9bbd8480cd1634ad6f295be6592ce9bd3e7..a7714ad1880318990525e4fa14ecb5ca1f11229e 100644 (file)
@@ -21,6 +21,15 @@ _kernel_install() {
     local comps
     local MACHINE_ID
     local cur=${COMP_WORDS[COMP_CWORD]}
+    local prev=${COMP_WORDS[COMP_CWORD-1]}
+    local entry_types="type1 type2 all"
+
+    case "$prev" in
+        --entry-type)
+            COMPREPLY=( $(compgen -W "$entry_types" -- "$cur") )
+            return 0
+            ;;
+    esac
 
     case $COMP_CWORD in
         1)
@@ -42,6 +51,11 @@ _kernel_install() {
             ;;
     esac
 
+    if [[ "${COMP_WORDS[1]}" == "remove" ]] && [[ $cur == -* ]]; then
+        COMPREPLY=( $(compgen -W '--entry-type' -- "$cur") )
+        return 0
+    fi
+
     COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
     return 0
 }
index 08247c735b6f298b67be3ff638efbf7b9c4378af..aa2bb31a513fe2129d5d0868b85aa357fb68af23 100755 (executable)
@@ -33,6 +33,11 @@ case "$COMMAND" in
         exec depmod -a "$KERNEL_VERSION"
         ;;
     remove)
+        [ "$KERNEL_INSTALL_BOOT_ENTRY_TYPE" = "type2" ] || \
+        [ "$KERNEL_INSTALL_BOOT_ENTRY_TYPE" = "type1" ] && \
+        [ -d "/lib/modules/$KERNEL_VERSION/kernel" ] && \
+            echo "Multiple entry types exist, not removing modules.dep or associated files." && \
+            exit 0
         [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
             echo "Removing /lib/modules/${KERNEL_VERSION}/modules.dep and associated files"
         exec rm -f \
index 75c0b47acaa1a94dc9626eb54bc516ac580478ea..6945a0fd288eccc34a7421227d326c61fc3382a5 100755 (executable)
@@ -49,6 +49,11 @@ LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION.conf"
 
 case "$COMMAND" in
     remove)
+        if [ -f "/lib/modules/$KERNEL_VERSION/vmlinuz" ] && [ "$KERNEL_INSTALL_BOOT_ENTRY_TYPE" = "type2" ]; then
+            [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+                echo "BOOT_ENTRY_TYPE=type2, not removing loader entries."
+            exit 0
+        fi
         [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
             echo "Removing ${LOADER_ENTRY%.conf}*.conf"
         exec rm -f \
index 73dcc37c91653d21b4b4e604eafe1290195737a7..bcc3d145b341b2a3537edeaaf78049c2ddf26505 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "argv-util.h"
 #include "boot-entry.h"
+#include "bootspec.h"
 #include "build.h"
 #include "chase.h"
 #include "conf-files.h"
@@ -88,6 +89,7 @@ typedef struct Context {
         Action action;
         sd_id128_t machine_id;
         bool machine_id_is_random;
+        BootEntryType entry_type;
         KernelImageType kernel_image_type;
         Layout layout;
         char *layout_other;
@@ -427,6 +429,20 @@ 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);
 
@@ -983,6 +999,7 @@ static int context_build_environment(Context *c) {
                                  "KERNEL_INSTALL_LAYOUT",           context_get_layout(c),
                                  "KERNEL_INSTALL_INITRD_GENERATOR", strempty(c->initrd_generator),
                                  "KERNEL_INSTALL_UKI_GENERATOR",    strempty(c->uki_generator),
+                                 "KERNEL_INSTALL_BOOT_ENTRY_TYPE",  boot_entry_type_to_string(c->entry_type),
                                  "KERNEL_INSTALL_STAGING_AREA",     c->staging_area);
         if (r < 0)
                 return log_error_errno(r, "Failed to build environment variables for plugins: %m");
@@ -1487,6 +1504,9 @@ static int help(void) {
                "     --root=PATH               Operate on an alternate filesystem root\n"
                "     --image=PATH              Operate on disk image as filesystem root\n"
                "     --image-policy=POLICY     Specify disk image dissection policy\n"
+               "     --entry-type=type1|type2|all\n"
+               "                               Operate only on the specified bootloader\n"
+               "                               entry type\n"
                "\n"
                "This program may also be invoked as 'installkernel':\n"
                "  installkernel  [OPTIONS...] VERSION VMLINUZ [MAP] [INSTALLATION-DIR]\n"
@@ -1516,6 +1536,7 @@ static int parse_argv(int argc, char *argv[], Context *c) {
                 ARG_ROOT,
                 ARG_IMAGE,
                 ARG_IMAGE_POLICY,
+                ARG_BOOT_ENTRY_TYPE,
         };
         static const struct option options[] = {
                 { "help",                 no_argument,       NULL, 'h'                      },
@@ -1531,6 +1552,7 @@ static int parse_argv(int argc, char *argv[], Context *c) {
                 { "image",                required_argument, NULL, ARG_IMAGE                },
                 { "image-policy",         required_argument, NULL, ARG_IMAGE_POLICY         },
                 { "no-legend",            no_argument,       NULL, ARG_NO_LEGEND            },
+                { "entry-type",           required_argument, NULL, ARG_BOOT_ENTRY_TYPE      },
                 {}
         };
         int t, r;
@@ -1614,6 +1636,12 @@ 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;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1641,6 +1669,7 @@ static int run(int argc, char* argv[]) {
                 .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;
index 51d618e6501e888dee9a269a231e47e5f84e4dee..7da8285969bdf5e6c2a01d6d67a8b76c98ccdf8c 100755 (executable)
@@ -97,6 +97,13 @@ test ! -e "$entry"
 test ! -e "$BOOT_ROOT/the-token/1.1.1/linux"
 test ! -e "$BOOT_ROOT/the-token/1.1.1/initrd"
 
+# Test --entry-type options
+"$kernel_install" -v add 1.1.1 "$D/sources/linux" "$D/sources/initrd"
+"$kernel_install" -v remove 1.1.1 --entry-type=type1
+test ! -e "$entry"
+test ! -e "$BOOT_ROOT/the-token/1.1.1/linux"
+test ! -e "$BOOT_ROOT/the-token/1.1.1/initrd"
+
 # Invoke kernel-install as installkernel
 ln -s --relative -v "$kernel_install" "$D/sources/installkernel"
 "$D/sources/installkernel" -v 1.1.2 "$D/sources/linux" System.map /somedirignored
index 7788d6551630884d85fcad0030491b23cca16a01..b0196f996d0bc9f9e9a619386891de63054b0236 100644 (file)
@@ -48,7 +48,7 @@ static const char* const boot_entry_type_table[_BOOT_ENTRY_TYPE_MAX] = {
         [BOOT_ENTRY_AUTO]   = "auto",
 };
 
-DEFINE_STRING_TABLE_LOOKUP_TO_STRING(boot_entry_type, BootEntryType);
+DEFINE_STRING_TABLE_LOOKUP(boot_entry_type, BootEntryType);
 
 static const char* const boot_entry_source_description_table[_BOOT_ENTRY_SOURCE_MAX] = {
         [BOOT_ENTRY_ESP]      = "EFI System Partition",
index dd192b4722864e61eaed1e5080eb6b123c03f7bd..1ccdf20606e7eb1d15d28879b4b5105e4331da04 100644 (file)
@@ -93,6 +93,7 @@ typedef struct BootConfig {
 
 const char* boot_entry_type_description_to_string(BootEntryType) _const_;
 const char* boot_entry_type_to_string(BootEntryType) _const_;
+BootEntryType boot_entry_type_from_string(const char *s) _pure_;
 
 const char* boot_entry_source_description_to_string(BootEntrySource) _const_;
 const char* boot_entry_source_to_string(BootEntrySource) _const_;