FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian Development

 
 
LinkBack Thread Tools
 
Old 12-13-2011, 09:58 PM
David Lehman
 
Default Add support for btrfs to the devicetree.

Adds support for scanning existing btrfs, including subvolumes.

Also adds an optional arg to getDeviceByPath to accommodate the fact
that btrfs volumes don't have a separate device node to represent the
top-level volume.

btrfs format.uuid is the member device's UUID (ID_FS_UUID_SUB),
while format.volUUID (ID_FS_UUID) is the top-level volume's UUID.
This prevents some further madness in which multiple devices would
have the same UUID.
---
pyanaconda/storage/devices.py | 15 ++++---
pyanaconda/storage/devicetree.py | 80 ++++++++++++++++++++++++++++++------
pyanaconda/storage/formats/fs.py | 2 +-
pyanaconda/storage/partitioning.py | 4 +-
4 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
index de78602..0e641f3 100644
--- a/pyanaconda/storage/devices.py
+++ b/pyanaconda/storage/devices.py
@@ -3941,18 +3941,21 @@ class BTRFSVolumeDevice(BTRFSDevice):
self.subvolumes = []

for parent in self.parents:
+ if parent.format.type != "btrfs":
+ raise ValueError("member device %s is not BTRFS" % parent.name)
+
if parent.format.exists and self.exists and
- parent.format.uuid != self.uuid:
+ parent.format.volUUID != self.uuid:
raise ValueError("BTRFS member device %s UUID %s does not "
"match volume UUID %s" % (parent.name,
- parent.format.uuid,
- self.uuid))
+ parent.format.volUUID, self.uuid))

if self.parents and not self.format.type:
label = getattr(self.parents[0].format, "label", None)
- self.format = getFormat("btrfs", exists=self.exists,
+ self.format = getFormat("btrfs",
+ exists=self.exists,
label=label,
- uuid=self.uuid,
+ volUUID=self.uuid,
device=self.path)

label = getattr(self.format, "label", None)
@@ -3980,7 +3983,7 @@ class BTRFSVolumeDevice(BTRFSDevice):
if device.format.type != "btrfs":
raise ValueError("addDevice requires a btrfs device as sole arg")

- if device.format.uuid != self.uuid:
+ if device.format.volUUID != self.uuid:
raise ValueError("device UUID does not match the volume UUID")

if device in self.parents:
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py
index fb40cf6..f4ac54c 100644
--- a/pyanaconda/storage/devicetree.py
+++ b/pyanaconda/storage/devicetree.py
@@ -336,7 +336,7 @@ class DeviceTree(object):
Raise ValueError if the device's identifier is already
in the list.
"""
- if newdev.path in [d.path for d in self._devices] and
+ if newdev.uuid and newdev.uuid in [d.uuid for d in self._devices] and
not isinstance(newdev, NoDevice):
raise ValueError("device is already in tree")

@@ -1558,6 +1558,42 @@ class DeviceTree(object):
#device.format.raidmem = block.getMemFromRaidSet(dm_array,
# major=major, minor=minor, uuid=uuid, name=name)

+ def handleBTRFSFormat(self, info, device):
+ log_method_call(self, name=device.name)
+ name = udev_device_get_name(info)
+ sysfs_path = udev_device_get_sysfs_path(info)
+ uuid = udev_device_get_uuid(info)
+
+ btrfs_dev = None
+ for d in self.devices:
+ if isinstance(d, BTRFSVolumeDevice) and d.uuid == uuid:
+ btrfs_dev = d
+ break
+
+ if btrfs_dev:
+ log.info("found btrfs volume %s" % btrfs_dev.name)
+ btrfs_dev._addDevice(device)
+ else:
+ label = udev_device_get_label(info)
+ log.info("creating btrfs volume btrfs.%s" % label)
+ btrfs_dev = BTRFSVolumeDevice(label, parents=[device], uuid=uuid,
+ exists=True)
+ self._addDevice(btrfs_dev)
+
+ if not btrfs_dev.subvolumes:
+ for subvol_dict in btrfs_dev.listSubVolumes():
+ vol_id = subvol_dict["id"]
+ vol_path = subvol_dict["path"]
+ if vol_path in [sv.name for sv in btrfs_dev.subvolumes]:
+ continue
+ fmt = getFormat("btrfs", device=btrfs_dev.path, exists=True,
+ mountopts="subvol=%d" % vol_id)
+ subvol = BTRFSSubVolumeDevice(vol_path,
+ vol_id=vol_id,
+ format=fmt,
+ parents=[btrfs_dev])
+ self._addDevice(subvol)
+
def handleUdevDeviceFormat(self, info, device):
log_method_call(self, name=getattr(device, "name", None))
name = udev_device_get_name(info)
@@ -1636,6 +1672,11 @@ class DeviceTree(object):
apple = formats.getFormat("appleboot")
if apple.minSize <= device.size <= apple.maxSize:
args[0] = "appleboot"
+ elif format_type == "btrfs":
+ # the format's uuid attr will contain the UUID_SUB, while the
+ # overarching volume UUID will be stored as volUUID
+ kwargs["uuid"] = info["ID_FS_UUID_SUB"]
+ kwargs["volUUID"] = uuid

try:
log.info("type detected on '%s' is '%s'" % (name, format_type,))
@@ -1665,6 +1706,8 @@ class DeviceTree(object):
self.handleUdevLVMPVFormat(info, device)
elif device.format.type == "multipath_member":
self.handleMultipathMemberFormat(info, device)
+ elif device.format.type == "btrfs":
+ self.handleBTRFSFormat(info, device)

def updateDeviceFormat(self, device):
log.info("updating format of device: %s" % device)
@@ -2051,21 +2094,30 @@ class DeviceTree(object):
log_method_return(self, found)
return found

- def getDeviceByPath(self, path):
+ def getDeviceByPath(self, path, preferLeaves=True):
log_method_call(self, path=path)
if not path:
log_method_return(self, None)
return None

- found = None
+ leaf = None
+ other = None
for device in self._devices:
- if device.path == path:
- found = device
- break
- elif (device.type == "lvmlv" or device.type == "lvmvg") and
- device.path == path.replace("--","-"):
- found = device
- break
+ if (device.path == path or
+ ((device.type == "lvmlv" or device.type == "lvmvg") and
+ device.path == path.replace("--","-"))):
+ if device.isleaf and not leaf:
+ leaf = device
+ elif not other:
+ other = device
+
+ if preferLeaves:
+ all_devs = [leaf, other]
+ else:
+ all_devs = [other, leaf]
+ all_devs = [d for d in all_devs if d]
+ if all_devs:
+ found = all_devs[0]

log_method_return(self, found)
return found
@@ -2082,9 +2134,9 @@ class DeviceTree(object):
""" List of device instances """
devices = []
for device in self._devices:
- if device.path in [d.path for d in devices] and
+ if device.uuid and device.uuid in [d.uuid for d in devices] and
not isinstance(device, NoDevice):
- raise DeviceTreeError("duplicate paths in device tree")
+ raise DeviceTreeError("duplicate uuids in device tree")

devices.append(device)

@@ -2132,7 +2184,9 @@ class DeviceTree(object):
"""
labels = {}
for dev in self._devices:
- if dev.format and getattr(dev.format, "label", None):
+ # don't include btrfs member devices
+ if getattr(dev.format, "label", None) and
+ (dev.format.type != "btrfs" or isinstance(dev, BTRFSDevice)):
labels[dev.format.label] = dev

return labels
diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py
index 3c3229f..0942402 100644
--- a/pyanaconda/storage/formats/fs.py
+++ b/pyanaconda/storage/formats/fs.py
@@ -1140,8 +1140,8 @@ class BTRFS(FS):
# partedSystem = fileSystemType["btrfs"]

def __init__(self, *args, **kwargs):
- self.uuidSub = kwargs.pop("uuidSub", None)
super(BTRFS, self).__init__(*args, **kwargs)
+ self.volUUID = kwargs.pop("volUUID", None)

def create(self, *args, **kwargs):
# filesystem creation is done in storage.devicelibs.btrfs.create_volume
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
index 4a80a8b..8669c82 100644
--- a/pyanaconda/storage/partitioning.py
+++ b/pyanaconda/storage/partitioning.py
@@ -261,8 +261,8 @@ def _scheduleVolumes(storage, devs):
def scheduleShrinkActions(storage):
""" Schedule actions to shrink partitions as per autopart selection. """
for (path, size) in storage.shrinkPartitions.items():
- device = storage.devicetree.getDeviceByPath(path)
- if not device:
+ device = storage.devicetree.getDeviceByPath(path, preferLeaves=False)
+ if not device or not isinstance(device, PartitionDevice):
raise StorageError("device %s scheduled for shrink disappeared"
% path)
storage.devicetree.registerAction(ActionResizeForm at(device, size))
--
1.7.3.4

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 06:16 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org