[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] Patch for opening remote VG for replicator target



Here is a small patch preview to resolve the problem of opening remote VG for
replicator target. It has still one 'minor' problem - thus I'll send full
patch set once I resolve that as well.

For now -

If remote VG is not active - than activation of local + remote VG successeds.

If remote VG is active - code currently fails and I'm trying to resolve
related problems.

No extra flags seems to be required at this moment. If there is need for
remote VG during _process_one_vg() call than there is loop which tries to
resolve those dependencies. Hopefully this solution does not influence any
other tool or command right now.

Zdenek
---
 lib/activate/dev_manager.c       |   31 +++++++++++++++
 lib/commands/toolcontext.h       |    1 +
 lib/metadata/metadata-exported.h |    3 +
 tools/toollib.c                  |   77 ++++++++++++++++++++++++++++++++++++-
 4 files changed, 109 insertions(+), 3 deletions(-)

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 2a8bfcd..3e0c8ca 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -958,6 +958,7 @@ static int _add_replicator_dev_target_to_dtree(struct dev_manager *dm,
 {
 	struct replicator_device *rdev;
 	struct replicator_site *rsite;
+	int vg_missing = 0;
 
 	/* only active replicator */
 	if (lv_is_active_replicator_dev(seg->lv)) {
@@ -967,12 +968,42 @@ static int _add_replicator_dev_target_to_dtree(struct dev_manager *dm,
 			return_0;
 
 		dm_list_iterate_items(rsite, &seg->replicator->rsites) {
+			if (rsite->vg == NULL) {
+				if (!rsite->vg_name)
+					continue;
+
+				if (dm->cmd->vgs_hash &&
+				    (rsite->vg = dm_hash_lookup(dm->cmd->vgs_hash, rsite->vg_name)))
+					continue;
+
+				if (!dm->cmd->vgs_hash)
+					if (!(dm->cmd->vgs_hash = dm_hash_create(16)))
+						return_0;
+				vg_missing++;
+
+				if (!(dm_hash_insert(dm->cmd->vgs_hash, rsite->vg_name, NULL)))
+					return_0;
+
+				log_verbose("VG %s added as missing.", rsite->vg_name);
+			}
+		}
+
+		if (vg_missing) {
+			log_verbose("Some VGs are missing, retry with them.");
+			return 0;
+		}
+
+		dm_list_iterate_items(rsite, &seg->replicator->rsites) {
 			dm_list_iterate_items(rdev, &rsite->rdevices) {
 				if (rdev->slog && !_add_new_lv_to_dtree(dm, dtree, rdev->slog, NULL))
 					return_0;
 				if ((rsite->state == REPLICATOR_STATE_ACTIVE) &&
 				    (!rdev->lv || !_add_new_lv_to_dtree(dm, dtree, rdev->lv, NULL)))
 					return_0;
+				if (rdev->rsite->vg &&
+				    (!rdev->name ||
+				      !_add_new_lv_to_dtree(dm, dtree, find_lv(rdev->rsite->vg, rdev->name), NULL)))
+					return_0;
 			}
 		}
 		dm_list_iterate_items(rsite, &seg->replicator->rsites) {
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index aa3de14..37210cf 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -60,6 +60,7 @@ struct cmd_context {
 
 	struct dm_list formats;	/* Available formats */
 	struct dm_list segtypes;	/* Available segment types */
+	struct dm_hash_table *vgs_hash;	/* Required read-only VGs */
 	const char *hostname;
 	const char *kernel_vsn;
 
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d2e3592..a4bc8c1 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -263,6 +263,9 @@ struct volume_group {
 	 * 0 for success else appropriate FAILURE_* bits set.
 	 */
 	uint32_t read_status;
+
+        /* linked vg */
+	struct dm_list vgs;
 };
 
 /* There will be one area for each stripe */
diff --git a/tools/toollib.c b/tools/toollib.c
index 39a6d69..0d0b78e 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -428,6 +428,11 @@ static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
 {
 	struct volume_group *vg;
 	int ret = 0;
+	struct dm_hash_node *n;
+	struct dm_list vg_list;
+	struct volume_group *rvg, *trvg;
+	const char *key;
+	int vg_missing;
 
 	log_verbose("Finding volume group \"%s\"", vg_name);
 
@@ -447,9 +452,65 @@ static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
 			goto out;
 	}
 
-	if ((ret = process_single(cmd, vg_name, vg,
-				  handle)) > ret_max)
-		ret_max = ret;
+	dm_list_init(&vg_list);
+	dm_list_add_h(&vg_list, &vg->vgs);
+	for (;;) {
+		if ((ret = process_single(cmd, vg_name, vg,
+					  handle)) > ret_max)
+			ret_max = ret;
+
+		if (!cmd->vgs_hash)
+			break;
+
+		/* release any currently hold VG in reverse order (add_h) */
+		dm_list_iterate_items_gen_safe(rvg, trvg, &vg_list, vgs)
+			unlock_and_release_vg(cmd, rvg, rvg->name);
+
+		vg_missing = 0;
+		dm_hash_iterate(n, cmd->vgs_hash)
+			if (!dm_hash_get_data(cmd->vgs_hash, n))
+				vg_missing++;
+
+		if (!vg_missing)
+			return ret_max;
+
+		vg = NULL;
+		dm_list_init(&vg_list);
+		dm_hash_iterate(n, cmd->vgs_hash) {
+			key = dm_hash_get_key(cmd->vgs_hash, n);
+
+			/* preserve alphabetic order */
+			if (!vg && strcmp(key, vg_name) > 0) {
+				vg = vg_read(cmd, vg_name, vgid, flags);
+				if (vg_read_error(vg))
+					goto rout;
+				dm_list_add_h(&vg_list, &vg->vgs);
+			}
+
+			rvg = vg_read(cmd, key, NULL, flags);
+			if (vg_read_error(rvg)) {
+				vg = rvg;
+				goto rout;
+			}
+			dm_list_add_h(&vg_list, &rvg->vgs);
+		}
+
+		if (!vg) {
+			vg = vg_read(cmd, vg_name, vgid, flags);
+			if (vg_read_error(vg)) {
+				goto rout;
+			}
+			dm_list_add_h(&vg_list, &vg->vgs);
+		}
+
+		/* updated hashed VG pointers */
+		dm_list_iterate_items_gen(rvg, &vg_list, vgs) {
+			if (rvg != vg) {
+				dm_hash_remove(cmd->vgs_hash, rvg->name);
+				dm_hash_insert(cmd->vgs_hash, rvg->name, rvg);
+			}
+		}
+	}
 
 out:
 	if ((vg_read_error(vg) == FAILED_ALLOCATION)||
@@ -458,6 +519,16 @@ out:
 	else
 		unlock_and_release_vg(cmd, vg, vg_name);
 	return ret_max;
+
+rout:
+	if ((vg_read_error(vg) == FAILED_ALLOCATION) ||
+	    (vg_read_error(vg) == FAILED_LOCKING))
+		vg_release(vg);
+
+	dm_list_iterate_items_gen_safe(rvg, trvg, &vg_list, vgs)
+		unlock_and_release_vg(cmd, rvg, rvg->name);
+
+	return ECMD_FAILED;
 }
 
 int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
-- 
1.6.5.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]