diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-07-29 12:19:09 +0200 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-08-03 20:55:32 +0200 |
commit | 35d40302af8ac1c8dfb7c970e621d2636a906851 (patch) | |
tree | 78ebcd09cdf845e634828991fc68b7858dd0ee0b /src/shared | |
parent | loop-util: Add loop_device_unrelinquish() (diff) | |
download | systemd-35d40302af8ac1c8dfb7c970e621d2636a906851.tar.xz systemd-35d40302af8ac1c8dfb7c970e621d2636a906851.zip |
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.
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/blockdev-util.c | 66 | ||||
-rw-r--r-- | src/shared/blockdev-util.h | 1 |
2 files changed, 67 insertions, 0 deletions
diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index b0ab5b440e..0d921cc045 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -5,9 +5,12 @@ #include <sys/ioctl.h> #include <unistd.h> +#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 f7055625a3..8c9401b4a7 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); |