[lvm-devel] [PATCH] Add mirror log to dependency tree using its UUID.
Petr Rockai
prockai at redhat.com
Fri Feb 12 08:42:56 UTC 2010
Hi,
Milan Broz <mbroz at redhat.com> writes:
> Now depencecy tree calculation tries to add log device using
> "_mlog" layer. It is wrong because log device do not use layering
> (it has its own UUID without layer suffix).
> It currently works because query is done only by name.
>
> Because I plan to change all kernel dm info queries to use UUID only,
> it must be rewritten to use proper UUID.
> In ideal world we can use log_lv directly. Unfortunately the lvconvert
> code is currently broken, so code must search for log_lv according to name
> (it doesn't provide log_lv when it should).
I have double-checked and this is not true. See below.
> (mornfall: please can we fix lvconvert to use proper LV struct
> with log lv prepared? See _lv_update_log_type() confusion where
> new log_lv get lost...)
If I was a little more careful to check the patch, this could have been
easy... You have moved the _mlog from _add_lv_to_dtree to
_create_partial_dtree -- but this is not correct! The following patch
works:
(The problem with the proposed patch is that when a nested mirror is
created -- which happens upon lvconvert -m+1, for example, the partial
tree will only contain the toplevel (temporary) mirror and the two
images -- one regular and one mirrored... the mirrored one will however
not get any of its dependencies in the tree, hence *partial*... this
breaks lvconvert since the suspend/resume cycle leaves the _mlog device,
which is not included in the partial trees, in the wrong state.)
diff -rN -u -p old-upstream/lib/activate/dev_manager.c new-upstream/lib/activate/dev_manager.c
--- old-upstream/lib/activate/dev_manager.c 2010-02-12 09:35:07.000000000 +0100
+++ new-upstream/lib/activate/dev_manager.c 2010-02-12 09:35:12.000000000 +0100
@@ -823,7 +823,8 @@ static int _add_lv_to_dtree(struct dev_m
if (!_add_dev_to_dtree(dm, dtree, lv, "cow"))
return_0;
- if (!_add_dev_to_dtree(dm, dtree, lv, "_mlog"))
+ if ((lv->status & MIRRORED) && first_seg(lv)->log_lv &&
+ !_add_dev_to_dtree(dm, dtree, first_seg(lv)->log_lv, NULL))
return_0;
return 1;
(the original patch):
> --- a/lib/activate/dev_manager.c
> +++ b/lib/activate/dev_manager.c
> @@ -823,8 +823,32 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struc
> if (!_add_dev_to_dtree(dm, dtree, lv, "cow"))
> return_0;
>
> - if (!_add_dev_to_dtree(dm, dtree, lv, "_mlog"))
> - return_0;
> + return 1;
> +}
> +
> +static int _add_mirrored_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
> + struct logical_volume *lv)
> +{
> + struct lv_segment *seg = first_seg(lv);
> + struct lv_list *lvl;
> + char log_name[NAME_LEN];
> +
> + if (seg->log_lv) {
> + if (!_add_dev_to_dtree(dm, dtree, seg->log_lv, NULL))
> + return_0;
> + } else {
> + /*
> + * FIXME: This should not be needed at all!
> + * Mirrored LV should have log_lv always updated, unfortunately
> + * some convert operations use old LV struct here.
> + * For now, try to find log LV using its reserved name.
> + */
> + if (dm_snprintf(log_name, NAME_LEN, "%s_mlog", lv->name) < 0)
> + return_0;
> + if ((lvl = find_lv_in_vg(lv->vg, log_name)) &&
> + !_add_dev_to_dtree(dm, dtree, lvl->lv, NULL))
> + return_0;
> + }
>
> return 1;
> }
> @@ -849,6 +873,9 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logi
> if (!_add_lv_to_dtree(dm, dtree, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow))
> goto_bad;
>
> + if ((lv->status & MIRRORED) && !_add_mirrored_lv_to_dtree(dm, dtree, lv))
> + goto_bad;
> +
> /* Add any LVs used by segments in this LV */
> dm_list_iterate_items(seg, &lv->segments)
> for (s = 0; s < seg->area_count; s++)
Yours,
Petr.
PS: Yes, it took me a few hours to track this down : - ( ... Next time I
should read more carefully.
More information about the lvm-devel
mailing list