[lvm-devel] master - activation: enhance holders detection

Zdenek Kabelac zkabelac at sourceware.org
Sat Nov 25 23:38:24 UTC 2017


Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8c6fd0933fa4ee9b79ae5edbb90afe6a3d893b18
Commit:        8c6fd0933fa4ee9b79ae5edbb90afe6a3d893b18
Parent:        ce83162d7c7eae008935989a26dbf23dfb08d0f9
Author:        Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate:    Fri Nov 24 20:59:38 2017 +0100
Committer:     Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Sun Nov 26 00:31:26 2017 +0100

activation: enhance holders detection

Use code which detectes handlers in a way, which is more
backward-compatible friendly.

Replace read of 'sysfs' uuid entry with dm ioctl call.

Use /sys/block/dm-X/holders path instead of
new path  /sys/dev/block/major:minor/holders.

TODO:
There are few more occurencies of this logic around the code
so some abstract interface should be considered.
---
 lib/activate/dev_manager.c |  128 ++++++++++++++++++++++++--------------------
 1 files changed, 69 insertions(+), 59 deletions(-)

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 76fc546..429f4f6 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1720,81 +1720,52 @@ static uint16_t _get_udev_flags(struct dev_manager *dm, const struct logical_vol
 
 static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
 			    const struct logical_volume *lv, int origin_only);
-/*
- * Add exiting devices which holds given LV device open.
- * This is used in case when metadata already do not contain information
- * i.e. PVMOVE is being finished and final table is going to be resumed.
- */
-static int _add_holders_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
-				 const struct logical_volume *lv, struct dm_info *info)
+
+static int _check_holder(struct dev_manager *dm, struct dm_tree *dtree,
+			 const struct logical_volume *lv, uint32_t major,
+			 const char *d_name)
 {
 	const char *default_uuid_prefix = dm_uuid_prefix();
 	const size_t default_uuid_prefix_len = strlen(default_uuid_prefix);
-	const char *sysfs_dir = dm_sysfs_dir();
-	char sysfs_path[PATH_MAX];
-	char uuid_path[PATH_MAX];
-	char uuid_buf[DM_UUID_LEN + 1];
-	char *uuid;
-	struct dirent *dirent;
-	DIR *d;
-	FILE *fp;
+	const char *name;
+	const char *uuid;
+	struct dm_info info;
+	struct dm_task *dmt;
 	struct logical_volume *lv_det;
-	int r = 0;
+	union lvid id;
+	int dev, r = 0;
 
-	/* Sysfs path of holders */
-	if (dm_snprintf(sysfs_path, sizeof(sysfs_path), "%sdev/block/" FMTu32
-			":" FMTu32 "/holders", sysfs_dir, info->major, info->minor) < 0) {
-		log_error("sysfs_path dm_snprintf failed.");
-		return 0;
-	}
-
-	if (!(d = opendir(sysfs_path))) {
-		if (errno != ENOENT)
-			log_sys_error("opendir", sysfs_path);
+	errno = 0;
+	dev = strtoll(d_name + 3, NULL, 10);
+	if (errno) {
+		log_error("Failed to parse dm device minor number from %s.", d_name);
 		return 0;
 	}
 
-	while ((dirent = readdir(d))) {
-		if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
-			continue;
-
-		/* Determine path where sysfs holds UUID for holding dm device */
-		if (dm_snprintf(uuid_path, sizeof(uuid_path), "%s/%s/dm/uuid",
-				sysfs_path, dirent->d_name) < 0) {
-			log_error("uuid_path dm_snprintf failed.");
-			goto out;
-		}
-
-		if (!(fp = fopen(uuid_path, "r"))) {
-			log_sys_error("fopen", uuid_path);
-			goto out;
-		}
-
-		if (!fgets(uuid_buf, sizeof(uuid_buf), fp)) {
-			log_sys_error("fgets", uuid_path);
-			fclose(fp);
-			goto out;
-		}
+	if (!(dmt = _setup_task_run(DM_DEVICE_INFO, &info, NULL, NULL, NULL,
+				    major, dev, 0, 0, 0)))
+		return_0;
 
-		if (fclose(fp))
-			log_sys_debug("fclose", uuid_path);
+	if (info.exists) {
+		uuid = dm_task_get_uuid(dmt);
+		name = dm_task_get_name(dmt);
 
-		uuid = uuid_buf;
-		log_debug_activation("Checking holder of LV %s with uuid %s.",
-				     display_lvname(lv), uuid);
+		log_debug_activation("Checking holder of %s  %s (" FMTu32 ":" FMTu32 ") %s.",
+				     display_lvname(lv), uuid, info.major, info.minor,
+				     name);
 
-		/* Skip common uuid LVM prefix */
+		/* Skip common uuid prefix */
 		if (!strncmp(default_uuid_prefix, uuid, default_uuid_prefix_len))
 			uuid += default_uuid_prefix_len;
 
-		/* Check holder comes from processed VG and is not yet in dmtree */
 		if (!strncmp(uuid, (char*)&lv->vg->id, sizeof(lv->vg->id)) &&
 		    !dm_tree_find_node_by_uuid(dtree, uuid)) {
-			uuid[2 * sizeof(struct id)] = 0; /* Cut any suffix */
+			dm_strncpy((char*)&id, uuid, 2 * sizeof(struct id) + 1);
+
 			/* If UUID is not yet in dtree, look for matching LV */
-			if (!(lv_det = find_lv_in_vg_by_lvid(lv->vg, (union lvid*)uuid))) {
-				log_error("Cannot find holding uuid %s in VG %s.",
-					  uuid, lv->vg->name);
+			if (!(lv_det = find_lv_in_vg_by_lvid(lv->vg, &id))) {
+				log_error("Cannot find holder with device name %s in VG %s.",
+					  name, lv->vg->name);
 				goto out;
 			}
 
@@ -1808,10 +1779,49 @@ static int _add_holders_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
 		}
 	}
 
+        r = 1;
+out:
+	dm_task_destroy(dmt);
+
+	return r;
+}
+
+/*
+ * Add exiting devices which holds given LV device open.
+ * This is used in case when metadata already do not contain information
+ * i.e. PVMOVE is being finished and final table is going to be resumed.
+ */
+static int _add_holders_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
+				 const struct logical_volume *lv, struct dm_info *info)
+{
+	const char *sysfs_dir = dm_sysfs_dir();
+	char sysfs_path[PATH_MAX];
+	struct dirent *dirent;
+	DIR *d;
+	int r = 0;
+
+	/* Sysfs path of holders */
+	if (dm_snprintf(sysfs_path, sizeof(sysfs_path), "%sblock/dm-" FMTu32
+			"/holders", sysfs_dir, info->minor) < 0) {
+		log_error("sysfs_path dm_snprintf failed.");
+		return 0;
+	}
+
+	if (!(d = opendir(sysfs_path))) {
+		log_sys_error("opendir", sysfs_path);
+		return 0;
+	}
+
+	while ((dirent = readdir(d)))
+		/* Expects minor is added to 'dm-' prefix */
+		if (!strncmp(dirent->d_name, "dm-", 3) &&
+		    !_check_holder(dm, dtree, lv, info->major, dirent->d_name))
+			goto_out;
+
 	r = 1;
 out:
 	if (closedir(d))
-		log_sys_error("closedir", "holders");
+		log_sys_debug("closedir", "holders");
 
 	return r;
 }




More information about the lvm-devel mailing list