From 4622a0a8f873418108eef6c2363ebb01a4b407d7 Mon Sep 17 00:00:00 2001 From: Chen Hanxiao Date: Sat, 7 Feb 2015 10:18:05 +0800 Subject: [PATCH] virt-clone: introduce --reflink for btrfs COW copy libvirt commit 466b29c8c3593b2dac92acad5dd8ec923c428259 introduce btrfsCloneFile() for COW copy. This patch add support for --reflink option for virt-clone. When specified --reflink, if src and dst images all on a btrfs fs, we could take advantage of COW copy. If not, error out. Signed-off-by: Chen Hanxiao --- virt-clone | 4 ++++ virtinst/cloner.py | 9 +++++++++ virtinst/storage.py | 15 +++++++++++++++ virtinst/support.py | 3 +++ 4 files changed, 31 insertions(+) diff --git a/virt-clone b/virt-clone index e6699a096..3fc6a17a8 100755 --- a/virt-clone +++ b/virt-clone @@ -120,6 +120,8 @@ def parse_args(): geng.add_argument("-n", "--name", dest="new_name", help=_("Name for the new guest")) geng.add_argument("-u", "--uuid", dest="new_uuid", help=argparse.SUPPRESS) + geng.add_argument("--reflink", action="store_true", dest="reflink", + help=_("use btrfs COW lightweight copy")) stog = parser.add_argument_group(_("Storage Configuration")) stog.add_argument("-f", "--file", dest="new_diskfile", action="append", @@ -178,6 +180,8 @@ def main(conn=None): get_clone_macaddr(options.new_mac, design) if options.new_uuid is not None: design.clone_uuid = options.new_uuid + if options.reflink is True: + design.reflink = True for i in options.target or []: design.force_target = i design.clone_sparse = options.sparse diff --git a/virtinst/cloner.py b/virtinst/cloner.py index 5e76413d8..68a5786fc 100644 --- a/virtinst/cloner.py +++ b/virtinst/cloner.py @@ -63,6 +63,7 @@ class Cloner(object): self._preserve = True self._clone_running = False self._replace = False + self._reflink = False # Default clone policy for back compat: don't clone readonly, # shareable, or empty disks @@ -259,6 +260,13 @@ class Cloner(object): replace = property(_get_replace, _set_replace, doc="If enabled, don't check for clone name collision, " "simply undefine any conflicting guest.") + def _get_reflink(self): + return self._reflink + def _set_reflink(self, reflink): + self._reflink = reflink + reflink = property(_get_reflink, _set_reflink, + doc="If true, use COW lightweight copy") + # Functional methods def setup_original(self): @@ -343,6 +351,7 @@ class Cloner(object): clone_vol_install.input_vol = orig_disk.get_vol_object() vol_install = clone_vol_install + vol_install.reflink = self.reflink clone_disk.set_vol_install(vol_install) elif orig_disk.path: clone_disk.set_local_disk_to_clone(orig_disk, self.clone_sparse) diff --git a/virtinst/storage.py b/virtinst/storage.py index bdbd064ed..98e76f49e 100644 --- a/virtinst/storage.py +++ b/virtinst/storage.py @@ -557,6 +557,7 @@ class StorageVolume(_StorageObject): self._input_vol = None self._pool = None self._pool_xml = None + self._reflink = False # Indicate that the volume installation has finished. Used to # definitively tell the storage progress thread to stop polling. @@ -597,6 +598,17 @@ class StorageVolume(_StorageObject): doc=_("virStorageVolume pointer to clone/use as " "input.")) + def _get_reflink(self): + return self._reflink + def _set_reflink(self, reflink): + if not self.conn.check_support(self.conn.SUPPORT_POOL_REFLINK): + raise ValueError(_("Creating storage by btrfs COW copy is" + " not supported by this libvirt version.")) + + self._reflink = reflink + reflink = property(_get_reflink, _set_reflink, + doc="flags for VIR_STORAGE_VOL_CREATE_REFLINK") + def sync_input_vol(self): # Pull parameters from input vol into this class parsevol = StorageVolume(self.conn, @@ -748,6 +760,9 @@ class StorageVolume(_StorageObject): self.conn.SUPPORT_POOL_METADATA_PREALLOC, self.pool)): createflags |= libvirt.VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA + if self.reflink: + cloneflags |= libvirt.VIR_STORAGE_VOL_CREATE_REFLINK + try: self._install_finished = False diff --git a/virtinst/support.py b/virtinst/support.py index 440be5513..adc741065 100644 --- a/virtinst/support.py +++ b/virtinst/support.py @@ -340,6 +340,9 @@ SUPPORT_POOL_LISTALLVOLUMES = _make( SUPPORT_POOL_METADATA_PREALLOC = _make( flag="VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA", version="1.0.1") +SUPPORT_POOL_REFLINK = _make( + flag="VIR_STORAGE_VOL_CREATE_REFLINK", + version="1.2.13") # Interface checks