From: Daan De Meyer Date: Fri, 29 Jul 2022 10:19:09 +0000 (+0200) Subject: blockdev-util: Add block_device_remove_all_partitions() X-Git-Tag: v252-rc1~521^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=35d40302af8ac1c8dfb7c970e621d2636a906851;p=thirdparty%2Fsystemd.git blockdev-util: Add block_device_remove_all_partitions() This function takes a block device, uses sd-device to iterate all the partitions, and removes them one by one. --- diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index b0ab5b440e3..0d921cc045c 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -5,9 +5,12 @@ #include #include +#include "sd-device.h" + #include "alloc-util.h" #include "blockdev-util.h" #include "btrfs-util.h" +#include "device-util.h" #include "devnum-util.h" #include "dirent-util.h" #include "errno-util.h" @@ -476,3 +479,66 @@ int block_device_remove_partition(int fd, const char *name, int nr) { return RET_NERRNO(ioctl(fd, BLKPG, &ba)); } + +int block_device_remove_all_partitions(int fd) { + struct stat stat; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + sd_device *part; + int r, k = 0; + + if (fstat(fd, &stat) < 0) + return -errno; + + r = sd_device_new_from_devnum(&dev, 'b', stat.st_rdev); + if (r < 0) + return r; + + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_parent(e, dev); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_subsystem(e, "block", true); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "partition"); + if (r < 0) + return r; + + FOREACH_DEVICE(e, part) { + const char *v, *devname; + int nr; + + r = sd_device_get_devname(part, &devname); + if (r < 0) + return r; + + r = sd_device_get_property_value(part, "PARTN", &v); + if (r < 0) + return r; + + r = safe_atoi(v, &nr); + if (r < 0) + return r; + + r = block_device_remove_partition(fd, devname, nr); + if (r == -ENODEV) { + log_debug("Kernel removed partition %s before us, ignoring", devname); + continue; + } + if (r < 0) { + log_debug_errno(r, "Failed to remove partition %s: %m", devname); + k = k ?: r; + continue; + } + + log_debug("Removed partition %s", devname); + } + + return k; +} diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index f7055625a36..8c9401b4a78 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -33,3 +33,4 @@ int path_get_whole_disk(const char *path, bool backing, dev_t *ret); int block_device_add_partition(int fd, const char *name, int nr, uint64_t start, uint64_t size); int block_device_remove_partition(int fd, const char *name, int nr); +int block_device_remove_all_partitions(int fd);