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 | 13 ++++++++++--- 5 files changed, 24 insertions(+), 9 deletions(-) Index: LVM2.2.02.85/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.85.orig/lib/metadata/lv_manip.c 2011-06-24 18:58:52.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/lv_manip.c 2011-06-24 19:00:21.000000000 +0200 @@ -3527,6 +3527,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: @@ -3606,15 +3607,21 @@ again: lp->origin); return 0; } - if (!lp->extents && lv_is_multisnap_origin(org)) { + if (!lp->extents && + (lv_is_multisnap_origin(org) || + lv_is_multisnap_cow(org))) { lp->extents = org->le_count; } + 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; @@ -3806,7 +3813,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.2.02.85/lib/activate/activate.c =================================================================== --- LVM2.2.02.85.orig/lib/activate/activate.c 2011-06-24 18:58:52.000000000 +0200 +++ LVM2.2.02.85/lib/activate/activate.c 2011-06-24 18:58:53.000000000 +0200 @@ -211,7 +211,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; } @@ -1456,7 +1456,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; @@ -1467,7 +1467,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.2.02.85/lib/activate/activate.h =================================================================== --- LVM2.2.02.85.orig/lib/activate/activate.h 2011-06-24 18:58:52.000000000 +0200 +++ LVM2.2.02.85/lib/activate/activate.h 2011-06-24 18:58:53.000000000 +0200 @@ -64,7 +64,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.2.02.85/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.85.orig/lib/activate/dev_manager.c 2011-06-24 18:58:52.000000000 +0200 +++ LVM2.2.02.85/lib/activate/dev_manager.c 2011-06-24 18:59:27.000000000 +0200 @@ -852,6 +852,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; @@ -864,8 +865,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.2.02.85/lib/activate/dev_manager.h =================================================================== --- LVM2.2.02.85.orig/lib/activate/dev_manager.h 2011-06-24 18:58:52.000000000 +0200 +++ LVM2.2.02.85/lib/activate/dev_manager.h 2011-06-24 18:58:53.000000000 +0200 @@ -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,