From 7f0358bd53916b4a8e3d59ff0e1f7488b7ca42d8 Mon Sep 17 00:00:00 2001 From: David Lehman Date: Wed, 18 Jul 2012 17:29:15 -0500 Subject: [PATCH 4/6] Add support for creating btrfs in the custom storage spoke. --- pyanaconda/ui/gui/spokes/custom.py | 85 ++++++++++++++++++++++++++++++++++-- 1 files changed, 81 insertions(+), 4 deletions(-) diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index 5932659..f66842f 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -51,6 +51,9 @@ from pyanaconda.ui.gui.categories.storage import StorageCategory from gi.repository import Gtk +import logging +log = logging.getLogger("anaconda") + __all__ = ["CustomPartitioningSpoke"] new_install_name = _("New %s %s Installation") % (productName, productVersion) @@ -455,25 +458,99 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): mountpoint in self.storage.mountpoints.keys(): return - if not size: + log.info("UI: create new %s %s" % (size, mountpoint)) + + # nothing in storage uses Size, so convert to float now + if size: + size = float(size.convertTo(spec="mb")) + else: # no size specified, so use the default size size = None - if self.data.autopart.type == AUTOPART_TYPE_PLAIN: + # swap can't be on btrfs. + # /boot* must be on partition or md + if (self.data.autopart.type == AUTOPART_TYPE_PLAIN or + (self.data.autopart.type == AUTOPART_TYPE_BTRFS and + fstype == "swap") or + (mountpoint and mountpoint.startswith("/boot"))): + log.info("UI: using a partition") # create a partition for this new filesystem - size_mb = float(size.convertTo(spec="mb")) - device = self.storage.newPartition(size=size_mb, + device = self.storage.newPartition(size=size, fmt_type=fstype, mountpoint=mountpoint) self.storage.createDevice(device) try: doPartitioning(self.storage) except StorageError as e: + log.error("UI: failed to allocate new partition: %s" % e) actions = self.storage.devicetree.findActions(device=device) for a in reversed(actions): self.storage.devicetree.cancelAction(a) else: self._do_refresh() + self._updateSpaceDisplay() + elif self.data.autopart.type == AUTOPART_TYPE_BTRFS: + log.info("UI: using a btrfs subvolume") + # see if we've already created a btrfs volume + container = None + for c in self.storage.btrfsVolumes: + if not c.exists: + container = c + break + + # XXX for now we are ignoring raid + + # if we have a container, we need to grow it + # figure out this device's space needs based on it and the container + if container: + log.debug("UI: found a btrfs volume with %d subvolumes" % len(container.subvolumes)) + new_size = container.size + size + # this is always rounding down + member_size = int(new_size / len(container.parents)) + log.debug("setting member device size to %d" % member_size) + for member in container.parents: + # btrfs members can only be partitions + # FIXME: grab the slave if the member is a DMCryptDevice + member.req_base_size = member_size + else: + log.debug("UI: going to create a btrfs volume") + # if we don't have a container we need to create member devices + # and then create the container itself + # figure out this devices's space needs + usable_disks = set(self.storage.disks) & set(self.storage.partitioned) + member_size = size / len(usable_disks) + members = [] + for disk in usable_disks: + member = self.storage.newPartition(parents=[disk], + size=member_size, + fmt_type="btrfs") + self.storage.createDevice(member) + members.append(member) + + try: + doPartitioning(self.storage) + except StorageError as e: + log.error("UI: failed to allocate new members: %s" % e) + for device in members: + actions = self.storage.devicetree.findActions(device=device) + for a in reversed(actions): + self.storage.devicetree.cancelAction(a) + # FIXME: revert container to its original state + return + + if not container: + log.debug("UI: creating new btrfs volume") + container = self.storage.newBTRFS(parents=members) + self.storage.createDevice(container) + + # add the new device to the container + log.debug("UI: creating new btrfs subvolume") + device = self.storage.newBTRFS(subvol=True, + parents=[container], + mountpoint=mountpoint) + self.storage.createDevice(device) + self._do_refresh() + self._updateSpaceDisplay() def _destroy_device(self, device): # if this device has parents with no other children, remove them too -- 1.7.7.6