]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/blockdev-util.c
blockdev: split out actual DM sysfs code of get_block_device_harder() into function...
[thirdparty/systemd.git] / src / basic / blockdev-util.c
index 6495a7165847121daaf10f4c06ff17543ca241f6..0b090bb2ed913418da60dd6b0da549700b237c0e 100644 (file)
@@ -85,35 +85,22 @@ int get_block_device(const char *path, dev_t *dev) {
         return 0;
 }
 
-int get_block_device_harder(const char *path, dev_t *dev) {
+int block_get_originating(dev_t dt, dev_t *ret) {
         _cleanup_closedir_ DIR *d = NULL;
         _cleanup_free_ char *t = NULL;
         char p[SYS_BLOCK_PATH_MAX("/slaves")];
         struct dirent *de, *found = NULL;
-        const char *q;
         unsigned maj, min;
-        dev_t dt;
+        const char *q;
         int r;
 
-        assert(path);
-        assert(dev);
-
-        /* Gets the backing block device for a file system, and
-         * handles LUKS encrypted file systems, looking for its
-         * immediate parent, if there is one. */
-
-        r = get_block_device(path, &dt);
-        if (r <= 0)
-                return r;
+        /* For the specified block device tries to chase it through the layers, in case LUKS-style DM stacking is used,
+         * trying to find the next underlying layer.  */
 
         xsprintf_sys_block_path(p, "/slaves", dt);
         d = opendir(p);
-        if (!d) {
-                if (errno == ENOENT)
-                        goto fallback;
-
+        if (!d)
                 return -errno;
-        }
 
         FOREACH_DIRENT_ALL(de, d, return -errno) {
 
@@ -141,34 +128,28 @@ int get_block_device_harder(const char *path, dev_t *dev) {
                                 return -ENOMEM;
 
                         r = read_one_line_file(u, &a);
-                        if (r < 0) {
-                                log_debug_errno(r, "Failed to read %s: %m", u);
-                                goto fallback;
-                        }
+                        if (r < 0)
+                                return log_debug_errno(r, "Failed to read %s: %m", u);
 
                         r = read_one_line_file(v, &b);
-                        if (r < 0) {
-                                log_debug_errno(r, "Failed to read %s: %m", v);
-                                goto fallback;
-                        }
+                        if (r < 0)
+                                return log_debug_errno(r, "Failed to read %s: %m", v);
 
                         /* Check if the parent device is the same. If not, then the two backing devices are on
                          * different physical devices, and we don't support that. */
                         if (!streq(a, b))
-                                goto fallback;
+                                return -ENOTUNIQ;
                 }
 
                 found = de;
         }
 
         if (!found)
-                goto fallback;
+                return -ENOENT;
 
         q = strjoina(p, "/", found->d_name, "/dev");
 
         r = read_one_line_file(q, &t);
-        if (r == -ENOENT)
-                goto fallback;
         if (r < 0)
                 return r;
 
@@ -176,12 +157,28 @@ int get_block_device_harder(const char *path, dev_t *dev) {
                 return -EINVAL;
 
         if (maj == 0)
-                goto fallback;
+                return -ENOENT;
 
-        *dev = makedev(maj, min);
+        *ret = makedev(maj, min);
         return 1;
+}
+
+int get_block_device_harder(const char *path, dev_t *ret) {
+        int r;
+
+        assert(path);
+        assert(ret);
+
+        /* Gets the backing block device for a file system, and handles LUKS encrypted file systems, looking for its
+         * immediate parent, if there is one. */
+
+        r = get_block_device(path, ret);
+        if (r <= 0)
+                return r;
+
+        r = block_get_originating(*ret, ret);
+        if (r < 0)
+                log_debug_errno(r, "Failed to chase block device '%s', ignoring: %m", path);
 
-fallback:
-        *dev = dt;
         return 1;
 }