]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Use cleanup handler to unload image
authorJan Janssen <medhefgo@web.de>
Mon, 7 Feb 2022 12:05:56 +0000 (13:05 +0100)
committerLuca Boccassi <bluca@debian.org>
Sat, 21 May 2022 14:11:13 +0000 (15:11 +0100)
This also moves the message about failed image execution into
image_start() as we would otherwise show two error messages if
any of the preparatory steps failed.

src/boot/efi/boot.c
src/boot/efi/drivers.c
src/boot/efi/util.h

index fb08b99333b8e2e577c9afd504ee0bc6c30f105d..8ad2ebe526367e2b547697824c37f6ced9ef0a34 100644 (file)
@@ -2322,7 +2322,7 @@ static EFI_STATUS image_start(
                 const ConfigEntry *entry) {
 
         _cleanup_(devicetree_cleanup) struct devicetree_state dtstate = {};
-        EFI_HANDLE image;
+        _cleanup_(unload_imagep) EFI_HANDLE image = NULL;
         _cleanup_freepool_ EFI_DEVICE_PATH *path = NULL;
         CHAR16 *options;
         EFI_STATUS err;
@@ -2363,10 +2363,8 @@ static EFI_STATUS image_start(
 
                 err = BS->OpenProtocol(image, &LoadedImageProtocol, (void **)&loaded_image,
                                        parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-                if (EFI_ERROR(err)) {
-                        log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err);
-                        goto out_unload;
-                }
+                if (EFI_ERROR(err))
+                        return log_error_status_stall(err, L"Error getting LoadedImageProtocol handle: %r", err);
                 loaded_image->LoadOptions = options;
                 loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions);
 
@@ -2376,9 +2374,11 @@ static EFI_STATUS image_start(
 
         efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0);
         err = BS->StartImage(image, NULL, NULL);
-out_unload:
-        BS->UnloadImage(image);
-        return err;
+        graphics_mode(FALSE);
+        if (err != EFI_SUCCESS)
+                return log_error_status_stall(err, L"Failed to execute %s (%s): %r", entry->title_show, entry->loader, err);
+
+        return EFI_SUCCESS;
 }
 
 static void config_free(Config *config) {
@@ -2623,11 +2623,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 (void) process_random_seed(root_dir, config.random_seed_mode);
 
                 err = image_start(image, &config, entry);
-                if (EFI_ERROR(err)) {
-                        graphics_mode(FALSE);
-                        log_error_stall(L"Failed to execute %s (%s): %r", entry->title_show, entry->loader, err);
+                if (err != EFI_SUCCESS)
+                        /* Not using EFI_ERROR here because positive values are also errors like with any
+                         * other (userspace) program. */
                         goto out;
-                }
 
                 menu = TRUE;
                 config.timeout_sec = 0;
index 2ff87261dabbf4666bd13d4b7939590cbfc4a8d6..65c74c461d52c8c454f2a271e1c08b7e9004cf9a 100644 (file)
@@ -6,17 +6,12 @@
 #include "drivers.h"
 #include "util.h"
 
-static void efi_unload_image(EFI_HANDLE *h) {
-        if (*h)
-                (void) BS->UnloadImage(*h);
-}
-
 static EFI_STATUS load_one_driver(
                 EFI_HANDLE parent_image,
                 EFI_LOADED_IMAGE *loaded_image,
                 const CHAR16 *fname) {
 
-        _cleanup_(efi_unload_image) EFI_HANDLE image = NULL;
+        _cleanup_(unload_imagep) EFI_HANDLE image = NULL;
         _cleanup_freepool_ EFI_DEVICE_PATH *path = NULL;
         _cleanup_freepool_ CHAR16 *spath = NULL;
         EFI_STATUS err;
index c45374a08ebe7f6836c0d47d1b731fdd45ee8746..af204e9ab57cdec69969e1512237c8fc1b467507 100644 (file)
@@ -86,6 +86,11 @@ static inline void file_closep(EFI_FILE **handle) {
         (*handle)->Close(*handle);
 }
 
+static inline void unload_imagep(EFI_HANDLE *image) {
+        if (*image)
+                (void) BS->UnloadImage(*image);
+}
+
 /*
  * Allocated random UUID, intended to be shared across tools that implement
  * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the