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 <chenhanxiao@cn.fujitsu.com>
This commit is contained in:
Chen Hanxiao 2015-02-07 10:18:05 +08:00
parent e44b95149b
commit 4622a0a8f8
4 changed files with 31 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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