Handle activation errors. With shared snapshot store it may happen that the store couldn't activate itself if the user specifies invalid parameters for a given exception store type. In this case, libdm would left orphan -real and -cow devices that would cause trouble in further activities. Use suspend_lv+resume_lv trick to get rid of these devices. On activation failure, delete the snapshot volume. Another problem is creating a shared snapshot of inactive volume. We activate the volume just for a little moment to make sure that the parameters are acceptable to the kernel. Signed-off-by: Mikulas Patocka --- lib/metadata/lv_manip.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) Index: LVM2.2.02.60/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.60.orig/lib/metadata/lv_manip.c 2010-02-08 20:01:38.000000000 +0100 +++ LVM2.2.02.60/lib/metadata/lv_manip.c 2010-02-08 20:13:31.000000000 +0100 @@ -3173,9 +3173,32 @@ int lv_create_single(struct volume_group if (!vg_write(vg)) return_0; + /* + * The kernel has authority over parameters line validity. + * To make sure that we won't commit invalid parameters + * to the metadata, try to activate the origin. + * We deactivate it later. + */ + if (!origin_active && lp->shared_store) + if (!activate_lv_excl(cmd, org)) + goto snapshot_failure; + if (!suspend_lv(cmd, org)) { - log_error("Failed to suspend origin %s", org->name); +snapshot_failure: + log_error("Failed to load snapshot driver for %s", lv->name); vg_revert(vg); + lv_remove_with_dependencies(cmd, lv, 1); + + /* + * This suspend+resume will clean up left + * -real and -cow devices. + */ + if (!origin_active) + deactivate_lv(cmd, org); + else { + suspend_lv(cmd, org); + resume_lv(cmd, org); + } return 0; } @@ -3186,6 +3209,9 @@ int lv_create_single(struct volume_group log_error("Problem reactivating origin %s", org->name); return 0; } + + if (!origin_active && lp->shared_store) + deactivate_lv(cmd, org); } /* FIXME out of sequence */ backup(vg);