[virt-tools-list] [virt-manager PATCH v2 1/2] virt-clone: introduce --reflink for btrfs COW copy

Chen Hanxiao chenhanxiao at cn.fujitsu.com
Fri Jan 30 03:50:18 UTC 2015


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 <chenhanxiao at cn.fujitsu.com>
---
v2: rewrite patch based on Cole's sugguestion.

 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 e6699a0..3fc6a17 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 5e76413..68a5786 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 bdbd064..98e76f4 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 440be55..adc7410 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
-- 
2.1.0




More information about the virt-tools-list mailing list