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

[lvm-devel] [PATCH 9/11] _init_mirror_log() to cope with activation status



_init_mirror_log() is a function to initialize mirror log contents
with necessary activation and cleanups.
The function was originaly made for log_lv, which is just created
and not active.

For the log (re-)initialization, it's nice if the function takes
care of the current activation status and the intent of the caller
for the failure case.

-- 
Jun'ichi Nomura, NEC Corporation of America
_init_mirror_log() is a function to initialize mirror log contents
with necessary activation and cleanups.
The function was originaly made for log_lv, which is just created
and not active.

For the log (re-)initialization, it's nice if the function takes
care of the current activation status and the intent of the caller
for the failure case.

Index: LVM2.work/lib/metadata/mirror.c
===================================================================
--- LVM2.work.orig/lib/metadata/mirror.c
+++ LVM2.work/lib/metadata/mirror.c
@@ -183,9 +183,12 @@ static int _write_log_header(struct cmd_
  */
 static int _init_mirror_log(struct cmd_context *cmd,
 			    struct logical_volume *log_lv, int in_sync,
-			    struct list *tags)
+			    struct list *tags, int remove_on_failure)
 {
 	struct str_list *sl;
+	struct lvinfo info;
+	uint32_t orig_status = log_lv->status;
+	int was_active = 0;
 
 	if (!activation() && in_sync) {
 		log_error("Aborting. Unable to create in-sync mirror log "
@@ -193,21 +196,31 @@ static int _init_mirror_log(struct cmd_c
 		return 0;
 	}
 
+	/* If the LV is active, deactivate it first. */
+	if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
+		if (!deactivate_lv(cmd, log_lv))
+			return_0;
+		was_active = 1;
+	}
+
+	/* Temporary make it visible for set_lv() */
+	log_lv->status |= VISIBLE_LV;
+
 	/* Temporary tag mirror log for activation */
 	list_iterate_items(sl, tags)
 		if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
 			log_error("Aborting. Unable to tag mirror log.");
-			return 0;
+			goto activate_lv;
 		}
 
 	/* store mirror log on disk(s) */
 	if (!vg_write(log_lv->vg))
-		return_0;
+		goto activate_lv;
 
 	backup(log_lv->vg);
 
 	if (!vg_commit(log_lv->vg))
-		return_0;
+		goto activate_lv;
 
 	if (!activate_lv(cmd, log_lv)) {
 		log_error("Aborting. Failed to activate mirror log.");
@@ -239,6 +252,9 @@ static int _init_mirror_log(struct cmd_c
 
 	log_lv->status &= ~VISIBLE_LV;
 
+	if (was_active && !activate_lv(cmd, log_lv))
+		return_0;
+
 	return 1;
 
 deactivate_and_revert_new_lv:
@@ -249,10 +265,27 @@ deactivate_and_revert_new_lv:
 	}
 
 revert_new_lv:
-	if (!lv_remove(log_lv) || !vg_write(log_lv->vg) ||
-	    (backup(log_lv->vg), !vg_commit(log_lv->vg)))
+	log_lv->status = orig_status;
+
+	list_iterate_items(sl, tags)
+		if (!str_list_del(&log_lv->tags, sl->str))
+			log_error("Failed to remove tag %s from mirror log.",
+				  sl->str);
+
+	if (remove_on_failure && !lv_remove(log_lv)) {
 		log_error("Manual intervention may be required to remove "
 			  "abandoned log LV before retrying.");
+		return 0;
+	}
+
+	if (!vg_write(log_lv->vg) ||
+	    (backup(log_lv->vg), !vg_commit(log_lv->vg)))
+		log_error("Manual intervention may be required to "
+			  "remove/restore abandoned log LV before retrying.");
+activate_lv:
+	if (was_active && !remove_on_failure && !activate_lv(cmd, log_lv))
+		return_0;
+
 	return 0;
 }
 
@@ -1110,7 +1143,7 @@ static struct logical_volume *_set_up_mi
 		return NULL;
 	}
 
-	if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags)) {
+	if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
 		log_error("Failed to create mirror log.");
 		return NULL;
 	}

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