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.
This commit is contained in:
Lennart Poettering 2020-08-06 10:31:19 +02:00
parent 96a4ce9f1d
commit e8467cd31c
2 changed files with 39 additions and 0 deletions

View 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);
}

View 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);