[PATCH 2/3] Add support for detecting btrfs default subvolume.

David Lehman dlehman at redhat.com
Fri Nov 15 14:32:01 UTC 2013


---
 blivet/devicelibs/btrfs.py | 16 ++++++++++++++++
 blivet/devices.py          | 31 +++++++++++++++++++++++++++++--
 blivet/devicetree.py       |  3 +++
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/blivet/devicelibs/btrfs.py b/blivet/devicelibs/btrfs.py
index eba27f7..1661f53 100644
--- a/blivet/devicelibs/btrfs.py
+++ b/blivet/devicelibs/btrfs.py
@@ -32,6 +32,8 @@ _ = lambda x: gettext.ldgettext("blivet", x)
 import logging
 log = logging.getLogger("blivet")
 
+main_volume_id = 5
+
 def btrfs(args, capture=False):
     if capture:
         exec_func = util.capture_output
@@ -113,3 +115,17 @@ def list_subvolumes(mountpoint):
                      "path": group[2]})
 
     return vols
+
+def get_default_subvolume(mountpoint):
+    if not os.path.ismount(mountpoint):
+        raise ValueError("volume not mounted")
+
+    args = ["subvol", "get-default", mountpoint]
+    buf = btrfs(args, capture=True)
+    m = re.match(r'ID (\d+) .*', buf)
+    try:
+        default = int(m.groups()[0])
+    except IndexError:
+        raise BTRFSError("failed to get default subvolume from %s" % mountpoint)
+
+    return default
diff --git a/blivet/devices.py b/blivet/devices.py
index 725a917..6c8acd3 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -4351,7 +4351,7 @@ class BTRFSDevice(StorageDevice):
 
 class BTRFSVolumeDevice(BTRFSDevice):
     _type = "btrfs volume"
-    vol_id = 5
+    vol_id = btrfs.main_volume_id
 
     def __init__(self, *args, **kwargs):
         self.dataLevel = kwargs.pop("dataLevel", None)
@@ -4379,7 +4379,7 @@ class BTRFSVolumeDevice(BTRFSDevice):
                                     label=label,
                                     volUUID=self.uuid,
                                     device=self.path,
-                                    mountopts="subvolid=" + self.vol_id)
+                                    mountopts="subvolid=%d" % self.vol_id)
             self.originalFormat = copy.copy(self.format)
 
     def _setFormat(self, format):
@@ -4487,6 +4487,8 @@ class BTRFSVolumeDevice(BTRFSDevice):
             subvols = btrfs.list_subvolumes(self.originalFormat._mountpoint)
         except BTRFSError as e:
             log.debug("failed to list subvolumes: %s" % e)
+        else:
+            self._getDefaultSubVolumeID()
         finally:
             self._undo_temp_mount()
 
@@ -4503,6 +4505,31 @@ class BTRFSVolumeDevice(BTRFSDevice):
     def removeSubVolume(self, name):
         raise NotImplementedError()
 
+    def _getDefaultSubVolumeID(self):
+        subvolid = None
+        try:
+            subvolid = btrfs.get_default_subvolume(self.originalFormat._mountpoint)
+        except BTRFSError as e:
+            log.debug("failed to get default subvolume id: %s" % e)
+
+        self.defaultSubVolumeID = subvolid
+
+    @property
+    def defaultSubVolume(self):
+        default = None
+        if self.defaultSubVolumeID is None:
+            return None
+
+        if self.defaultSubVolumeID == btrfs.main_volume_id:
+            return self
+
+        for sv in self.subvolumes:
+            if sv.vol_id == self.defaultSubVolumeID:
+                default = sv
+                break
+
+        return default
+
     def _create(self):
         log_method_call(self, self.name, status=self.status)
         btrfs.create_volume(devices=[d.path for d in self.parents],
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 0311e42..4ef67d3 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -2364,6 +2364,9 @@ class DeviceTree(object):
             elif "subvolid=" in options:
                 attr = "vol_id"
                 val = util.get_option_value("subvolid", options)
+            elif device.defaultSubVolume:
+                # default subvolume
+                device = device.defaultSubVolume
 
             if attr and val:
                 for subvol in device.subvolumes:
-- 
1.8.1.4



More information about the anaconda-patches mailing list