Support snapshots-of-snapshots Signed-off-by: Mikulas Patocka --- lib/activate/activate.c | 6 +++--- lib/activate/activate.h | 3 ++- lib/activate/dev_manager.c | 10 ++++++++-- lib/activate/dev_manager.h | 1 + lib/metadata/lv_manip.c | 9 +++++++-- 5 files changed, 21 insertions(+), 8 deletions(-) Index: lvm2/lib/metadata/lv_manip.c =================================================================== --- lvm2.orig/lib/metadata/lv_manip.c +++ lvm2/lib/metadata/lv_manip.c @@ -3052,6 +3052,7 @@ int lv_create_single(struct volume_group struct logical_volume *lv, *org = NULL; int origin_active = 0; const char *lv_name; + const char *origin_snapid = NULL; struct lvinfo info; again: @@ -3136,12 +3137,16 @@ again: lp->origin); return 0; } + if (lv_is_multisnap_cow(org)) { + origin_snapid = first_seg(org)->snapid; + org = first_seg(org)->origin; + } if (lv_is_virtual_origin(org)) { log_error("Can't share virtual origins. " "Use --virtualsize."); return 0; } - if (lv_is_cow(org) || lv_is_multisnap_cow(org)) { + if (lv_is_cow(org)) { log_error("Snapshots of snapshots are not " "supported yet."); return 0; @@ -3325,7 +3330,7 @@ again: } } - if (!lv_multisnap_prepare_create(cmd, org, &snapid)) { + if (!lv_multisnap_prepare_create(cmd, org, origin_snapid, &snapid)) { log_error("Couldn't make new snapshot for origin LV %s", org->name); multisnapshot_error: Index: lvm2/lib/activate/activate.c =================================================================== --- lvm2.orig/lib/activate/activate.c +++ lvm2/lib/activate/activate.c @@ -209,7 +209,7 @@ int lv_activate_with_filter(struct cmd_c return 1; } -int lv_multisnap_prepare_create(struct cmd_context *cmd, struct logical_volume *lv, char **snapid) +int lv_multisnap_prepare_create(struct cmd_context *cmd, struct logical_volume *lv, const char *origin_snapid, char **snapid) { return 0; } @@ -1167,7 +1167,7 @@ int lv_activate_with_filter(struct cmd_c return 1; } -int lv_multisnap_prepare_create(struct cmd_context *cmd, struct logical_volume *lv, char **snapid) +int lv_multisnap_prepare_create(struct cmd_context *cmd, struct logical_volume *lv, const char *origin_snapid, char **snapid) { struct dev_manager *dm; int r; @@ -1178,7 +1178,7 @@ int lv_multisnap_prepare_create(struct c if (!(dm = dev_manager_create(cmd, lv->vg->name))) return_0; - r = dev_manager_multisnap_prepare_create(dm, lv, snapid); + r = dev_manager_multisnap_prepare_create(dm, lv, origin_snapid, snapid); dev_manager_destroy(dm); Index: lvm2/lib/activate/activate.h =================================================================== --- lvm2.orig/lib/activate/activate.h +++ lvm2/lib/activate/activate.h @@ -63,7 +63,8 @@ int lv_activate_with_filter(struct cmd_c int lv_deactivate(struct cmd_context *cmd, const char *lvid_s); int lv_multisnap_prepare_create(struct cmd_context *cmd, - struct logical_volume *lv, char **snapid); + struct logical_volume *lv, + const char *origin_snapid, char **snapid); int lv_multisnap_delete(struct cmd_context *cmd, struct logical_volume *lv, const char *snapid); Index: lvm2/lib/activate/dev_manager.c =================================================================== --- lvm2.orig/lib/activate/dev_manager.c +++ lvm2/lib/activate/dev_manager.c @@ -741,6 +741,7 @@ static int _multisnapshot_status(struct int dev_manager_multisnap_prepare_create(struct dev_manager *dm, struct logical_volume *lv, + const char *origin_snapid, char **snapid) { const char *dlid; @@ -753,8 +754,13 @@ int dev_manager_multisnap_prepare_create log_debug("Getting new snapshot id for %s", lv->name); - if (!_multisnap_message(dm, dlid, "create")) - return 0; + if (!origin_snapid) { + if (!_multisnap_message(dm, dlid, "create")) + return 0; + } else { + if (!_multisnap_message(dm, dlid, "create_subsnap %s", origin_snapid)) + return 0; + } if (!_multisnapshot_status(dm, dlid, &err, snapid, NULL, NULL, NULL)) return 0; Index: lvm2/lib/activate/dev_manager.h =================================================================== --- lvm2.orig/lib/activate/dev_manager.h +++ lvm2/lib/activate/dev_manager.h @@ -62,6 +62,7 @@ int dev_manager_mknodes(const struct log int dev_manager_multisnap_prepare_create(struct dev_manager *dm, struct logical_volume *lv, + const char *origin_snapid, char **snapid); int dev_manager_multisnap_delete(struct dev_manager *dm, struct logical_volume *lv,