[PATCH 4/9] Add type-specific methods for member set management.
David Lehman
dlehman at redhat.com
Thu Mar 20 17:14:08 UTC 2014
---
blivet/devices.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++------
blivet/formats/fs.py | 4 +--
2 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/blivet/devices.py b/blivet/devices.py
index 5ffb265..16677e4 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -27,6 +27,7 @@ import tempfile
from decimal import Decimal
# device backend modules
+from devicelibs import raid
from devicelibs import mdraid
from devicelibs import lvm
from devicelibs import dm
@@ -2353,18 +2354,26 @@ class LVMVolumeGroupDevice(ContainerDevice):
# the same name that we want to keep/use.
return
- lvm.vgreduce(self.name, [], rm=True)
+ lvm.vgreduce(self.name, None, rm=True)
lvm.vgdeactivate(self.name)
lvm.vgremove(self.name)
- def reduce(self, pv_list):
- """ Remove the listed PVs from the VG. """
- log_method_call(self, self.name, status=self.status)
- if not self.exists:
- raise DeviceError("device has not been created", self.name)
+ def _remove(self, member):
+ status = []
+ for lv in self.lvs:
+ status.append(lv.status)
+ if lv.exists:
+ lv.setup()
+
+ lvm.pvmove(member.path)
+ lvm.vgreduce(self.name, member.path)
- lvm.vgreduce(self.name, pv_list)
- # XXX do we need to notify the kernel?
+ for (lv, status) in zip(self.lvs, status):
+ if lv.status and not status:
+ lv.teardown()
+
+ def _add(self, member):
+ lvm.vgextend(self.name, member.path)
def _addLogVol(self, lv):
""" Add an LV to this VG. """
@@ -2408,6 +2417,9 @@ class LVMVolumeGroupDevice(ContainerDevice):
# XXX It would be nice to raise an exception if removing this member
# would not leave enough space, but the devicefactory relies on it
# being possible to _temporarily_ overcommit the VG.
+ #
+ # Maybe removeMember could be a wrapper with the checks and the
+ # devicefactory could call the _ versions to bypass the checks.
super(LVMVolumeGroupDevice, self)._removeMember(member)
# and update our pv count
@@ -3323,7 +3335,7 @@ class MDRaidArrayDevice(ContainerDevice):
if self.spares <= 0:
try:
- mdraid.mdadd(None, [member.path], incremental=True)
+ mdraid.mdadd(None, member.path, incremental=True)
# mdadd causes udev events
udev_settle()
except MDRaidError as e:
@@ -3373,6 +3385,19 @@ class MDRaidArrayDevice(ContainerDevice):
return status
+ def memberStatus(self, member):
+ if not (self.status and member.status):
+ return
+
+ member_name = os.path.basename(member.sysfsPath)
+ path = "/sys/%s/md/dev-%s/state" % (self.sysfsPath, member_name)
+ try:
+ state = open(path).read().strip()
+ except IOError:
+ state = None
+
+ return state
+
@property
def degraded(self):
""" Return True if the array is running in degraded mode. """
@@ -3477,7 +3502,7 @@ class MDRaidArrayDevice(ContainerDevice):
info = udev_get_block_device(self.sysfsPath)
self.uuid = udev_device_get_md_uuid(info)
for member in self.devices:
- member.mdUuid = self.uuid
+ member.format.mdUuid = self.uuid
def _create(self):
""" Create the device. """
@@ -3492,6 +3517,21 @@ class MDRaidArrayDevice(ContainerDevice):
bitmap=self.createBitmap)
udev_settle()
+ def _remove(self, member):
+ self.setup()
+ # see if the device must be marked as failed before it can be removed
+ fail = (self.memberStatus(member) == "in_sync")
+ mdraid.mdremove(self.path, member.path, fail=fail)
+
+ def _add(self, member):
+ self.setup()
+ if self.level.name == "raid0":
+ raid_devices = self.memberDevices
+ else:
+ raid_devices = None
+
+ mdraid.mdadd(self.path, member.path, raid_devices=raid_devices)
+
@property
def formatArgs(self):
formatArgs = []
@@ -4608,12 +4648,40 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
else:
self.format.volUUID = udev_device_get_uuid(info)
+ self.format.exists = True
+ self.originalFormat.exists = True
+
def _destroy(self):
log_method_call(self, self.name, status=self.status)
for device in self.parents:
device.setup(orig=True)
DeviceFormat(device=device.path, exists=True).destroy()
+ def _remove(self, member):
+ log_method_call(self, self.name, status=self.status)
+ try:
+ self._do_temp_mount(orig=True)
+ except FSError as e:
+ log.debug("btrfs temp mount failed: %s" % e)
+ raise
+
+ try:
+ btrfs.remove(self.originalFormat._mountpoint, member.path)
+ finally:
+ self._undo_temp_mount()
+
+ def _add(self, member):
+ try:
+ self._do_temp_mount(orig=True)
+ except FSError as e:
+ log.debug("btrfs temp mount failed: %s" % e)
+ raise
+
+ try:
+ btrfs.add(self.originalFormat._mountpoint, member.path)
+ finally:
+ self._undo_temp_mount()
+
def populateKSData(self, data):
super(BTRFSVolumeDevice, self).populateKSData(data)
data.dataLevel = self.dataLevel
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index 7b0807b..f1b9c43 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -1104,11 +1104,11 @@ class BTRFS(FS):
def create(self, *args, **kwargs):
# filesystem creation is done in storage.devicelibs.btrfs.create_volume
- pass
+ self.exists = True
def destroy(self, *args, **kwargs):
# filesystem creation is done in storage.devicelibs.btrfs.delete_volume
- pass
+ self.exists = False
def setup(self, *args, **kwargs):
""" Mount the filesystem.
--
1.8.5.3
More information about the anaconda-patches
mailing list