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@xxxxxxxxxxxxxx> --- 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 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list