blockdev-util: add correct API for detecting if block device has partition scanning...
authorLennart Poettering <lennart@poettering.net>
Thu, 6 Aug 2020 08:31:19 +0000 (10:31 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 11 Aug 2020 08:29:43 +0000 (10:29 +0200)
Instead of checking the loopback ioctls, let's check sysfs, so that we
catch all kinds of block devices, not just loopback block devices.

src/basic/blockdev-util.c
src/basic/blockdev-util.h

index 5f82126..21ff3ba 100644 (file)
@@ -214,3 +214,40 @@ int lock_whole_block_device(dev_t devt, int operation) {
 
         return TAKE_FD(lock_fd);
 }
+
+int blockdev_partscan_enabled(int fd) {
+        _cleanup_free_ char *p = NULL, *buf = NULL;
+        unsigned long long ull;
+        struct stat st;
+        int r;
+
+        /* Checks if partition scanning is correctly enabled on the block device */
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (!S_ISBLK(st.st_mode))
+                return -ENOTBLK;
+
+        if (asprintf(&p, "/sys/dev/block/%u:%u/capability", major(st.st_rdev), minor(st.st_rdev)) < 0)
+                return -ENOMEM;
+
+        r = read_one_line_file(p, &buf);
+        if (r == -ENOENT) /* If the capability file doesn't exist then we are most likely looking at a
+                           * partition block device, not the whole block device. And that means we have no
+                           * partition scanning on for it (we do for its parent, but not for the partition
+                           * itself). */
+                return false;
+        if (r < 0)
+                return r;
+
+        r = safe_atollu_full(buf, 16, &ull);
+        if (r < 0)
+                return r;
+
+#ifndef GENHD_FL_NO_PART_SCAN
+#define GENHD_FL_NO_PART_SCAN (0x0200)
+#endif
+
+        return !FLAGS_SET(ull, GENHD_FL_NO_PART_SCAN);
+}
index 1e7588f..58a7050 100644 (file)
@@ -20,3 +20,5 @@ int get_block_device(const char *path, dev_t *dev);
 int get_block_device_harder(const char *path, dev_t *dev);
 
 int lock_whole_block_device(dev_t devt, int operation);
+
+int blockdev_partscan_enabled(int fd);