[virt-tools-list] [virt-manager PATCH 1/3] virt-clone: introduce --reflink for btrfs COW copy
Chen Hanxiao
chenhanxiao at cn.fujitsu.com
Wed Jan 28 04:12:11 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>
---
virt-clone | 4 +++-
virtinst/cloner.py | 5 +++--
virtinst/devicedisk.py | 4 ++--
virtinst/diskbackend.py | 14 ++++++++------
virtinst/storage.py | 5 ++++-
5 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/virt-clone b/virt-clone
index e6699a0..1e189f8 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 lightweight copy"))
stog = parser.add_argument_group(_("Storage Configuration"))
stog.add_argument("-f", "--file", dest="new_diskfile", action="append",
@@ -198,7 +200,7 @@ def main(conn=None):
else:
# start cloning
meter = progress.TextMeter(fo=sys.stdout)
- design.start_duplicate(meter)
+ design.start_duplicate(meter, options.reflink)
print_stdout("")
print_stdout(_("Clone '%s' created successfully.") % design.clone_name)
diff --git a/virtinst/cloner.py b/virtinst/cloner.py
index 5e76413..7d1ef3e 100644
--- a/virtinst/cloner.py
+++ b/virtinst/cloner.py
@@ -415,7 +415,7 @@ class Cloner(object):
self.setup_original()
self.setup_clone()
- def start_duplicate(self, meter=None):
+ def start_duplicate(self, meter=None, reflink=None):
"""
Actually perform the duplication: cloning disks if needed and defining
the new clone xml.
@@ -436,7 +436,8 @@ class Cloner(object):
if self.preserve:
for dst_dev in self.clone_disks:
- dst_dev.setup(meter=meter)
+ # seed for test reflink!!!!
+ dst_dev.setup(meter=meter, reflink=reflink)
except Exception, e:
logging.debug("Duplicate failed: %s", str(e))
if dom:
diff --git a/virtinst/devicedisk.py b/virtinst/devicedisk.py
index ac03716..813cbfe 100644
--- a/virtinst/devicedisk.py
+++ b/virtinst/devicedisk.py
@@ -857,7 +857,7 @@ class VirtualDisk(VirtualDevice):
self._storage_backend.validate(self)
- def setup(self, meter=None):
+ def setup(self, meter=None, reflink=None):
"""
Build storage (if required)
@@ -872,7 +872,7 @@ class VirtualDisk(VirtualDevice):
if not self._storage_backend.will_create_storage():
return
- vol_object = self._storage_backend.create(meter)
+ vol_object = self._storage_backend.create(meter, reflink)
if not vol_object:
return
diff --git a/virtinst/diskbackend.py b/virtinst/diskbackend.py
index 2bcd064..2e1250a 100644
--- a/virtinst/diskbackend.py
+++ b/virtinst/diskbackend.py
@@ -202,7 +202,7 @@ class _StorageBase(object):
# Storage creation routines
def is_size_conflict(self):
raise NotImplementedError()
- def create(self, progresscb):
+ def create(self, progresscb, reflink):
raise NotImplementedError()
def will_create_storage(self):
raise NotImplementedError()
@@ -226,7 +226,7 @@ class _StorageCreator(_StorageBase):
# Public API #
##############
- def create(self, progresscb):
+ def create(self, progresscb, reflink):
raise NotImplementedError()
def get_path(self):
@@ -341,7 +341,8 @@ class CloneStorageCreator(_StorageCreator):
((need / (1024 * 1024)), (avail / (1024 * 1024))))
return (ret, msg)
- def create(self, progresscb):
+ def create(self, progresscb, reflink):
+ ignore = reflink
text = (_("Cloning %(srcfile)s") %
{'srcfile' : os.path.basename(self._input_path)})
@@ -432,8 +433,8 @@ class ManagedStorageCreator(_StorageCreator):
self._pool = vol_install.pool
self._vol_install = vol_install
- def create(self, progresscb):
- return self._vol_install.install(meter=progresscb)
+ def create(self, progresscb, reflink=None):
+ return self._vol_install.install(meter=progresscb, reflink=reflink)
def is_size_conflict(self):
return self._vol_install.is_size_conflict()
@@ -573,7 +574,8 @@ class StorageBackend(_StorageBase):
return (False, None)
def will_create_storage(self):
return False
- def create(self, progresscb):
+ def create(self, progresscb, reflink):
ignore = progresscb
+ ignore = reflink
raise RuntimeError("programming error: %s can't create storage" %
self.__class__.__name__)
diff --git a/virtinst/storage.py b/virtinst/storage.py
index bdbd064..fe7f9cb 100644
--- a/virtinst/storage.py
+++ b/virtinst/storage.py
@@ -723,7 +723,7 @@ class StorageVolume(_StorageObject):
"setting allocation equal to capacity"))
self.allocation = self.capacity
- def install(self, meter=None):
+ def install(self, meter=None, reflink=None):
"""
Build and install storage volume from xml
"""
@@ -748,6 +748,9 @@ class StorageVolume(_StorageObject):
self.conn.SUPPORT_POOL_METADATA_PREALLOC, self.pool)):
createflags |= libvirt.VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA
+ if reflink:
+ cloneflags |= libvirt.VIR_STORAGE_VOL_CREATE_REFLINK
+
try:
self._install_finished = False
--
2.1.0
More information about the virt-tools-list
mailing list