diff --git a/src/basic/blockdev-util.c b/src/basic/blockdev-util.c index 5f8212685b..21ff3ba1b1 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 1e7588f71c..58a7050f53 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);