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

Brian C. Lane bcl at redhat.com
Sat Nov 16 01:28:39 UTC 2013


On Fri, Nov 15, 2013 at 08:32:01AM -0600, David Lehman wrote:
> ---
>  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
> +

This should be all caps.

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

The match may fail and m could be None which will give you an
AttributeError

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

why do this instead of just referring to btrfs.MAIN_VOLUME_ID where
needed?

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

How is vol_id different from btrfs.main_volume_id? I must be missing
something here.

-- 
Brian C. Lane | Anaconda Team | IRC: bcl #anaconda | Port Orchard, WA (PST8PDT)


More information about the anaconda-patches mailing list