We don't want to overwrite it if addUdevDevice was called a second time for a device we've already added, since that would cause us to lose the real original format.
(cherry picked from commit b3f28a2d1fcaeec768917ba6ef1b761423bc01d4) --- blivet/devicetree.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 915b94e..5318bea 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -1200,8 +1200,9 @@ class DeviceTree(object): # # The first step is to either look up or create the device # + device_added = True if device: - pass + device_added = False elif udev.device_is_loop(info): log.info("%s is a loop device", name) device = self.addUdevLoopDevice(info) @@ -1265,7 +1266,8 @@ class DeviceTree(object):
# now handle the device's formatting self.handleUdevDeviceFormat(info, device) - device.originalFormat = copy.copy(device.format) + if device_added: + device.originalFormat = copy.copy(device.format) device.deviceLinks = udev.device_get_symlinks(info)
def handleUdevDiskLabelFormat(self, info, device):
If we don't do it right away the device could be looked up successfully and cause confusion due to inaccurate(missing) format data.
This is only needed in the places where we add a new device from a format handler. The device additions from add*Device are not vulnerable to this issue.
(cherry picked from commit 1d3fc688b504b329d9f19da530f52da314fc2ff4)
Related: rhbz#1192004 --- blivet/devicetree.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 5318bea..73facfe 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -1127,7 +1127,16 @@ class DeviceTree(object): self._addDevice(device) return device
- def addUdevDevice(self, info): + def addUdevDevice(self, info, updateOrigFmt=False): + """ + :param :class:`pyudev.Device` info: udev info for the device + :keyword bool updateOrigFmt: update original format unconditionally + + If a device is added to the tree based on info its original format + will be saved after the format has been detected. If the device + that corresponds to info is already in the tree, its original format + will not be updated unless updateOrigFmt is True. + """ name = udev.device_get_name(info) log_method_call(self, name=name, info=pprint.pformat(dict(info))) uuid = udev.device_get_uuid(info) @@ -1266,7 +1275,7 @@ class DeviceTree(object):
# now handle the device's formatting self.handleUdevDeviceFormat(info, device) - if device_added: + if device_added or updateOrigFmt: device.originalFormat = copy.copy(device.format) device.deviceLinks = udev.device_get_symlinks(info)
@@ -1364,6 +1373,12 @@ class DeviceTree(object): else: luks_device.updateSysfsPath() self._addDevice(luks_device) + luks_info = udev.get_device(luks_device.sysfsPath) + if not luks_info: + log.error("failed to get udev data for %s", luks_device.name) + return + + self.addUdevDevice(luks_info, updateOrigFmt=True) else: log.warning("luks device %s already in the tree", device.format.mapName) @@ -1534,7 +1549,7 @@ class DeviceTree(object): return
# do format handling now - self.addUdevDevice(lv_info) + self.addUdevDevice(lv_info, updateOrigFmt=True)
raid = dict((n.replace("[", "").replace("]", ""), {"copies": 0, "log": Size(0), "meta": Size(0)}) @@ -1694,6 +1709,13 @@ class DeviceTree(object): md_array.updateSysfsPath() md_array.parents.append(device) self._addDevice(md_array) + if md_array.status: + array_info = udev.get_device(md_array.sysfsPath) + if not array_info: + log.error("failed to get udev data for %s", md_array.name) + return + + self.addUdevDevice(array_info, updateOrigFmt=True)
def handleUdevDMRaidMemberFormat(self, info, device): # if dmraid usage is disabled skip any dmraid set activation @@ -2098,7 +2120,7 @@ class DeviceTree(object): self._addDevice(loopdev) self._addDevice(dmdev) info = udev.get_device(dmdev.sysfsPath) - self.addUdevDevice(info) + self.addUdevDevice(info, updateOrigFmt=True)
def backupConfigs(self, restore=False): """ Create a backup copies of some storage config files. """
Similarly, if all members of an existing array are partitionable the array is also partitionable.
Resolves: rhbz#1197582 --- blivet/devices/md.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/blivet/devices/md.py b/blivet/devices/md.py index 096975a..2a3df0d 100644 --- a/blivet/devices/md.py +++ b/blivet/devices/md.py @@ -72,6 +72,19 @@ class MDRaidArrayDevice(ContainerDevice): :type metadataVersion: str (eg: "0.90") :keyword minor: the device minor (obsolete?) :type minor: int + + .. note:: + + An instance of this class whose :attr:`exists` attribute is + True and whose parent/member devices are all partitionable is + also considered to be partitionable. + + .. note:: + + An instance of this class whose :attr:`exists` attribute is + True and whose parent/member devices are all disks is also + treated like a disk. + """ # pylint: disable=unused-argument
@@ -337,6 +350,13 @@ class MDRaidArrayDevice(ContainerDevice): self._totalDevices += 1 self.memberDevices += 1
+ # The new member hasn't been added yet, so account for it explicitly. + is_disk = self.isDisk and member.isDisk + for p in self.parents: + p.format._hidden = is_disk + + member.format._hidden = is_disk + def _removeParent(self, member): """ If this is a raid array that is not actually redundant and it appears to have formatting and therefore probably data on it, @@ -478,6 +498,10 @@ class MDRaidArrayDevice(ContainerDevice): if self.type == "mdcontainer" or self.type == "mdbiosraidarray": return
+ if self.isDisk: + # treat arrays whose members are disks as partitionable disks + return + # We don't really care what the array's state is. If the device # file exists, we want to deactivate it. mdraid has too many # states. @@ -567,11 +591,13 @@ class MDRaidArrayDevice(ContainerDevice):
@property def partitionable(self): - return self.type == "mdbiosraidarray" + return (self.type == "mdbiosraidarray" or + (self.exists and all(p.partitionable for p in self.parents)))
@property def isDisk(self): - return self.type == "mdbiosraidarray" + return (self.type == "mdbiosraidarray" or + (self.exists and all(p.isDisk for p in self.parents)))
def dracutSetupArgs(self): return set(["rd.md.uuid=%s" % self.mdadmFormatUUID])
anaconda-patches@lists.fedorahosted.org