Allow mirror log conversion while inactive
PATCH 1/1 Allow mirror log conversion while inactive
brassow
Fix for bug 192865.
Allow mirror log conversion (disk -> core) of a non-clustered mirror while it is inactive.
It should be mentioned that core -> disk was already working.
I also had to turn off support for this for cluster mirrors, due to the fact that a mirror could be active on another machine, but processing would continue as though inactive if that was the state on the executing machine. (core -> disk conversions of cluster mirrors was being allowed... but should not have been.)
So, in summary:
Single Machine mirroring
OPERATION BEFORE PATCH AFTER PATCH
inactive c->d allowed allowed
inactive d->c disallowed allowed (y/n prompt)
active c->d allowed allowed
active d->c allowed allowed
Cluster mirroring
OPERATION BEFORE PATCH AFTER PATCH
inactive c->d allowed disallowed (better msg)
inactive d->c disallowed disallowed (better msg)
active c->d allowed allowed
active d->c allowed allowed
lib/metadata/mirror.c +33 -9
@@ -1140,6 +1140,8 @@ int remove_mirror_log(struct cmd_context struct list *removable_pvs) {float sync_percent; +struct lvinfo info; +struct volume_group *vg = lv->vg;/* Unimplemented features */ if (list_size (&lv->segments) !=1 ) {
@@ -1148,10 +1150,21 @@ int remove_mirror_log(struct cmd_context }/* Had disk log, switch to core. */ -if (!lv_mirror_percent (cmd, lv,0 , &sync_percent,NULL )) { -log_error ("Unable to determine mirror sync status." ); +if (lv_info (cmd, lv, &info,0 ,0 ) && info.exists) { +if (!lv_mirror_percent (cmd, lv,0 , &sync_percent,NULL )) { +log_error ("Unable to determine mirror sync status." ); +return 0 ; + } + }else if (vg_is_clustered (vg)) { +log_error ("Unable to convert the log of an inactive " +"cluster mirrors, %s" , lv->name); +return 0 ; + }else if (yes_no_prompt ("Converting %s to core log while inactive " +" requires a complete resync of the mirror.\n" +"Proceed? [y/n]: " )) + sync_percent =0 ; +else return 0 ; - }if (sync_percent >=100.0 )init_mirror_in_sync (1 );
@@ -1269,12 +1282,9 @@ int attach_mirror_log(struct lv_segmentreturn add_seg_to_segs_using_this_lv (log_lv, seg); } -int add_mirror_log (struct cmd_context *cmd, -struct logical_volume *lv, -uint32_t log_count, -uint32_t region_size, -struct list *allocatable_pvs, -alloc_policy_t alloc) +int add_mirror_log (struct cmd_context *cmd,struct logical_volume *lv, +uint32_t log_count,uint32_t region_size, +struct list *allocatable_pvs,alloc_policy_t alloc) {struct alloc_handle *ah;const struct segment_type *segtype;
@@ -1282,17 +1292,31 @@ int add_mirror_log(struct cmd_context *cfloat sync_percent;int in_sync;struct logical_volume *log_lv; +struct lvinfo info;/* Unimplemented features */ if (log_count >1 ) {log_error ("log_count > 1 is not supported" );return 0 ; } +if (list_size (&lv->segments) !=1 ) {log_error ("Multiple-segment mirror is not supported" );return 0 ; } +/* +* We are unable to convert the log of inactive cluster mirrors +* due to the inability to detect whether the mirror is active +* on remote nodes (even though it is inactive on this node) +*/ +if (vg_is_clustered (lv->vg) && + !(lv_info (cmd, lv, &info,0 ,0 ) && info.exists)) { +log_error ("Unable to convert the log of an inactive " +"cluster mirror, %s" , lv->name); +return 0 ; + } +if (!(parallel_areas =build_parallel_areas_from_lv (cmd, lv))) return_0;
tools/lvconvert.c +3 -0
@@ -508,6 +508,9 @@ static int lvconvert_mirrors(struct cmd_ } if (lp->mirrors == existing_mirrors) { + /* + * Convert Mirror log type + */ original_lv = _original_lv(lv); if (!first_seg(original_lv)->log_lv && !corelog) { if (!add_mirror_log(cmd, original_lv, 1,