]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
blockdev-util: Add block_device_remove_all_partitions()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 29 Jul 2022 10:19:09 +0000 (12:19 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 3 Aug 2022 18:55:32 +0000 (20:55 +0200)
This function takes a block device, uses sd-device to iterate all
the partitions, and removes them one by one.

src/shared/blockdev-util.c
src/shared/blockdev-util.h

index b0ab5b440e37de25efee57e596c39aeabf8f5abe..0d921cc045c178bf5ac1a8fa527ff91f08312175 100644 (file)
@@ -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;
+}
index f7055625a36c57ed182050249bbf2ca3d437c934..8c9401b4a784e8b270351ab38c5e18690a0a3e87 100644 (file)
@@ -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);