Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow partitioning of md arrays whose members are all disks #138

Merged
merged 2 commits into from
Jun 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions blivet/devices/md.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ def __init__(self, name, level=None, major=None, minor=None, size=None,
: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

Expand Down Expand Up @@ -323,6 +336,13 @@ def _addParent(self, member):
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):
error_msg = self._validateParentRemoval(self.level, member)
if error_msg:
Expand Down Expand Up @@ -447,6 +467,10 @@ def teardown(self, recursive=None):
# see comment just above md_deactivate call
self._preTeardown(recursive=recursive)

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.
Expand Down Expand Up @@ -535,6 +559,14 @@ def formatArgs(self):
def model(self):
return self.description

@property
def partitionable(self):
return self.exists and all(p.partitionable for p in self.parents)

@property
def isDisk(self):
return self.exists and all(p.isDisk for p in self.parents)

def dracutSetupArgs(self):
return set(["rd.md.uuid=%s" % self.mdadmFormatUUID])

Expand Down
30 changes: 26 additions & 4 deletions blivet/populator.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,16 @@ def addUdevLoopDevice(self, info):
self.devicetree._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)
Expand Down Expand Up @@ -744,7 +753,7 @@ def addUdevDevice(self, info):

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

Expand Down Expand Up @@ -843,6 +852,12 @@ def handleUdevLUKSFormat(self, info, device):
else:
luks_device.updateSysfsPath()
self.devicetree._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)
Expand Down Expand Up @@ -1003,7 +1018,7 @@ def addLV(lv):
return

# do format handling now
self.addUdevDevice(lv_info)
self.addUdevDevice(lv_info, updateOrigFmt=True)

raid_items = dict((n.replace("[", "").replace("]", ""),
{"copies": 0, "log": Size(0), "meta": Size(0)})
Expand Down Expand Up @@ -1145,6 +1160,13 @@ def handleUdevMDMemberFormat(self, info, device):
md_array.updateSysfsPath()
md_array.parents.append(device)
self.devicetree._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
Expand Down Expand Up @@ -1451,7 +1473,7 @@ def setupDiskImages(self):
self.devicetree._addDevice(loopdev)
self.devicetree._addDevice(dmdev)
info = udev.get_device(dmdev.sysfsPath)
self.addUdevDevice(info)
self.addUdevDevice(info, updateOrigFmt=True)

def teardownDiskImages(self):
""" Tear down any disk image stacks. """
Expand Down