Currently the Snapshot() method is used only during `gnt-backup export` and is only implemented in the LogicalVolume() class.
This patch makes this method a BlockDev() method, changes its signature so that it can take both snap_size and snap_name and lets bdev calculate both (i.e. snap_size=bdev.size, snap_name=bdev._lv_name + snap). Signed-off-by: Dimitris Aragiorgis <[email protected]> --- lib/backend.py | 15 ++++++++------- lib/storage/base.py | 16 ++++++++++++++++ lib/storage/bdev.py | 20 +++++++++++++------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index 4b98e22..7a6c4bd 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -3404,19 +3404,20 @@ def BlockdevSnapshot(disk): @return: snapshot disk ID as (vg, lv) """ + def _DiskSnapshot(disk, snap_name=None, snap_size=None): + r_dev = _RecursiveFindBD(disk) + if r_dev is not None: + return r_dev.Snapshot(snap_name=snap_name, snap_size=snap_size) + else: + _Fail("Cannot find block device %s", disk) + if disk.dev_type == constants.DT_DRBD8: if not disk.children: _Fail("DRBD device '%s' without backing storage cannot be snapshotted", disk.unique_id) return BlockdevSnapshot(disk.children[0]) elif disk.dev_type == constants.DT_PLAIN: - r_dev = _RecursiveFindBD(disk) - if r_dev is not None: - # FIXME: choose a saner value for the snapshot size - # let's stay on the safe side and ask for the full size, for now - return r_dev.Snapshot(disk.size) - else: - _Fail("Cannot find block device %s", disk) + return _DiskSnapshot(disk) else: _Fail("Cannot snapshot non-lvm block device '%s' of type '%s'", disk.unique_id, disk.dev_type) diff --git a/lib/storage/base.py b/lib/storage/base.py index 9d23dd2..0ffcf99 100644 --- a/lib/storage/base.py +++ b/lib/storage/base.py @@ -233,6 +233,22 @@ class BlockDev(object): "count=%s" % self.size, "iflag=direct"] + def Snapshot(self, snap_name, snap_size): + """Creates a snapshot of the block device. + + Currently this is used only during LUInstanceExport. + + @type snap_name: string + @param snap_name: The name of the snapshot. + @type snap_size: int + @param snap_size: The size of the snapshot. + @rtype: tuple + @return: The logical id of the newly created disk. + + """ + ThrowError("Snapshot is not supported for disk %s of type %s.", + self.unique_id, self.__class__.__name__) + def SetSyncParams(self, params): """Adjust the synchronization parameters of the mirror. diff --git a/lib/storage/bdev.py b/lib/storage/bdev.py index e75cc8e..64b8b1c 100644 --- a/lib/storage/bdev.py +++ b/lib/storage/bdev.py @@ -592,28 +592,34 @@ class LogicalVolume(base.BlockDev): """ pass - def Snapshot(self, size): + def Snapshot(self, snap_name=None, snap_size=None): """Create a snapshot copy of an lvm block device. @returns: tuple (vg, lv) """ - snap_name = self._lv_name + ".snap" + if not snap_name: + snap_name = self._lv_name + ".snap" + + if not snap_size: + # FIXME: choose a saner value for the snapshot size + # let's stay on the safe side and ask for the full size, for now + snap_size = self.size # remove existing snapshot if found - snap = LogicalVolume((self._vg_name, snap_name), None, size, self.params, - self.dyn_params) + snap = LogicalVolume((self._vg_name, snap_name), None, snap_size, + self.params, self.dyn_params) base.IgnoreError(snap.Remove) vg_info = self.GetVGInfo([self._vg_name], False) if not vg_info: base.ThrowError("Can't compute VG info for vg %s", self._vg_name) free_size, _, _ = vg_info[0] - if free_size < size: + if free_size < snap_size: base.ThrowError("Not enough free space: required %s," - " available %s", size, free_size) + " available %s", snap_size, free_size) - _CheckResult(utils.RunCmd(["lvcreate", "-L%dm" % size, "-s", + _CheckResult(utils.RunCmd(["lvcreate", "-L%dm" % snap_size, "-s", "-n%s" % snap_name, self.dev_path])) return (self._vg_name, snap_name) -- 1.7.10.4
