From f3ec8efbdd4aa4b907a0c9b904d3057639d1b7f8 Mon Sep 17 00:00:00 2001 From: David Lehman Date: Thu, 21 Aug 2014 12:46:21 -0500 Subject: [PATCH 6/7] Reset default subvolume prior to removing the default subvolume. Resolves: rhbz#1076383 --- blivet/devicelibs/btrfs.py | 7 +++++++ blivet/devices.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/blivet/devicelibs/btrfs.py b/blivet/devicelibs/btrfs.py index 0e1171d..94aefaa 100644 --- a/blivet/devicelibs/btrfs.py +++ b/blivet/devicelibs/btrfs.py @@ -151,6 +151,13 @@ def get_default_subvolume(mountpoint): return default +def set_default_subvolume(mountpoint, subvol_id): + if not os.path.ismount(mountpoint): + raise ValueError("volume not mounted") + + args = ["subvol", "set-default", subvol_id, mountpoint] + return btrfs(args) + def create_snapshot(source, dest, ro=False): """ :param str source: path to source subvolume diff --git a/blivet/devices.py b/blivet/devices.py index 9df38dd..01a2f62 100644 --- a/blivet/devices.py +++ b/blivet/devices.py @@ -5196,6 +5196,23 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice): self._defaultSubVolumeID = subvolid + def _setDefaultSubVolumeID(self, vol_id): + """ Set a new default subvolume by id. + + This writes the change to the filesystem, which must be mounted. + """ + try: + btrfs.set_default_subvolume(self.originalFormat._mountpoint, vol_id) + except BTRFSError as e: + log.error("failed to set new default subvolume id (%s): %s", + vol_id, e) + # The only time we set a new default subvolume is so we can remove + # the current default. If we can't change the default, we won't be + # able to remove the subvolume. + raise + else: + self._defaultSubVolumeID = vol_id + @property def defaultSubVolume(self): default = None @@ -5355,6 +5372,10 @@ class BTRFSSubVolumeDevice(BTRFSDevice): def _destroy(self): log_method_call(self, self.name, status=self.status) self.volume._do_temp_mount(orig=True) + if self.volume._defaultSubVolumeID == self.vol_id: + # btrfs does not allow removal of the default subvolume + self.volume._setDefaultSubVolumeID(self.volume.vol_id) + mountpoint = self.volume.originalFormat._mountpoint if not mountpoint: raise RuntimeError("btrfs subvol destroy requires mounted volume") -- 1.9.3