diff mbox series

[v3,11/12] libmultipath: accept empty partitions as valid in do_foreach_partmaps

Message ID 20241126184224.855459-12-bmarzins@redhat.com (mailing list archive)
State New
Headers show
Series multipath-tools: Handle tableless DM devices | expand

Commit Message

Benjamin Marzinski Nov. 26, 2024, 6:42 p.m. UTC
If the partition is empty, is_valid_partmap() only checks that the uuid
matches the multipath device, since there is no table to check for
mapping over the multipath device.

The only partmap_func that needs changes to handle empty devices is
count_partitions(), which should only count a partition if it has a
table (since otherwise it will not have the multipath device open).

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
 libmultipath/devmapper.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index 3667c51b..c96e4b22 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -944,16 +944,23 @@  has_partmap(const char *name __attribute__((unused)),
  * This will be called from mpath_in_use, for each partition.
  * If the partition itself in use, returns 1 immediately, causing
  * do_foreach_partmaps() to stop iterating and return 1.
- * Otherwise, increases the partition count.
+ * Otherwise, increases the partition count if the partition has a
+ * table (live or inactive). Devices with no table don't count
+ * towards the multipath device open count.
  */
 static int count_partitions(const char *name, void *data)
 {
+	struct dm_info info;
 	int *ret_count = (int *)data;
-	int open_count = dm_get_opencount(name);
 
-	if (open_count)
+	if (dm_get_info(name, &info) != DMP_OK)
+		return 1;
+
+	if (info.open_count)
 		return 1;
-	(*ret_count)++;
+
+	if (info.live_table || info.inactive_table)
+		(*ret_count)++;
 	return 0;
 }
 
@@ -1335,8 +1342,8 @@  is_valid_partmap(const char *name, const char *map_dev_t,
 			  (mapid_t) { .str = name },
 			  (mapinfo_t) { .uuid = part_uuid, .target = &params});
 
-	/* There must be a single linear target */
-	if (r != DMP_OK)
+	/* There must be a single linear target or an empty map. */
+	if (r != DMP_OK && r != DMP_EMPTY)
 		return false;
 
 	/*
@@ -1346,7 +1353,10 @@  is_valid_partmap(const char *name, const char *map_dev_t,
 	if (!is_mpath_part_uuid(part_uuid, map_uuid))
 		return false;
 
-	/* and the table must map over the multipath map */
+	if (r == DMP_EMPTY)
+		return true;
+
+	/* and if the table isn't empty it must map over the multipath map */
 	return ((p = strstr(params, map_dev_t)) &&
 		!isdigit(*(p + strlen(map_dev_t))));
 }