# # autopart.py - auto partitioning logic # # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Author(s): Jeremy Katz # import parted import copy import string, sys import fsset import lvm import logging from anaconda_log import logger, logFile import cryptodev import partedUtils import partRequests from constants import * from errors import * import iutil import isys log = logging.getLogger("anaconda") import gettext _ = lambda x: gettext.ldgettext("anaconda", x) PARTITION_FAIL = -1 PARTITION_SUCCESS = 0 BOOT_NOT_EXT2 = -1 BOOTEFI_NOT_VFAT = -2 BOOTALPHA_NOT_BSD = -3 BOOTALPHA_NO_RESERVED_SPACE = -4 BOOTIPSERIES_TOO_HIGH = -5 # check that our "boot" partitions meet necessary constraints unless # the request has its ignore flag set def bootRequestCheck(req, diskset): if not req.device or req.ignoreBootConstraints: return PARTITION_SUCCESS part = None if not hasattr(req, "drive"): return PARTITION_SUCCESS for drive in req.drive: part = diskset.disks[drive].getPartitionByPath("/dev/%s" % req.device) if not part: return PARTITION_SUCCESS if iutil.isEfi(): if req.mountpoint == "/boot": if not part.fileSystem.type.startswith("ext"): return BOOT_NOT_EXT2 elif req.mountpoint == "/boot/efi": if not part.fileSystem.type in ["fat16", "fat32"]: return BOOTEFI_NOT_VFAT elif iutil.isAlpha(): return bootAlphaCheckRequirements(part) elif (iutil.getPPCMachine() == "pSeries" or iutil.getPPCMachine() == "iSeries"): for drive in req.drive: part = diskset.disks[drive].getPartitionByPath("/dev/%s" % req.device) if part and ((part.geometry.end * part.geometry.device.sectorSize / (1024.0 * 1024)) > 4096): return BOOTIPSERIES_TOO_HIGH return PARTITION_SUCCESS # Alpha requires a BSD partition to boot. Since we can be called after: # # - We re-attached an existing /boot partition (existing dev.drive) # - We create a new one from a designated disk (no dev.drive) # - We auto-create a new one from a designated set of disks (dev.drive # is a list) # # it's simpler to get disk the partition belong to through dev.device # Some other tests pertaining to a partition where /boot resides are: # # - There has to be at least 1 MB free at the begining of the disk # (or so says the aboot manual.) def bootAlphaCheckRequirements(part): disk = part.disk # Disklabel check if not disk.type == "bsd": return BOOTALPHA_NOT_BSD # The first free space should start at the begining of the drive # and span for a megabyte or more. free = disk.getFirstPartition() while free: if free.type & parted.PARTITION_FREESPACE: break free = free.nextPartition() if (not free or free.geometry.start != 1L or free.getSize(unit="MB") < 1): return BOOTALPHA_NO_RESERVED_SPACE return PARTITION_SUCCESS def getMinimumSector(disk): if disk.type == 'sun': (cylinders, heads, sectors) = disk.device.biosGeometry start = long(sectors * heads) start /= long(1024 / disk.device.sectorSize) return start + 1 return 0L def getAutopartitionBoot(partitions): """Return the proper shorthand for the boot dir (arch dependent).""" fsname = fsset.fileSystemTypeGetDefaultBoot().getName() if iutil.isEfi(): ret = [ ["/boot/efi", "efi", 50, 200, 1, 1, 0] ] for req in partitions.requests: if req.fstype == fsset.fileSystemTypeGet("efi") \ and not req.mountpoint: req.mountpoint = "/boot/efi" ret = [] ret.append(("/boot", fsname, 200, None, 0, 1, 0)) return ret elif (iutil.getPPCMachine() == "pSeries"): return [ (None, "PPC PReP Boot", 4, None, 0, 1, 0), ("/boot", fsname, 200, None, 0, 1, 0) ] elif (iutil.getPPCMachine() == "iSeries") and not iutil.hasiSeriesNativeStorage(): return [ (None, "PPC PReP Boot", 16, None, 0, 1, 0) ] elif (iutil.getPPCMachine() == "iSeries") and iutil.hasiSeriesNativeStorage(): return [] elif (iutil.getPPCMachine() == "PMac") and iutil.getPPCMacGen() == "NewWorld": return [ ( None, "Apple Bootstrap", 1, 1, 0, 1, 0), ("/boot", fsname, 200, None, 0, 1, 0) ] else: return [ ("/boot", fsname, 200, None, 0, 1, 0) ]