[PATCH 06/17] Add backend functions for creating and managing snapshots.
David Lehman
dlehman at redhat.com
Thu Jun 5 16:47:26 UTC 2014
---
blivet/devicelibs/btrfs.py | 20 +++++++++++++++-----
blivet/devicelibs/lvm.py | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/blivet/devicelibs/btrfs.py b/blivet/devicelibs/btrfs.py
index 61697ba..e1d08d0 100644
--- a/blivet/devicelibs/btrfs.py
+++ b/blivet/devicelibs/btrfs.py
@@ -107,20 +107,23 @@ def delete_subvolume(mountpoint, name):
args = ["subvol", "delete", path]
return btrfs(args)
-_SUBVOL_REGEX_STR = r'ID (\d+) gen \d+ parent (\d+) top level \d+ path (.+)\n'
+_SUBVOL_REGEX_STR = r'ID (?P<id>\d+) gen \d+ (cgen \d+ )?parent (?P<parent>\d+) top level \d+ (otime \d{4}-\d{2}-\d{2} \d\d:\d\d:\d\d )?path (?P<path>.+)\n'
_SUBVOL_REGEX = re.compile(_SUBVOL_REGEX_STR)
# get a list of subvolumes from a mounted btrfs filesystem
-def list_subvolumes(mountpoint):
+def list_subvolumes(mountpoint, snapshots_only=False):
if not os.path.ismount(mountpoint):
raise ValueError("volume not mounted")
args = ["subvol", "list", "-p", mountpoint]
+ if snapshots_only:
+ args.insert(2, "-s")
+
buf = btrfs(args, capture=True)
vols = []
- for group in _SUBVOL_REGEX.findall(buf):
- vols.append({"id": int(group[0]), "parent": int(group[1]),
- "path": group[2]})
+ for m in _SUBVOL_REGEX.finditer(buf):
+ vols.append({"id": int(m.group('id')), "parent": int(m.group('parent')),
+ "path": m.group('path')})
return vols
@@ -138,6 +141,13 @@ def get_default_subvolume(mountpoint):
return default
+def create_snapshot(source, dest):
+ if not os.path.ismount(source):
+ raise ValueError("source is not a mounted subvolume")
+
+ args = ["subvol", "snapshot", source, dest]
+ return btrfs(args)
+
_DEVICE_REGEX_STR = r'devid[ \t]+(\d+)[ \t]+size[ \t]+(\S+)[ \t]+used[ \t]+(\S+)[ \t]+path[ \t]+(\S+)\n'
_DEVICE_REGEX = re.compile(_DEVICE_REGEX_STR)
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
index f2b85ac..a66f4d6 100644
--- a/blivet/devicelibs/lvm.py
+++ b/blivet/devicelibs/lvm.py
@@ -520,6 +520,32 @@ def lvdeactivate(vg_name, lv_name):
except LVMError as msg:
raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
+def lvsnapshotmerge(vg_name, lv_name):
+ """ Merge(/rollback/revert) a snapshot volume into its origin.
+
+ .. note::
+
+ This is an asynchronous procedure. See lvconvert(8) for details of
+ how merge is handled by lvm.
+
+ """
+ args = ["lvconvert", "--merge", "%s/%s" % (vg_name, lv_name)]
+ args += _getConfigArgs() + [lv_name]
+
+ try:
+ lvm(args)
+ except LVMError as msg:
+ raise LVMError("lvsnapshotmerge failed for %s: %s" % (lv_name, msg))
+
+def lvsnapshotcreate(vg_name, lv_name, size, origin):
+ args = ["lvcreate", "-s", "-L", "%dm" % size.convertTo(spec="MiB"),
+ "-n", lv_name] + _getConfigArgs() + ["%s/%s" % (vg_name, origin)]
+
+ try:
+ lvm(args)
+ except LVMError as msg:
+ raise LVMError("lvsnapshotcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
+
def thinpoolcreate(vg_name, lv_name, size, metadatasize=None, chunksize=None):
args = ["lvcreate", "--thinpool", "%s/%s" % (vg_name, lv_name),
"--size", "%dm" % size.convertTo(spec="mib")]
@@ -550,6 +576,15 @@ def thinlvcreate(vg_name, pool_name, lv_name, size):
except LVMError as msg:
raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
+def thinsnapshotcreate(vg_name, lv_name, origin_name, pool_name=None):
+ args = ["lvcreate", "-s", "-n", lv_name, "%s/%s" % (vg_name, origin_name)]
+ if pool_name:
+ args.extend(["--thinpool", pool_name])
+ try:
+ lvm(args)
+ except LVMError as msg:
+ raise LVMError("lvcreate (snapshot) failed for %s/%s: %s" % (vg_name, lv_name, msg))
+
def thinlvpoolname(vg_name, lv_name):
args = ["lvs", "--noheadings", "-o", "pool_lv"] + \
_getConfigArgs(read_only_locking=True) + \
--
1.9.0
More information about the anaconda-patches
mailing list