diff options
author | Tony Asleson <tasleson@redhat.com> | 2013-06-06 16:40:51 -0400 |
---|---|---|
committer | Tony Asleson <tasleson@redhat.com> | 2013-07-02 14:24:34 -0500 |
commit | 49e3eecc33dbe0a47d8dcdbf225ddd52a8a6b75d (patch) | |
tree | a1c1d5ae462948c04dcf796b8f7611c21c903c8b | |
parent | 2a3472b2b34d2ef82cc04eb89bd29dfb456e2d47 (diff) | |
download | lvm2-49e3eecc33dbe0a47d8dcdbf225ddd52a8a6b75d.tar.gz |
lvm2app: Add thinp snapshot functionality
Added parameter object constructor for thinp and
changed the shapshot function to use it.
Signed-off-by: Tony Asleson <tasleson@redhat.com>
-rw-r--r-- | liblvm/lvm2app.h | 21 | ||||
-rw-r--r-- | liblvm/lvm_lv.c | 100 |
2 files changed, 88 insertions, 33 deletions
diff --git a/liblvm/lvm2app.h b/liblvm/lvm2app.h index 65dc340e3..f4475c08f 100644 --- a/liblvm/lvm2app.h +++ b/liblvm/lvm2app.h @@ -1538,7 +1538,26 @@ lv_create_params_t lvm_lv_params_create_thin_pool(vg_t vg, LVM_THIN_DISCARDS_PASSDOWN) - +/** + * Creates the snapshot parameter passing object for the specified lv. + * + * \param lv + * The logical volume to snapshot + * + * \param snap_name + * Name of snapshot + * + * \param max_snap_size + * Used for old snap shots max size, set to zero for thinp + * + * \return + * Valid lv_create_params pointer on success, else NULL on error. + * Note: Memory is associated with the vg, it will get reclaimed when vg is + * closed. + */ +lv_create_params_t lvm_lv_params_create_snapshot(const lv_t lv, + const char *snap_name, + uint64_t max_snap_size); /** * Get the specific value of a lv create parameter by name * diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c index 9f5921055..081c73edc 100644 --- a/liblvm/lvm_lv.c +++ b/liblvm/lvm_lv.c @@ -347,41 +347,16 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size) return 0; } -lv_t lvm_lv_snapshot(const lv_t lv, const char *snap_name, uint64_t max_snap_size) +lv_t lvm_lv_snapshot(const lv_t lv, const char *snap_name, + uint64_t max_snap_size) { - struct lvcreate_params lp = { 0 }; - uint64_t extents = 0; - uint64_t size = 0; - struct lv_list *lvl = NULL; - - if (vg_read_error(lv->vg)) - return NULL; - if (!vg_check_write_mode(lv->vg)) - return NULL; - - size = max_snap_size >> SECTOR_SHIFT; + struct lvm_lv_create_params *lvcp = NULL; - if (!(extents = extents_from_size(lv->vg->cmd, size, - lv->vg->extent_size))) { - log_error("Unable to create LV snapshot without size."); - return NULL; + lvcp = lvm_lv_params_create_snapshot(lv, snap_name, max_snap_size); + if (lvcp) { + return lvm_lv_create(lvcp); } - - _lv_set_default_params(&lp, lv->vg, snap_name, extents); - - /* Fill out required default input values */ - lp.snapshot = 1; - lp.segtype = _get_segtype(lv->vg->cmd); - lp.stripes = 1; - lp.origin = lv->name; - - if (!lp.segtype) - return_NULL; - if (!lv_create_single(lv->vg, &lp)) - return_NULL; - if (!(lvl = find_lv_in_vg(lv->vg, snap_name))) - return NULL; - return (lv_t) lvl->lv; + return NULL; } /* Set defaults for thin pool specific LV parameters */ @@ -496,6 +471,67 @@ static void _lv_set_thin_params(struct lvcreate_params *lp, lp->stripes = 1; } +lv_create_params_t lvm_lv_params_create_snapshot(const lv_t lv, + const char *snap_name, + uint64_t max_snap_size) +{ + uint64_t size = 0; + uint64_t extents = 0; + struct lvm_lv_create_params *lvcp = NULL; + + if (vg_read_error(lv->vg)) { + return NULL; + } + + if (!vg_check_write_mode(lv->vg)) + return NULL; + + if (snap_name == NULL || !strlen(snap_name)) { + log_error("snap_name invalid"); + return NULL; + } + + if (max_snap_size) { + size = max_snap_size >> SECTOR_SHIFT; + extents = extents_from_size(lv->vg->cmd, size, lv->vg->extent_size); + } + + if (!size && !lv_is_thin_volume(lv) ) { + log_error("Origin is not thin, specify size of snapshot"); + return NULL; + } + + lvcp = dm_pool_zalloc(lv->vg->vgmem, sizeof (struct lvm_lv_create_params)); + if (lvcp) { + lvcp->vg = lv->vg; + _lv_set_default_params(&lvcp->lvp, lv->vg, snap_name, extents); + lvcp->lvp.snapshot = 1; + + + if (size) { + lvcp->lvp.segtype = _get_segtype(lvcp->vg->cmd); + lvcp->lvp.chunk_size = 8; + } else { + lvcp->lvp.segtype = get_segtype_from_string(lv->vg->cmd, "thin"); + + if (!lvcp->lvp.segtype) { + log_error(INTERNAL_ERROR "Segtype thin not found."); + return NULL; + } + + lvcp->lvp.pool = first_seg(lv)->pool_lv->name; + } + + lvcp->lvp.stripes = 1; + lvcp->lvp.origin = lv->name; + + lvcp->magic = LV_CREATE_PARAMS_MAGIC; + } + + return lvcp; +} + + lv_create_params_t lvm_lv_params_create_thin(const vg_t vg, const char *pool_name, const char *lvname, uint64_t size) { |