From e8467cd31c9d5da28c31a6559fbe40ccb663fa7f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Aug 2020 10:31:19 +0200 Subject: [PATCH] blockdev-util: add correct API for detecting if block device has partition scanning enabled 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 | 37 +++++++++++++++++++++++++++++++++++++ src/basic/blockdev-util.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/basic/blockdev-util.c b/src/basic/blockdev-util.c index 5f8212685b7..21ff3ba1b13 100644 --- a/src/basic/blockdev-util.c +++ b/src/basic/blockdev-util.c @@ -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); +} diff --git a/src/basic/blockdev-util.h b/src/basic/blockdev-util.h index 1e7588f71ca..58a7050f53b 100644 --- a/src/basic/blockdev-util.h +++ b/src/basic/blockdev-util.h @@ -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); -- 2.39.2