Hello, i am currently trying to install a VMware ESX from within a recovery partition on a harddisk on which i want to install the ESX too. I am getting an error message some time after anaconda starts: "/tmp/anaconda_build//usr/lib/anaconda/partitions.py", line 95, in setProtected AttributeError: 'NoneType' object has no attribute 'setProtected' I found a thread (http://communities.vmware.com/thread/75792) in the VMware forum which describes my problem (look for "UPDATE: Fix for "BUG" in Anaconda installer script"). The files linked in the thread aren´t available anymore. So i tried to find the code myself and change it, but my python is very bad. So i came up here and asks you for help. Can anyone send me a patch for the partitions.py script attached which doesn´t protect the disk on which the sources reside? I know this is likely to be found with google, but i think i ask it anyway. How can i compile the attached script? Kind regards, Timo *_ _*
#
# partitions.py: partition object containing partitioning info
#
# Matt Wilson <msw redhat com>
# Jeremy Katz <katzj redhat com>
# Mike Fulbright <msf redhat com>
# Harald Hoyer <harald redhat de>
#
# Copyright 2002 Red Hat, Inc.
#
# This software may be freely redistributed under the terms of the GNU
# library public license.
#
# You should have received a copy of the GNU Library Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
"""Overarching partition object."""
import parted
import iutil
import isys
import string
import types
import os, sys
from constants import *
import fsset
import raid
import lvm
import partedUtils
import partRequests
from rhpl.translate import _
from rhpl.log import log
class Partitions:
"""Defines all of the partition requests and delete requests."""
def __init__ (self, diskset = None):
"""Initializes a Partitions object.
Can pass in the diskset if it already exists.
"""
self.requests = []
"""A list of RequestSpec objects for all partitions."""
self.deletes = []
"""A list of DeleteSpec objects for partitions to be deleted."""
self.autoPartitionRequests = []
"""A list of RequestSpec objects for autopartitioning.
These are setup by the installclass and folded into self.requests
by auto partitioning."""
self.filteredPartitionRequests = []
"""A list of RequestSpec objects filtered out of autopartitioning.
This consists of VMFS partitions which were excluded due to a
CLEARPART_TYPE_NOTVMFS."""
self.autoClearPartType = CLEARPART_TYPE_NONE
"""What type of partitions should be cleared?"""
self.autoClearPartDrives = None
"""Drives to clear partitions on (note that None is equiv to all)."""
self.nextUniqueID = 1
"""Internal counter. Don't touch unless you're smarter than me."""
self.reinitializeDisks = 0
"""Should the disk label be reset on all disks?"""
self.zeroMbr = 0
"""Should the mbr be zero'd?"""
# partition method to be used. not to be touched externally
self.useAutopartitioning = 1
self.useFdisk = 0
# autopartitioning info becomes kickstart partition requests
# and its useful to be able to differentiate between the two
self.isKickstart = 0
if diskset:
self.setFromDisk(diskset)
def setFromDisk(self, diskset):
"""Clear the delete list and set self.requests to reflect disk."""
self.deletes = []
self.requests = []
diskset.refreshDevices()
labels = diskset.getLabels()
drives = diskset.disks.keys()
drives.sort()
for drive in drives:
disk = diskset.disks[drive]
part = disk.next_partition()
while part:
if part.type & parted.PARTITION_METADATA:
part = disk.next_partition(part)
continue
format = None
if part.type & parted.PARTITION_FREESPACE:
ptype = None
elif part.type & parted.PARTITION_EXTENDED:
ptype = None
elif part.get_flag(parted.PARTITION_RAID) == 1:
ptype = fsset.fileSystemTypeGet("software RAID")
elif part.get_flag(parted.PARTITION_LVM) == 1:
ptype = fsset.fileSystemTypeGet("physical volume (LVM)")
else:
ptype = partedUtils.get_partition_file_system_type(part)
# FIXME: we don't handle ptype being None very well, so
# just say it's foreign. Should probably fix None handling
# instead some day.
if ptype is None:
ptype = fsset.fileSystemTypeGet("foreign")
start = part.geom.start
end = part.geom.end
size = partedUtils.getPartSizeMB(part)
drive = partedUtils.get_partition_drive(part)
spec = partRequests.PreexistingPartitionSpec(ptype,
size = size,
start = start,
end = end,
drive = drive,
format = format)
spec.device = fsset.PartedPartitionDevice(part).getDevice()
# set label if makes sense
if ptype and ptype.isMountable() and \
(ptype.getName() == "ext2" or ptype.getName() == "ext3"):
if spec.device in labels.keys():
if labels[spec.device] and len(labels[spec.device])>0:
spec.fslabel = labels[spec.device]
self.addRequest(spec)
part = disk.next_partition(part)
# now we need to read in all pre-existing RAID stuff
diskset.startAllRaid()
mdList = diskset.mdList
for raidDev in mdList:
(theDev, devices, level, numActive) = raidDev
level = "RAID%s" %(level,)
# is minor always mdN ?
minor = int(theDev[2:])
raidvols = []
for dev in devices:
req = self.getRequestByDeviceName(dev)
if not req:
log("RAID device %s using non-existent partition %s"
%(theDev, dev))
continue
raidvols.append(req.uniqueID)
fs = partedUtils.sniffFilesystemType(theDev)
if fs is None:
fsystem = fsset.fileSystemTypeGet("foreign")
else:
fsystem = fsset.fileSystemTypeGet(fs)
if fs == "swap":
mnt = None
# more forced swap format hacking
format = 1
else:
mnt = None
format = 0
spares = len(devices) - numActive
spec = partRequests.RaidRequestSpec(fsystem, format = format,
raidlevel = level,
raidmembers = raidvols,
raidminor = minor,
raidspares = spares,
mountpoint = mnt,
preexist = 1)
spec.size = spec.getActualSize(self, diskset)
self.addRequest(spec)
# now to read in pre-existing LVM stuff
lvm.vgscan()
lvm.vgactivate()
vgs = []
if os.path.isdir("/proc/lvm/VGs"):
vgs = os.listdir("/proc/lvm/VGs")
for vg in vgs:
# first find the PE size
f = open("/proc/lvm/VGs/%s/group" %(vg,), "r")
lines = f.readlines()
f.close()
pesize = 0
preexist_size = None
for line in lines:
fields = line.split(':',1)
if len(fields) < 2:
continue
if fields[0].strip() == "PE size":
pesize = fields[1].strip()
try:
pesize = int(pesize)
except:
log("PE size for %s not a valid integer, defaulting to 4096" %(vg,))
pesize = 4096
elif fields[0].strip() == "size":
preexist_size = fields[1].strip()
try:
preexist_size = int(preexist_size) / 1024.0
except:
log("preexisting size for %s not a valid integer, ignoring" %(vg,))
preexist_size = None
if not pesize:
log("Unable to find PE size for %s, defaulting to 4096" %(vg,))
pesize = 4096
# Now find the physical volumes associated with this VG
if not os.path.isdir("/proc/lvm/VGs/%s/PVs" % (vg,)):
log("Unable to find PVs for %s" % (vg,))
continue
pvs = os.listdir("/proc/lvm/VGs/%s/PVs/" % (vg,))
pvids = []
for pv in pvs:
# XXX I hate the lvm code. it puts cciss_c0d0p2 for
# things like cciss/c0d0p2 so we need to substitute. ick.
pv = pv.replace("_", "/")
req = self.getRequestByDeviceName(pv)
if not req:
log("Volume group %s using non-existent partition %s"
%(vg, pv))
continue
pvids.append(req.uniqueID)
spec = partRequests.VolumeGroupRequestSpec(format = 0,
vgname = vg,
physvols = pvids,
pesize = pesize,
preexist = 1,
preexist_size = preexist_size)
vgid = self.addRequest(spec)
# now we need to find out about the logical volumes
if not os.path.isdir("/proc/lvm/VGs/%s/LVs" %(vg,)):
log("Unable to find LVs for %s" % (vg,))
continue
lvs = os.listdir("/proc/lvm/VGs/%s/LVs" % (vg,))
for lv in lvs:
f = open("/proc/lvm/VGs/%s/LVs/%s" % (vg,lv), "r")
lines = f.readlines()
f.close()
lvsize = None
for line in lines:
fields = line.split(':',1)
if len(fields) < 2:
continue
if fields[0].strip() == "size":
lvsize = fields[1].strip()
if lvsize is None:
log("Unable to find LV size for %s/%s" % (vg, lv))
continue
# size is listed as number of blocks, we want size in megs
lvsize = int(lvsize) / 2048.0
theDev = "/dev/%s/%s" %(vg, lv)
fs = partedUtils.sniffFilesystemType(theDev)
if fs is None:
fsystem = fsset.fileSystemTypeGet("foreign")
else:
fsystem = fsset.fileSystemTypeGet(fs)
if fs == "swap":
mnt = None
format = 1
else:
mnt = None
format = 0
spec = partRequests.LogicalVolumeRequestSpec(fsystem,
format = format,
size = lvsize,
volgroup = vgid,
lvname = lv,
mountpoint = mnt,
preexist = 1)
self.addRequest(spec)
lvm.vgdeactivate()
diskset.stopAllRaid()
def addRequest (self, request):
"""Add a new request to the list."""
if not request.uniqueID:
request.uniqueID = self.nextUniqueID
self.nextUniqueID = self.nextUniqueID + 1
self.requests.append(request)
self.requests.sort()
return request.uniqueID
def addDelete (self, delete):
"""Add a new DeleteSpec to the list."""
self.deletes.append(delete)
self.deletes.sort()
def removeRequest (self, request):
"""Remove a request from the list."""
self.requests.remove(request)
def getRequestByFslabel(self, mount):
"""Find and return the request with the given fslabel."""
for request in self.requests:
if request.fslabel == mount:
return request
def getRequestByMountPoint(self, mount):
"""Find and return the request with the given mountpoint."""
for request in self.requests:
if request.mountpoint == mount:
return request
for request in self.requests:
if request.type == REQUEST_LV and request.mountpoint == mount:
return request
return None
def findRequestByPath(self, path):
"""Find the request for the partition which will contain 'path'."""
match = self.getRequestByMountPoint(path)
while not match:
oldpath = path
path = os.path.split(path)[0]
# This will never happen, but prevent loops anyway.
if oldpath == path:
return None
match = self.getRequestByMountPoint(path)
return match
def getRequestByDeviceName(self, device):
"""Find and return the request with the given device name."""
if device is None:
return None
for request in self.requests:
if request.type == REQUEST_RAID and request.raidminor is not None:
tmp = "md%d" % (request.raidminor,)
if tmp == device:
return request
elif request.device == device:
return request
return None
def getRequestsByDevice(self, diskset, device):
"""Find and return the requests on a given device (like 'hda')."""
if device is None:
return None
drives = diskset.disks.keys()
if device not in drives:
return None
rc = []
disk = diskset.disks[device]
part = disk.next_partition()
while part:
dev = partedUtils.get_partition_name(part)
request = self.getRequestByDeviceName(dev)
if request:
rc.append(request)
part = disk.next_partition(part)
if len(rc) > 0:
return rc
else:
return None
def getRequestByVolumeGroupName(self, volname):
"""Find and return the request with the given volume group name."""
if volname is None:
return None
for request in self.requests:
if (request.type == REQUEST_VG and
request.volumeGroupName == volname):
return request
return None
def getRequestByLogicalVolumeName(self, lvname):
"""Find and return the request with the given logical volume name."""
if lvname is None:
return None
for request in self.requests:
if (request.type == REQUEST_LV and
request.logicalVolumeName == lvname):
return request
return None
def getRequestByID(self, id):
"""Find and return the request with the given unique ID.
Note that if id is a string, it will be converted to an int for you.
"""
if type(id) == type("a string"):
id = int(id)
for request in self.requests:
if request.uniqueID == id:
return request
return None
def getBootDrive(self, upgrade=0, upgradeRoot=None):
driveReq = None
bootDrive = None
if upgrade and upgradeRoot:
(rootDisk, part) = fsset.getDiskPart(upgradeRoot[0][0])
return rootDisk
for mnt in '/boot', '/':
if self.getRequestByMountPoint(mnt) and \
self.getRequestByMountPoint(mnt).drive:
driveReq = self.getRequestByMountPoint(mnt).drive
break
if driveReq:
if type(driveReq) == types.StringType:
bootDrive = driveReq
elif type(driveReq) == types.ListType:
bootDrive = driveReq[0]
return bootDrive
def getRaidRequests(self):
"""Find and return a list of all of the RAID requests."""
retval = []
for request in self.requests:
if request.type == REQUEST_RAID:
retval.append(request)
return retval
def getRaidDevices(self):
"""Find and return a list of all of the requests for use in RAID."""
raidRequests = []
for request in self.requests:
if isinstance(request, partRequests.RaidRequestSpec):
raidRequests.append(request)
return raidRequests
def getAvailableRaidMinors(self):
"""Find and return a list of all of the unused minors for use in RAID."""
raidMinors = range(0,32)
for request in self.requests:
if isinstance(request, partRequests.RaidRequestSpec):
raidMinors.remove(request.raidminor)
return raidMinors
def getAvailRaidPartitions(self, request, diskset):
"""Return a list of tuples of RAID partitions which can be used.
Return value is (part, size, used) where used is 0 if not,
1 if so, 2 if used for *this* request.
"""
rc = []
drives = diskset.disks.keys()
raiddevs = self.getRaidDevices()
drives.sort()
for drive in drives:
disk = diskset.disks[drive]
for part in partedUtils.get_raid_partitions(disk):
partname = partedUtils.get_partition_name(part)
used = 0
for raid in raiddevs:
if raid.raidmembers:
for raidmem in raid.raidmembers:
tmpreq = self.getRequestByID(raidmem)
if (partname == tmpreq.device):
if raid.uniqueID == request.uniqueID:
used = 2
else:
used = 1
break
if used:
break
size = partedUtils.getPartSizeMB(part)
if not used:
rc.append((partname, size, 0))
elif used == 2:
rc.append((partname, size, 1))
return rc
def getRaidMemberParent(self, request):
"""Return RAID device request containing this request."""
raiddev = self.getRaidRequests()
if not raiddev or not request.device:
return None
for dev in raiddev:
if not dev.raidmembers:
continue
for member in dev.raidmembers:
if request.device == self.getRequestByID(member).device:
return dev
return None
def isRaidMember(self, request):
"""Return whether or not the request is being used in a RAID device."""
if self.getRaidMemberParent(request) is not None:
return 1
else:
return 0
def getLVMLVForVGID(self, vgid):
"""Find and return a list of all the LVs associated with a VG id."""
retval = []
for request in self.requests:
if request.type == REQUEST_LV:
if request.volumeGroup == vgid:
retval.append(request)
return retval
def getLVMLVForVG(self, vgrequest):
"""Find and return a list of all of the LVs in the VG."""
vgid = vgrequest.uniqueID
return self.getLVMLVForVGID(vgid)
def getLVMRequests(self):
"""Return a dictionary of all of the LVM bits.
The dictionary returned is of the form vgname: [ lvrequests ]
"""
retval = {}
for request in self.requests:
if request.type == REQUEST_VG:
retval[request.volumeGroupName] = self.getLVMLVForVG(request)
return retval
def getLVMVGRequests(self):
"""Find and return a list of all of the volume groups."""
retval = []
for request in self.requests:
if request.type == REQUEST_VG:
retval.append(request)
return retval
def getLVMLVRequests(self):
"""Find and return a list of all of the logical volumes."""
retval = []
for request in self.requests:
if request.type == REQUEST_LV:
retval.append(request)
return retval
def getAvailLVMPartitions(self, request, diskset):
"""Return a list of tuples of PV partitions which can be used.
Return value is (part, size, used) where used is 0 if not,
1 if so, 2 if used for *this* request.
"""
rc = []
drives = diskset.disks.keys()
drives.sort()
volgroups = self.getLVMVGRequests()
for drive in drives:
disk = diskset.disks[drive]
for part in partedUtils.get_lvm_partitions(disk):
partname = partedUtils.get_partition_name(part)
partrequest = self.getRequestByDeviceName(partname)
used = 0
for volgroup in volgroups:
if volgroup.physicalVolumes:
if partrequest.uniqueID in volgroup.physicalVolumes:
if (request and request.uniqueID and
volgroup.uniqueID == request.uniqueID):
used = 2
else:
used = 1
if used:
break
size = partedUtils.getPartSizeMB(part)
if used == 0:
rc.append((partrequest.uniqueID, size, 0))
elif used == 2:
rc.append((partrequest.uniqueID, size, 1))
# now find available RAID devices
raiddev = self.getRaidRequests()
if raiddev:
raidcounter = 0
for dev in raiddev:
used = 0
if dev.fstype is None:
continue
if dev.fstype.getName() != "physical volume (LVM)":
continue
for volgroup in volgroups:
if volgroup.physicalVolumes:
if dev.uniqueID in volgroup.physicalVolumes:
if (request and request.uniqueID and
volgroup.uniqueID == request.uniqueID):
used = 2
else:
used = 1
if used:
break
size = dev.getActualSize(self, diskset)
if used == 0:
rc.append((dev.uniqueID, size, 0))
elif used == 2:
rc.append((dev.uniqueID, size, 1))
raidcounter = raidcounter + 1
return rc
def getLVMVolumeGroupMemberParent(self, request):
"""Return parent volume group of a physical volume"""
volgroups = self.getLVMVGRequests()
if not volgroups:
return None
for volgroup in volgroups:
if volgroup.physicalVolumes:
if request.uniqueID in volgroup.physicalVolumes:
return volgroup
return None
def isLVMVolumeGroupMember(self, request):
"""Return whether or not the request is being used in an LVM device."""
if self.getLVMVolumeGroupMemberParent(request) is None:
return 0
else:
return 1
def isVolumeGroupNameInUse(self, vgname):
"""Return whether or not the requested volume group name is in use."""
if not vgname:
return None
lvmrequests = self.getLVMRequests()
if not lvmrequests:
return None
if vgname in lvmrequests.keys():
return 1
return 0
def getBootableRequest(self):
"""Return the name of the current 'boot' mount point."""
bootreq = None
if iutil.getArch() == "ia64":
bootreq = self.getRequestByMountPoint("/boot/efi")
if bootreq:
return [ bootreq ]
else:
return None
elif iutil.getPPCMachine() == "iSeries":
for req in self.requests:
if req.fstype == fsset.fileSystemTypeGet("PPC PReP Boot"):
return [ req ]
return None
elif iutil.getPPCMachine() == "pSeries":
# pSeries bootable requests are odd.
# have to consider both the PReP partition (with potentially > 1
# existing) as well as /boot,/
# for the prep partition, we want either the first or the
# first non-preexisting one
bestprep = None
for req in self.requests:
if req.fstype == fsset.fileSystemTypeGet("PPC PReP Boot"):
if ((bestprep is None) or
(bestprep.getPreExisting() and
not req.getPreExisting())):
bestprep = req
if bestprep:
ret = [ bestprep ]
else:
ret = []
# now add the /boot
bootreq = self.getRequestByMountPoint("/boot")
if not bootreq:
bootreq = self.getRequestByMountPoint("/")
if bootreq:
ret.append(bootreq)
if len(ret) >= 1:
return ret
return None
if not bootreq:
bootreq = self.getRequestByMountPoint("/boot")
if not bootreq:
bootreq = self.getRequestByMountPoint("/")
if bootreq:
return [ bootreq ]
return None
def getBootableMountpoints(self):
"""Return a list of bootable valid mountpoints for this arch."""
# FIXME: should be somewhere else, preferably some sort of arch object
if iutil.getArch() == "ia64":
return [ "/boot/efi" ]
else:
return [ "/boot", "/" ]
def isBootable(self, request):
"""Returns if the request should be considered a 'bootable' request.
This basically means that it should be sorted to the beginning of
the drive to avoid cylinder problems in most cases.
"""
bootreqs = self.getBootableRequest()
if not bootreqs:
return 0
for bootreq in bootreqs:
if bootreq == request:
return 1
if bootreq.type == REQUEST_RAID and \
request.uniqueID in bootreq.raidmembers:
return 1
return 0
def sortRequests(self):
"""Resort the requests into allocation order."""
self.requests.sort()
tmp = self.getBootableRequest()
boot = []
if tmp:
for req in tmp:
# if raid, we want all of the contents of the bootable raid
if req.type == REQUEST_RAID:
for member in req.raidmembers:
boot.append(self.getRequestByID(member))
else:
boot.append(req)
# remove the bootables from the request
for bootable in boot:
self.requests.pop(self.requests.index(bootable))
# move to the front of the list
boot.extend(self.requests)
# vmkcore should be at the end of the disk
vmkcoreRequests = []
finalRequests = []
for request in boot:
if request.fstype and request.fstype.getName() == 'vmkcore':
vmkcoreRequests.append(request)
else:
finalRequests.append(request)
finalRequests.extend(vmkcoreRequests)
self.requests = finalRequests
def sanityCheckAllRequests(self, diskset, baseChecks = 0):
"""Do a sanity check of all of the requests.
This function is called at the end of partitioning so that we
can make sure you don't have anything silly (like no /, a really
small /, etc). Returns (errors, warnings) where each is a list
of strings or None if there are none.
If baseChecks is set, the basic sanity tests which the UI runs prior to
accepting a partition will be run on the requests as well.
"""
checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 500),
('/home', 100), ('/boot', 90), ('/var/log', 500)]
warnings = []
errors = []
slash = self.getRequestByMountPoint('/')
if not slash:
errors.append(_("You have not defined a root partition (/), "
"which is required for installation of %s "
"to continue.") % (productName,))
# pad this check a little
if slash and slash.getActualSize(self, diskset) < 1797:
warnings.append(_("Your root partition is less than 1.8 "
"gigabytes which is smaller than the minimum "
"recommended root partition size for %s.") %
(productName,))
# Check to see if /var/log and / are on the same file system. If so,
# present a warning. This ensures that filling up /var/log does not
# prevent writing to the / file system.
varlog = self.findRequestByPath('/var/log')
if varlog and varlog == slash:
warnings.append(_("/var/log is on the same partition as the root "
"partition (/). It is recommended to create a "
"separate /var/log or /var partition."))
if iutil.getArch() == "ia64":
bootreq = self.getRequestByMountPoint("/boot/efi")
if not bootreq or bootreq.getActualSize(self, diskset) < 50:
errors.append(_("You must create a /boot/efi partition of "
"type FAT and a size of 50 megabytes."))
if (iutil.getPPCMachine() == "pSeries" or
iutil.getPPCMachine() == "iSeries"):
reqs = self.getBootableRequest()
found = 0
if reqs:
for req in reqs:
if req.fstype == fsset.fileSystemTypeGet("PPC PReP Boot"):
found = 1
break
if iutil.getPPCMachine() == "iSeries" and iutil.hasIbmSis():
found = 1
if not found:
errors.append(_("You must create a PPC PReP Boot partition."))
for (path, size) in checkSizes:
req = self.findRequestByPath(path)
if not req:
continue
if req.getActualSize(self, diskset) < size:
warnings.append(_("Your %s partition is less than %s "
"megabytes which is lower than recommended "
"for a normal %s install.")
%(path, size, productName))
foundSwap = 0
swapSize = 0
for request in self.requests:
rc = request.sanityCheckDriveForVmfs()
if rc:
errors.append(rc)
if request.fstype and request.fstype.getName() == "swap" and \
request.format:
foundSwap = foundSwap + 1
swapSize = swapSize + request.getActualSize(self, diskset)
if baseChecks:
rc = request.doSizeSanityCheck()
if rc:
warnings.append(rc)
rc = request.doMountPointLinuxFSChecks()
if rc:
errors.append(rc)
if isinstance(request, partRequests.RaidRequestSpec):
rc = request.sanityCheckRaid(self)
if rc:
errors.append(rc)
bootreqs = self.getBootableRequest()
if bootreqs:
for bootreq in bootreqs:
if (bootreq and
(isinstance(bootreq, partRequests.RaidRequestSpec)) and
(not raid.isRaid1(bootreq.raidlevel))):
errors.append(_("Bootable partitions can only be on RAID1 "
"devices."))
# can't have bootable partition on LV
if (bootreq and
(isinstance(bootreq,
partRequests.LogicalVolumeRequestSpec))):
errors.append(_("Bootable partitions cannot be on a "
"logical volume."))
# most arches can't have boot on RAID
if (bootreq and
(isinstance(bootreq, partRequests.RaidRequestSpec)) and
(iutil.getArch() not in raid.raidBootArches)):
errors.append("Bootable partitions cannot be on a RAID "
"device.")
if foundSwap == 0:
warnings.append(_("You have not specified a swap partition to "
"be formatted. Although not strictly required "
"in all cases, you may encounter errors while "
"running %s.")
% (productName,))
# XXX number of swaps not exported from kernel and could change
if foundSwap >= 32:
warnings.append(_("You have specified more than 32 swap devices. "
"The kernel for %s only supports 32 "
"swap devices.") % (productName,))
mem = iutil.memInstalled(corrected = 0)
rem = mem % 16384
if rem:
mem = mem + (16384 - rem)
mem = mem / 1024
if foundSwap and (swapSize < (mem - 8)) and (mem < 1024):
warnings.append(_("You have allocated less swap space (%dM) than "
"available RAM (%dM) on your system. This "
"could negatively impact performance.")
%(swapSize, mem))
if warnings == []:
warnings = None
if errors == []:
errors = None
return (errors, warnings)
def setProtected(self, dispatch):
"""Set any partitions which should be protected to be so."""
protected = dispatch.method.protectedPartitions()
if protected:
for device in protected:
log("%s is a protected partition" % (device))
request = self.getRequestByDeviceName(device)
request.setProtected(1)
def copy (self):
"""Deep copy the object."""
new = Partitions()
for request in self.requests:
new.addRequest(request)
for delete in self.deletes:
new.addDelete(delete)
new.autoPartitionRequests = self.autoPartitionRequests
new.filteredPartitionRequests = self.filteredPartitionRequests
new.autoClearPartType = self.autoClearPartType
new.autoClearPartDrives = self.autoClearPartDrives
new.nextUniqueID = self.nextUniqueID
new.useAutopartitioning = self.useAutopartitioning
new.useFdisk = self.useFdisk
new.reinitializeDisks = self.reinitializeDisks
return new
def getClearPart(self):
"""Get the kickstart directive related to the clearpart being used."""
clearpartargs = []
if self.autoClearPartType == CLEARPART_TYPE_LINUX:
clearpartargs.append('--linux')
elif self.autoClearPartType == CLEARPART_TYPE_ALL:
clearpartargs.append('--all')
elif self.autoClearPartType == CLEARPART_TYPE_NOTVMFS:
clearpartargs.append('--exceptvmfs')
else:
return None
if self.reinitializeDisks:
clearpartargs.append('--initlabel')
if self.autoClearPartDrives:
drives = string.join(self.autoClearPartDrives, ',')
clearpartargs.append('--drives=%s' % (drives))
return "#clearpart %s\n" %(string.join(clearpartargs))
def writeKS(self, f):
"""Write out the partitioning information in kickstart format."""
f.write("# The following is the partition information you requested\n")
f.write("# Note that any partitions you deleted are not expressed\n")
f.write("# here so unless you clear all partitions first, this is\n")
f.write("# not guaranteed to work\n")
clearpart = self.getClearPart()
if clearpart:
f.write(clearpart)
# lots of passes here -- parts, raid, volgroup, logvol
# XXX what do we do with deleted partitions?
for request in self.requests:
args = []
if request.type == REQUEST_RAID:
continue
# no fstype, no deal (same with foreigns)
if not request.fstype or request.fstype.getName() == "foreign":
continue
# first argument is mountpoint, which can also be swap or
# the unique RAID identifier. I hate kickstart partitioning
# syntax. a lot. too many special cases
if request.fstype.getName() == "swap":
args.append("swap")
elif request.fstype.getName() == "software RAID":
# since we guarantee that uniqueIDs are ints now...
args.append("raid.%s" % (request.uniqueID))
elif request.fstype.getName() == "physical volume (LVM)":
# see above about uniqueIDs being ints
args.append("pv.%s" % (request.uniqueID))
elif request.mountpoint:
args.append(request.mountpoint)
args.append("--fstype")
args.append(request.fstype.getName())
else:
continue
# generic options
if not request.format:
args.append("--noformat")
if request.badblocks:
args.append("--badblocks")
# preexisting only
if request.type == REQUEST_PREEXIST and request.device:
args.append("--onpart")
args.append(request.device)
# we have a billion ways to specify new partitions
elif request.type == REQUEST_NEW:
if request.size:
args.append("--size=%s" % (request.size))
if request.grow:
args.append("--grow")
if request.start:
args.append("--start=%s" % (request.start))
if request.end:
args.append("--end=%s" % (request.end))
if request.maxSizeMB:
args.append("--maxsize=%s" % (request.maxSizeMB))
if request.drive:
args.append("--ondisk=%s" % (request.drive[0]))
if request.primary:
args.append("--asprimary")
else: # how the hell did we get this?
continue
f.write("#part %s\n" % (string.join(args)))
for request in self.requests:
args = []
if request.type != REQUEST_RAID:
continue
# no fstype, no deal (same with foreigns)
if not request.fstype or request.fstype.getName() == "foreign":
continue
# also require a raidlevel and raidmembers for raid
if (request.raidlevel == None) or not request.raidmembers:
continue
# first argument is mountpoint, which can also be swap
if request.fstype.getName() == "swap":
args.append("swap")
elif request.fstype.getName() == "physical volume (LVM)":
# see above about uniqueIDs being ints
args.append("pv.%s" % (request.uniqueID))
elif request.mountpoint:
args.append(request.mountpoint)
else:
continue
# generic options
if not request.format:
args.append("--noformat")
if request.fstype:
args.append("--fstype")
args.append(request.fstype.getName())
if request.badblocks:
args.append("--badblocks")
args.append("--level=%s" % (request.raidlevel))
if request.raidspares:
args.append("--spares=%s" % (request.raidspares))
# silly raid member syntax
raidmems = []
for member in request.raidmembers:
if (type(member) != type("")) or (member[0:5] != "raid."):
raidmems.append("raid.%s" % (member))
else:
raidmems.append(member)
args.append("%s" % (string.join(raidmems)))
f.write("#raid %s\n" % (string.join(args)))
for request in self.requests:
args = []
if request.type != REQUEST_VG:
continue
args.append(request.volumeGroupName)
# silly pv syntax
pvs = []
for member in request.physicalVolumes:
if (type(member) != type("")) or not member.startswith("pv."):
pvs.append("pv.%s" % (member))
else:
pvs.append(member)
args.append("%s" % (string.join(pvs)))
f.write("#volgroup %s\n" % (string.join(args)))
for request in self.requests:
args = []
if request.type != REQUEST_LV:
continue
# no fstype, no deal (same with foreigns)
if not request.fstype or request.fstype.getName() == "foreign":
continue
# require a vg name and an lv name
if (request.logicalVolumeName is None or
request.volumeGroup is None):
continue
# first argument is mountpoint, which can also be swap
if request.fstype.getName() == "swap":
args.append("swap")
elif request.mountpoint:
args.append(request.mountpoint)
else:
continue
# generic options
if not request.format:
args.append("--noformat")
if request.fstype:
args.append("--fstype")
args.append(request.fstype.getName())
vg = self.getRequestByID(request.volumeGroup)
if vg is None:
continue
args.extend(["--name=%s" %(request.logicalVolumeName,),
"--vgname=%s" %(vg.volumeGroupName,)])
if request.grow:
if request.startSize is not None:
args.append("--size=%s" % (request.startSize,))
else:
# shouldnt happen
continue
args.append("--grow")
if request.maxSizeMB is not None and int(request.maxSizeMB) > 0:
args.append("--maxsize=%s" % (request.maxSizeMB,))
else:
if request.percent is not None:
args.append("--percent=%s" %(request.percent,))
elif request.size is not None:
args.append("--size=%s" %(request.size,))
else:
continue
f.write("#logvol %s\n" % (string.join(args)))
def deleteAllLogicalPartitions(self, part):
"""Add delete specs for all logical partitions in part."""
for partition in partedUtils.get_logical_partitions(part.disk):
partName = partedUtils.get_partition_name(partition)
request = self.getRequestByDeviceName(partName)
self.removeRequest(request)
if request.preexist:
drive = partedUtils.get_partition_drive(partition)
delete = partRequests.DeleteSpec(drive, partition.geom.start,
partition.geom.end)
self.addDelete(delete)
def containsImmutablePart(self, part):
"""Returns whether the partition contains parts we can't delete."""
if not part or (type(part) == type("RAID")) or (type(part) == type(1)):
return None
if not part.type & parted.PARTITION_EXTENDED:
return None
disk = part.disk
while part:
if not part.is_active():
part = disk.next_partition(part)
continue
device = partedUtils.get_partition_name(part)
request = self.getRequestByDeviceName(device)
if request:
if request.getProtected():
return _("the partition in use by the installer.")
if self.isRaidMember(request):
return _("a partition which is a member of a RAID array.")
if self.isLVMVolumeGroupMember(request):
return _("a partition which is a member of a LVM Volume Group.")
part = disk.next_partition(part)
return None
def doMetaDeletes(self, diskset):
"""Does the removal of all of the non-physical volumes in the delete list."""
# have to have lvm on, which requires raid to be started
diskset.startAllRaid()
lvm.vgactivate()
# now, go through and delete logical volumes
for delete in self.deletes:
if isinstance(delete, partRequests.DeleteLogicalVolumeSpec):
lvm.lvremove(delete.name, delete.vg)
# now, go through and delete volume groups
for delete in self.deletes:
if isinstance(delete, partRequests.DeleteVolumeGroupSpec):
lvm.vgremove(delete.name)
lvm.vgdeactivate()
diskset.stopAllRaid()
def deleteDependentRequests(self, request):
"""Handle deletion of this request and all requests which depend on it.
eg, delete all logical volumes from a volume group, all volume groups
which depend on the raid device.
Side effects: removes all dependent requests from self.requests
adds needed dependent deletes to self.deletes
"""
toRemove = []
id = request.uniqueID
for req in self.requests:
if isinstance(req, partRequests.RaidRequestSpec):
if id in req.raidmembers:
toRemove.append(req)
# XXX do we need to do anything special with preexisting raids?
elif isinstance(req, partRequests.VolumeGroupRequestSpec):
if id in req.physicalVolumes:
toRemove.append(req)
if req.getPreExisting():
delete = partRequests.DeleteVolumeGroupSpec(req.volumeGroupName)
self.addDelete(delete)
elif isinstance(req, partRequests.LogicalVolumeRequestSpec):
if id == req.volumeGroup:
toRemove.append(req)
tmp = self.getRequestByID(req.volumeGroup)
if not tmp:
log("Unable to find the vg for %s"
% (req.logicalVolumeName,))
vgname = req.volumeGroup
else:
vgname = tmp.volumeGroupName
if req.getPreExisting():
delete = partRequests.DeleteLogicalVolumeSpec(req.logicalVolumeName,
vgname)
self.addDelete(delete)
for req in toRemove:
self.deleteDependentRequests(req)
self.removeRequest(req)
Attachment:
signature.asc
Description: OpenPGP digital signature