Blob Blame History Raw
From cd7bcbfad5c1319f8c7a9f74c2649ace096f6e2a Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Wed, 13 Sep 2017 11:47:15 +0200
Subject: [PATCH] util: make get_block_device() available

(cherry picked from commit c43b2b9c71e6e5f9af90ca178674d248acb0b9fc)
---
 src/basic/util.c                            | 131 ++++++++++++++++++++++++++++
 src/basic/util.h                            |   3 +
 src/gpt-auto-generator/gpt-auto-generator.c | 130 ---------------------------
 3 files changed, 134 insertions(+), 130 deletions(-)

diff --git a/src/basic/util.c b/src/basic/util.c
index b52a5db31b..6cbb58bdea 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -34,6 +34,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "btrfs-util.h"
 #include "build.h"
 #include "cgroup-util.h"
 #include "def.h"
@@ -719,3 +720,133 @@ int version(void) {
              SYSTEMD_FEATURES);
         return 0;
 }
+
+int get_block_device(const char *path, dev_t *dev) {
+        struct stat st;
+        struct statfs sfs;
+
+        assert(path);
+        assert(dev);
+
+        /* Get's the block device directly backing a file system. If
+         * the block device is encrypted, returns the device mapper
+         * block device. */
+
+        if (lstat(path, &st))
+                return -errno;
+
+        if (major(st.st_dev) != 0) {
+                *dev = st.st_dev;
+                return 1;
+        }
+
+        if (statfs(path, &sfs) < 0)
+                return -errno;
+
+        if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
+                return btrfs_get_block_device(path, dev);
+
+        return 0;
+}
+
+int get_block_device_harder(const char *path, dev_t *dev) {
+        _cleanup_closedir_ DIR *d = NULL;
+        _cleanup_free_ char *p = NULL, *t = NULL;
+        struct dirent *de, *found = NULL;
+        const char *q;
+        unsigned maj, min;
+        dev_t dt;
+        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;
+
+        if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
+                return -ENOMEM;
+
+        d = opendir(p);
+        if (!d) {
+                if (errno == ENOENT)
+                        goto fallback;
+
+                return -errno;
+        }
+
+        FOREACH_DIRENT_ALL(de, d, return -errno) {
+
+                if (dot_or_dot_dot(de->d_name))
+                        continue;
+
+                if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
+                        continue;
+
+                if (found) {
+                        _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL;
+
+                        /* We found a device backed by multiple other devices. We don't really support automatic
+                         * discovery on such setups, with the exception of dm-verity partitions. In this case there are
+                         * two backing devices: the data partition and the hash partition. We are fine with such
+                         * setups, however, only if both partitions are on the same physical device. Hence, let's
+                         * verify this. */
+
+                        u = strjoin(p, "/", de->d_name, "/../dev");
+                        if (!u)
+                                return -ENOMEM;
+
+                        v = strjoin(p, "/", found->d_name, "/../dev");
+                        if (!v)
+                                return -ENOMEM;
+
+                        r = read_one_line_file(u, &a);
+                        if (r < 0) {
+                                log_debug_errno(r, "Failed to read %s: %m", u);
+                                goto fallback;
+                        }
+
+                        r = read_one_line_file(v, &b);
+                        if (r < 0) {
+                                log_debug_errno(r, "Failed to read %s: %m", v);
+                                goto fallback;
+                        }
+
+                        /* 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;
+                }
+
+                found = de;
+        }
+
+        if (!found)
+                goto fallback;
+
+        q = strjoina(p, "/", found->d_name, "/dev");
+
+        r = read_one_line_file(q, &t);
+        if (r == -ENOENT)
+                goto fallback;
+        if (r < 0)
+                return r;
+
+        if (sscanf(t, "%u:%u", &maj, &min) != 2)
+                return -EINVAL;
+
+        if (maj == 0)
+                goto fallback;
+
+        *dev = makedev(maj, min);
+        return 1;
+
+fallback:
+        *dev = dt;
+        return 1;
+}
diff --git a/src/basic/util.h b/src/basic/util.h
index c7da6c39bf..b31dfd1c92 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -192,3 +192,6 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
 int update_reboot_parameter_and_warn(const char *param);
 
 int version(void);
+
+int get_block_device(const char *path, dev_t *dev);
+int get_block_device_harder(const char *path, dev_t *dev);
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index a072242430..dc307ff585 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -609,136 +609,6 @@ static int enumerate_partitions(dev_t devnum) {
         return r;
 }
 
-static int get_block_device(const char *path, dev_t *dev) {
-        struct stat st;
-        struct statfs sfs;
-
-        assert(path);
-        assert(dev);
-
-        /* Get's the block device directly backing a file system. If
-         * the block device is encrypted, returns the device mapper
-         * block device. */
-
-        if (lstat(path, &st))
-                return -errno;
-
-        if (major(st.st_dev) != 0) {
-                *dev = st.st_dev;
-                return 1;
-        }
-
-        if (statfs(path, &sfs) < 0)
-                return -errno;
-
-        if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
-                return btrfs_get_block_device(path, dev);
-
-        return 0;
-}
-
-static int get_block_device_harder(const char *path, dev_t *dev) {
-        _cleanup_closedir_ DIR *d = NULL;
-        _cleanup_free_ char *p = NULL, *t = NULL;
-        struct dirent *de, *found = NULL;
-        const char *q;
-        unsigned maj, min;
-        dev_t dt;
-        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;
-
-        if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
-                return -ENOMEM;
-
-        d = opendir(p);
-        if (!d) {
-                if (errno == ENOENT)
-                        goto fallback;
-
-                return -errno;
-        }
-
-        FOREACH_DIRENT_ALL(de, d, return -errno) {
-
-                if (dot_or_dot_dot(de->d_name))
-                        continue;
-
-                if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))
-                        continue;
-
-                if (found) {
-                        _cleanup_free_ char *u = NULL, *v = NULL, *a = NULL, *b = NULL;
-
-                        /* We found a device backed by multiple other devices. We don't really support automatic
-                         * discovery on such setups, with the exception of dm-verity partitions. In this case there are
-                         * two backing devices: the data partition and the hash partition. We are fine with such
-                         * setups, however, only if both partitions are on the same physical device. Hence, let's
-                         * verify this. */
-
-                        u = strjoin(p, "/", de->d_name, "/../dev");
-                        if (!u)
-                                return -ENOMEM;
-
-                        v = strjoin(p, "/", found->d_name, "/../dev");
-                        if (!v)
-                                return -ENOMEM;
-
-                        r = read_one_line_file(u, &a);
-                        if (r < 0) {
-                                log_debug_errno(r, "Failed to read %s: %m", u);
-                                goto fallback;
-                        }
-
-                        r = read_one_line_file(v, &b);
-                        if (r < 0) {
-                                log_debug_errno(r, "Failed to read %s: %m", v);
-                                goto fallback;
-                        }
-
-                        /* 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;
-                }
-
-                found = de;
-        }
-
-        if (!found)
-                goto fallback;
-
-        q = strjoina(p, "/", found->d_name, "/dev");
-
-        r = read_one_line_file(q, &t);
-        if (r == -ENOENT)
-                goto fallback;
-        if (r < 0)
-                return r;
-
-        if (sscanf(t, "%u:%u", &maj, &min) != 2)
-                return -EINVAL;
-
-        if (maj == 0)
-                goto fallback;
-
-        *dev = makedev(maj, min);
-        return 1;
-
-fallback:
-        *dev = dt;
-        return 1;
-}
-
 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
         int r;