From: Yu Watanabe Date: Mon, 25 Aug 2025 16:43:10 +0000 (+0900) Subject: bootctl: do not fail on removing unfied kernel image X-Git-Tag: v258-rc4~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37d1f1573b859e61df46bed4648fa60da5b60102;p=thirdparty%2Fsystemd.git bootctl: do not fail on removing unfied kernel image A boot loader entry for a unified kernel image has BootEntry.kernel : path to the image relative to ESP or XBOOTLDR, BootEntry.path : path to the image. Hence, these two effectively point to the same file. Hence, by unlink command, the image is removed by ``` deref_unlink_file(&known_files, e->kernel, e->root); ``` then later tried again by ``` r = chase_and_unlink(e->path, root, ...); ``` and of course it fails with -ENOENT. Let's ignore the failure there. We already ignore ENOENT on removal at various places, especially in deref_unlink_file(). Fixes #38706. Follow-ups for 8702496bfb0205764569782a9a2ebd11fd80e5e8. --- diff --git a/src/bootctl/bootctl-status.c b/src/bootctl/bootctl-status.c index 81fdeed64e6..069a1d7a4c6 100644 --- a/src/bootctl/bootctl-status.c +++ b/src/bootctl/bootctl-status.c @@ -781,7 +781,7 @@ static int unlink_entry(const BootConfig *config, const char *root, const char * r = boot_config_find_in(config, root, id); if (r < 0) - return r; + return 0; /* There is nothing to remove. */ if (r == config->default_entry) log_warning("%s is the default boot entry", id); @@ -802,6 +802,8 @@ static int unlink_entry(const BootConfig *config, const char *root, const char * log_info("Would remove \"%s\"", e->path); else { r = chase_and_unlink(e->path, root, CHASE_PROHIBIT_SYMLINKS|CHASE_TRIGGER_AUTOFS, 0, NULL); + if (r == -ENOENT) + return 0; /* Already removed? */ if (r < 0) return log_error_errno(r, "Failed to remove \"%s\": %m", e->path); @@ -833,7 +835,8 @@ static int list_remove_orphaned_file( if (arg_dry_run) log_info("Would remove %s", path); else if (unlinkat(dir_fd, de->d_name, 0) < 0) - log_warning_errno(errno, "Failed to remove \"%s\", ignoring: %m", path); + log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, + "Failed to remove \"%s\", ignoring: %m", path); else log_info("Removed %s", path); @@ -920,12 +923,9 @@ int verb_list(int argc, char *argv[], void *userdata) { return cleanup_orphaned_files(&config, arg_esp_path); } else { assert(streq(argv[0], "unlink")); - if (arg_xbootldr_path && xbootldr_devid != esp_devid) { + if (arg_xbootldr_path && xbootldr_devid != esp_devid) r = unlink_entry(&config, arg_xbootldr_path, argv[1]); - if (r == 0 || r != -ENOENT) - return r; - } - return unlink_entry(&config, arg_esp_path, argv[1]); + return RET_GATHER(r, unlink_entry(&config, arg_esp_path, argv[1])); } }