]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
blockdev-util: Add recursive lookup flag
authorChris Down <chris@chrisdown.name>
Thu, 22 Jan 2026 10:13:44 +0000 (18:13 +0800)
committerChris Down <chris@chrisdown.name>
Fri, 23 Jan 2026 05:26:08 +0000 (13:26 +0800)
Originating device lookups currently use separate entry points and
callers must decide between the single-step helper and manual looping.

Add a recursive flag to block_device_get_originating() and
block_get_originating(), and update callers to pass an explicit value.

src/core/cgroup.c
src/cryptenroll/cryptenroll.c
src/repart/repart.c
src/shared/blockdev-util.c
src/shared/blockdev-util.h
src/sleep/sleep.c
src/storagetm/storagetm.c
src/sysupdate/sysupdate-resource.c

index 6a434eba84bdfc9f15635b29aac97c1e4b1f311e..35c0898e03c71ad9683045a6e54dd623226cbdbd 100644 (file)
@@ -973,8 +973,7 @@ static int lookup_block_device(const char *p, dev_t *ret) {
         }
 
         /* If this is a LUKS/DM device, recursively try to get the originating block device */
-        while (block_get_originating(*ret, ret) >= 0)
-                ;
+        (void) block_get_originating(*ret, ret, /* recursive= */ true);
 
         /* If this is a partition, try to get the originating block device */
         (void) block_get_whole_disk(*ret, ret);
index a4be09d3e0d4510265cb95b5cd8bd42496d56cec..86d57e964f835bcccca1abd12cade223baa5049c 100644 (file)
@@ -152,7 +152,7 @@ static int determine_default_node(void) {
                 return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Block device backing /var/ is not a LUKS2 device.");
 
         _cleanup_(sd_device_unrefp) sd_device *origin = NULL;
-        r = block_device_get_originating(dev, &origin);
+        r = block_device_get_originating(dev, &origin, /* recursive= */ false);
         if (r < 0)
                 return log_error_errno(r, "Failed to get originating device of LUKS2 device backing /var/: %m");
 
index 100e03aab556496d5025adcd1e5b06f8d7600501..65b7d1be317fe6286b4d45be66bdaa6336eb908c 100644 (file)
@@ -9934,7 +9934,7 @@ static int acquire_root_devno(
                 return -ENOTBLK;
 
         /* From dm-crypt to backing partition */
-        r = block_get_originating(devno, &devno);
+        r = block_get_originating(devno, &devno, /* recursive= */ false);
         if (r == -ENOENT)
                 log_debug_errno(r, "Device '%s' has no dm-crypt/dm-verity device, no need to look for underlying block device.", p);
         else if (r < 0)
index 3242ea23da519b61d4caca3d10b0eef9bffa8cff..b138455acc9e6dc9190d833d7963adb772e9f977 100644 (file)
@@ -101,7 +101,7 @@ int block_device_get_whole_disk(sd_device *dev, sd_device **ret) {
         return 0;
 }
 
-int block_device_get_originating(sd_device *dev, sd_device **ret) {
+static int block_device_get_originating_one(sd_device *dev, sd_device **ret) {
         _cleanup_(sd_device_unrefp) sd_device *first_found = NULL;
         const char *suffix;
         dev_t devnum = 0;  /* avoid false maybe-uninitialized warning */
@@ -148,6 +148,39 @@ int block_device_get_originating(sd_device *dev, sd_device **ret) {
         return 0;
 }
 
+int block_device_get_originating(sd_device *dev, sd_device **ret, bool recursive) {
+        _cleanup_(sd_device_unrefp) sd_device *current = NULL;
+        int r;
+
+        assert(dev);
+        assert(ret);
+
+        if (!recursive)
+                return block_device_get_originating_one(dev, ret);
+
+        current = sd_device_ref(dev);
+
+        for (;;) {
+                sd_device *origin;
+
+                r = block_device_get_originating_one(current, &origin);
+                if (r == -ENOENT)
+                        break;
+                if (r < 0)
+                        return r;
+
+                sd_device_unref(current);
+                current = origin;
+        }
+
+        if (current == dev)
+                return -ENOENT;
+
+        *ret = TAKE_PTR(current);
+
+        return 0;
+}
+
 int block_device_new_from_fd(int fd, BlockDeviceLookupFlags flags, sd_device **ret) {
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
         dev_t devnum;
@@ -172,7 +205,7 @@ int block_device_new_from_fd(int fd, BlockDeviceLookupFlags flags, sd_device **r
                 if (r < 0)
                         return r;
 
-                r = block_device_get_originating(dev_whole_disk, &dev_origin);
+                r = block_device_get_originating(dev_whole_disk, &dev_origin, /* recursive= */ false);
                 if (r >= 0)
                         device_unref_and_replace(dev, dev_origin);
                 else if (r != -ENOENT)
@@ -290,7 +323,7 @@ int get_block_device(const char *path, dev_t *ret) {
         return get_block_device_fd(fd, ret);
 }
 
-int block_get_originating(dev_t dt, dev_t *ret) {
+int block_get_originating(dev_t dt, dev_t *ret, bool recursive) {
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL, *origin = NULL;
         int r;
 
@@ -300,7 +333,7 @@ int block_get_originating(dev_t dt, dev_t *ret) {
         if (r < 0)
                 return r;
 
-        r = block_device_get_originating(dev, &origin);
+        r = block_device_get_originating(dev, &origin, recursive);
         if (r < 0)
                 return r;
 
@@ -320,7 +353,7 @@ int get_block_device_harder_fd(int fd, dev_t *ret) {
         if (r <= 0)
                 return r;
 
-        r = block_get_originating(*ret, ret);
+        r = block_get_originating(*ret, ret, /* recursive= */ false);
         if (r < 0)
                 log_debug_errno(r, "Failed to chase block device, ignoring: %m");
 
index 871596f618c277f1966b312b11bfae22125fa618..3a20a5307d2e5497763bc760fdd12a3217d5c179 100644 (file)
@@ -24,10 +24,9 @@ int block_device_new_from_path(const char *path, BlockDeviceLookupFlags flags, s
 
 int block_device_is_whole_disk(sd_device *dev);
 int block_device_get_whole_disk(sd_device *dev, sd_device **ret);
-int block_device_get_originating(sd_device *dev, sd_device **ret);
-
+int block_device_get_originating(sd_device *dev, sd_device **ret, bool recursive);
 int block_get_whole_disk(dev_t d, dev_t *ret);
-int block_get_originating(dev_t d, dev_t *ret);
+int block_get_originating(dev_t d, dev_t *ret, bool recursive);
 
 int get_block_device_fd(int fd, dev_t *ret);
 int get_block_device(const char *path, dev_t *ret);
index 4fa6f16fcddf5948b2ab64bd0d28319c9375c889..0d128053ba1afc5b65c7dac60c4604386b9dacb7 100644 (file)
@@ -61,7 +61,7 @@ static int determine_auto_swap(sd_device *device) {
 
         assert(device);
 
-        r = block_device_get_originating(device, &origin);
+        r = block_device_get_originating(device, &origin, /* recursive= */ false);
         if (r < 0 && r != -ENOENT)
                 return r;
         if (r >= 0)
index 54d516ef128b4d6c8f377be81b52f14fef11fc9f..89a6e0b55252425419891a9e017ee5e7aea25cdd 100644 (file)
@@ -848,7 +848,7 @@ static void device_track_back(sd_device *d, sd_device **ret) {
         (void) sd_device_get_devname(d, &devname);
 
         _cleanup_(sd_device_unrefp) sd_device *d_originating = NULL;
-        r = block_device_get_originating(d, &d_originating);
+        r = block_device_get_originating(d, &d_originating, /* recursive= */ false);
         if (r < 0 && r != -ENOENT)
                 log_device_debug_errno(d, r, "Failed to get originating device for '%s', ignoring: %m", strna(devname));
 
index c9e69812613a34cd24c847f21626db9ec006a412..b26884189959bf4f690efd54ef82154af571ad43 100644 (file)
@@ -678,7 +678,7 @@ static int get_sysext_overlay_block(const char *p, dev_t *ret) {
                 return 0;
         }
 
-        (void) block_get_originating(*ret, ret);
+        (void) block_get_originating(*ret, ret, /* recursive= */ false);
         return 1;
 }