]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sleep: record whether the hibernation device is auto swap (with "swap" designator)
authorMike Yuan <me@yhndnzj.com>
Sat, 3 May 2025 16:02:54 +0000 (18:02 +0200)
committerMike Yuan <me@yhndnzj.com>
Mon, 5 May 2025 17:37:10 +0000 (19:37 +0200)
src/sleep/sleep.c

index 7eb3130c4e89abb7182c79d16b5ff36427d3002e..2149a49299c1114adcb55303a51f10f1128077ac 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "battery-capacity.h"
 #include "battery-util.h"
+#include "blockdev-util.h"
 #include "build.h"
 #include "bus-error.h"
 #include "bus-locator.h"
 
 static SleepOperation arg_operation = _SLEEP_OPERATION_INVALID;
 
+#if ENABLE_EFI
+static int determine_auto_swap(sd_device *device) {
+        _cleanup_(sd_device_unrefp) sd_device *origin = NULL;
+        const char *part_designator;
+        int r;
+
+        /* Check if the selected hibernation device is the "auto" one. Specifically, trace to the partition
+         * block device and check if ID_DISSECT_PART_DESIGNATOR property is set to "swap" by udev
+         * dissect_image builtin. Later hibernate-resume-generator will generate cryptsetup unit based on
+         * this info. */
+
+        assert(device);
+
+        r = block_device_get_originating(device, &origin);
+        if (r < 0 && r != -ENOENT)
+                return r;
+        if (r >= 0)
+                device = origin;
+
+        r = sd_device_get_property_value(device, "ID_DISSECT_PART_DESIGNATOR", &part_designator);
+        if (r == -ENOENT)
+                return false;
+        if (r < 0)
+                return r;
+
+        return streq(part_designator, "swap");
+}
+#endif
+
 static int write_efi_hibernate_location(const HibernationDevice *hibernation_device, bool required) {
         int log_level = required ? LOG_ERR : LOG_DEBUG;
 
@@ -64,7 +94,7 @@ static int write_efi_hibernate_location(const HibernationDevice *hibernation_dev
         const char *uuid_str;
         sd_id128_t uuid;
         struct utsname uts = {};
-        int r, log_level_ignore = required ? LOG_WARNING : LOG_DEBUG;
+        int r, auto_swap, log_level_ignore = required ? LOG_WARNING : LOG_DEBUG;
 
         assert(hibernation_device);
 
@@ -87,6 +117,11 @@ static int write_efi_hibernate_location(const HibernationDevice *hibernation_dev
                 return log_full_errno(log_level, r, "Failed to parse ID_FS_UUID '%s' for device '%s': %m",
                                       uuid_str, hibernation_device->path);
 
+        auto_swap = determine_auto_swap(device);
+        if (auto_swap < 0)
+                log_full_errno(log_level_ignore, auto_swap,
+                               "Failed to get partition designator of '%s', ignoring: %m", hibernation_device->path);
+
         if (uname(&uts) < 0)
                 log_full_errno(log_level_ignore, errno, "Failed to get kernel info, ignoring: %m");
 
@@ -102,6 +137,7 @@ static int write_efi_hibernate_location(const HibernationDevice *hibernation_dev
                         &v,
                         SD_JSON_BUILD_PAIR_UUID("uuid", uuid),
                         SD_JSON_BUILD_PAIR_UNSIGNED("offset", hibernation_device->offset),
+                        SD_JSON_BUILD_PAIR_CONDITION(auto_swap >= 0, "autoSwap", SD_JSON_BUILD_BOOLEAN(auto_swap)),
                         SD_JSON_BUILD_PAIR_CONDITION(!isempty(uts.release), "kernelVersion", SD_JSON_BUILD_STRING(uts.release)),
                         SD_JSON_BUILD_PAIR_CONDITION(!!id, "osReleaseId", SD_JSON_BUILD_STRING(id)),
                         SD_JSON_BUILD_PAIR_CONDITION(!!image_id, "osReleaseImageId", SD_JSON_BUILD_STRING(image_id)),