summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--autopart.py7
-rw-r--r--fsset.py194
-rw-r--r--iw/keyboard_gui.py2
-rw-r--r--iw/progress_gui.py2
-rw-r--r--iw/upgrade_swap_gui.py11
-rw-r--r--partitioning.py55
6 files changed, 188 insertions, 83 deletions
diff --git a/autopart.py b/autopart.py
index 471801556..00e254143 100644
--- a/autopart.py
+++ b/autopart.py
@@ -159,7 +159,6 @@ def fitSized(diskset, requests):
ret = bestPartType(disk)
if ret == PARTITION_FAIL:
return ret
- print ret
if ret == parted.PARTITION_PRIMARY:
partType = parted.PARTITION_PRIMARY
elif ret == parted.PARTITION_EXTENDED:
@@ -291,7 +290,11 @@ def processPartitioning(diskset, requests):
for request in requests.requests:
if request.type == REQUEST_NEW:
request.device = None
-# request.requestSize = request.size
+
+ # set the unique identifier for raid devices
+ if request.type == REQUEST_RAID and not request.device:
+ request.device = requests.maxcontainer
+ requests.maxcontainer = requests.maxcontainer + 1
# XXX - handle delete requests
for delete in requests.deletes:
diff --git a/fsset.py b/fsset.py
index 927c6cd6d..b278c83ee 100644
--- a/fsset.py
+++ b/fsset.py
@@ -21,11 +21,14 @@ import parted
from log import log
from translate import _, N_
import partitioning
+import sys
defaultMountPoints = ('/', '/boot', '/home', '/tmp', '/usr', '/var')
fileSystemTypes = {}
+availRaidLevels = ['RAID-0', 'RAID-1', 'RAID-5']
+
def fileSystemTypeGetDefault():
return fileSystemTypeGet('ext2')
@@ -87,8 +90,18 @@ class FileSystemType:
self.name = ""
self.linuxnativefs = 0
self.partedFileSystemType = None
- self.partedPartitonFlags = []
+ self.partedPartitionFlags = []
+ def mount(self, device, mountpoint, readOnly=0):
+ if not self.isMountable():
+ return
+ iutil.mkdirChain(mountpoint)
+ isys.mount(device, mountpoint, fstype = self.getName(),
+ readOnly = readOnly)
+
+ def umount(self, path):
+ isys.umount(path, removeDir = 0)
+
def getName(self):
return self.name
@@ -169,6 +182,37 @@ class ext2FileSystem(FileSystemType):
fileSystemTypeRegister(ext2FileSystem())
+class ext3FileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.partedFileSystemType = parted.file_system_type_get("ext2")
+ self.formattable = 1
+ self.checked = 1
+ self.linuxnativefs = 1
+ self.name = "ext3"
+
+ def formatDevice(self, entry, progress, message, chroot='/'):
+ devicePath = entry.device.setupDevice(chroot)
+ devArgs = self.getDeviceArgs(entry.device)
+ label = labelFactory.createLabel(entry.mountpoint)
+ entry.setLabel(label)
+ args = [ "/usr/sbin/mke2fs", devicePath, '-j', '-L', label ]
+ args.extend(devArgs)
+
+ rc = ext2FormatFilesystem(args, "/dev/tty5",
+ progress,
+ entry.mountpoint)
+ if rc:
+ message and message(_("Error"),
+ _("An error occured trying to format %s. "
+ "This problem is serious, and the install "
+ "cannot continue.\n\n"
+ "Press Enter to reboot your "
+ "system.") % (entry.device.getDevice(),))
+ raise SystemError
+
+fileSystemTypeRegister(ext3FileSystem())
+
class raidMemberDummyFileSystem(FileSystemType):
def __init__(self):
FileSystemType.__init__(self)
@@ -186,12 +230,21 @@ class raidMemberDummyFileSystem(FileSystemType):
fileSystemTypeRegister(raidMemberDummyFileSystem())
class swapFileSystem(FileSystemType):
+ enabledSwaps = {}
+
def __init__(self):
FileSystemType.__init__(self)
self.partedFileSystemType = parted.file_system_type_get("linux-swap")
self.formattable = 1
self.name = "swap"
+ def mount(self, device, mountpoint):
+ isys.swapon (device)
+
+ def umount(self, device, path):
+ # unfortunately, turning off swap is bad.
+ pass
+
def formatDevice(self, entry, progress, message, chroot='/'):
file = entry.device.setupDevice(chroot)
rc = iutil.execWithRedirect ("/usr/sbin/mkswap",
@@ -325,7 +378,7 @@ class FileSystemSet:
if bootDev.getName() == "LoopbackDevice":
return None
elif bootDev.getName() == "RAIDDevice":
- return [ bootDev.device, "RAID Device" ]
+ return [ ( bootDev.device, "RAID Device" ) ]
return [ (diskSet.driveList()[0], N_("Master Boot Record (MBR)") ),
(bootDev.device, N_("First sector of boot partition"))
@@ -333,24 +386,20 @@ class FileSystemSet:
def formatSwap (self, chroot):
for entry in self.entries:
- if entry.mountpoint and entry.fsystem.getName() == "swap":
+ if (entry.fsystem and entry.fsystem.getName() == "swap"
+ and entry.getFormat()):
entry.fsystem.formatDevice(entry, self.progressWindow,
self.messageWindow, chroot)
def turnOnSwap (self, chroot):
for entry in self.entries:
- if entry.mountpoint and entry.fsystem.getName() == "swap":
- if not entry.isMounted():
- file = entry.device.setupDevice(chroot)
- isys.swapon (file)
- entry.setMounted(1)
+ if entry.fsystem and entry.fsystem.getName() == "swap":
+ entry.mount(chroot)
def turnOffSwap(self, devices = 1, files = 0):
for entry in self.entries:
- if entry.mountpoint and entry.fsystem.getName() == "swap":
- if entry.isMounted():
- isys.swapoff(n)
- entry.setMounted(0)
+ if entry.fsystem and entry.fsystem.getName() == "swap":
+ entry.umount(chroot)
def formattablePartitions(self):
list = []
@@ -361,10 +410,9 @@ class FileSystemSet:
def makeFilesystems (self, chroot='/'):
for entry in self.entries:
- if (not entry.format or entry.isMounted()
- or not entry.fsystem.isFormattable()):
+ if (not entry.fsystem.isFormattable() or not entry.getFormat()
+ or entry.isMounted()):
continue
-
entry.fsystem.formatDevice(entry, self.progressWindow,
self.messageWindow, chroot)
@@ -372,27 +420,20 @@ class FileSystemSet:
for entry in self.entries:
if not entry.fsystem.isMountable():
continue
- elif (entry.fsystem.isFormattable()
- or (entry.fsystem.getName() == "vfat"
- and entry.mountpoint == "/boot/efi")):
- try:
- iutil.mkdirChain(instPath + entry.mountpoint)
- isys.mount(entry.device.getDevice(),
- instPath + entry.mountpoint,
- fstype = entry.fsystem.getName(),
- readOnly = readOnly)
- entry.setMounted(1)
- except SystemError, (errno, msg):
- if raiseErrors:
- raise SystemError, (errno, msg)
- self.messageWindow and self.messageWindow(_("Error"),
- _("Error mounting device %s as %s: %s\n\n"
- "This most likely means this partition has "
- "not been formatted.\n\nPress OK to reboot your "
- "system.") % (entry.device.getDevice(),
- entry.mountpoint, msg))
- sys.exit(0)
-
+ try:
+ entry.mount(instPath)
+ except SystemError, (errno, msg):
+ if raiseErrors:
+ raise SystemError, (errno, msg)
+ self.messageWindow and self.messageWindow(_("Error"),
+ _("Error mounting device %s as %s: %s\n\n"
+ "This most likely means this partition has "
+ "not been formatted.\n\nPress OK to reboot your "
+ "system.") % (entry.device.getDevice(),
+ entry.mountpoint, msg))
+ sys.exit(0)
+
+ # XXX remove special case...
try:
os.mkdir (instPath + '/proc')
except:
@@ -401,6 +442,7 @@ class FileSystemSet:
isys.mount('/proc', instPath + '/proc', 'proc')
def umountFilesystems(self, instPath, ignoreErrors = 0):
+ # XXX remove special case
try:
isys.umount(instPath + '/proc/bus/usb', removeDir = 0)
log("Umount USB OK")
@@ -412,9 +454,7 @@ class FileSystemSet:
reverse.reverse()
for entry in reverse:
- if entry.isMounted():
- isys.umount(instPath + entry.mountpoint, removeDir = 0)
- entry.setMounted(0)
+ entry.umount(instPath)
class FileSystemSetEntry:
def __init__ (self, device, mountpoint,
@@ -426,7 +466,7 @@ class FileSystemSetEntry:
self.mountpoint = mountpoint
self.fsystem = fsystem
self.options = options
- self.mounted = 0
+ self.mountcount = 0
self.label = None
if fsck == -1:
self.fsck = fsystem.isChecked()
@@ -444,6 +484,17 @@ class FileSystemSetEntry:
if format and not fsystem.isFormattable():
raise RuntimeError, "file system type %s is not formattable, but has been added to fsset with format flag on" % fsystem.getName()
self.format = format
+
+ def mount(self, chroot='/', devPrefix='/tmp'):
+ device = self.device.setupDevice(chroot, devPrefix=devPrefix)
+ self.fsystem.mount(device, "%s/%s" % (chroot, self.mountpoint))
+ self.mountcount = self.mountcount + 1
+
+ def umount(self, chroot='/'):
+ if self.mountcount > 0:
+ self.fssytem.umount(self.device, "%s/%s" % (chroot,
+ self.mountpoint))
+ self.mountcount = self.mountcount - 1
def setFormat (self, state):
self.format = state
@@ -452,10 +503,7 @@ class FileSystemSetEntry:
return self.format
def isMounted (self):
- return self.mounted
-
- def setMounted (self, state):
- self.isMounted = state
+ return self.mountcount > 0
def getLabel (self):
return self.label
@@ -468,6 +516,7 @@ class Device:
self.device = "none"
self.fsoptions = {}
self.label = None
+ self.isSetup = 0
def __repr__(self):
return self.device
@@ -478,7 +527,7 @@ class Device:
def getDevice (self):
return self.device
- def setupDevice (self, chroot='/tmp'):
+ def setupDevice (self, chroot='/', devPrefix='/tmp'):
pass
def cleanupDevice (self, chroot, devPrefix='/tmp'):
@@ -491,16 +540,17 @@ class Device:
return self.__class__.__name__
class RAIDDevice(Device):
- usedMajors = []
+ usedMajors = {}
# members is a list of Device based instances that will be
# a part of this raid device
- def __init__(self, level, members, minor=-1, spares=0):
+ def __init__(self, level, members, minor=-1, spares=0, existing=0):
Device.__init__(self)
self.level = level
self.members = members
self.spares = spares
self.numDisks = len(members) - spares
+ self.isSetup = existing
if len(members) < spares:
raise RuntimeError, "you requiested more spare devices than online devices!"
@@ -512,12 +562,12 @@ class RAIDDevice(Device):
# there are 32 major md devices, 0...31
if minor == -1:
for I in range(32):
- if not I in RAIDDevice.usedMajors:
+ if not RAIDDevice.usedMajors.has_key(I):
minor = I
break
raise RuntimeError, "Unable to allocate minor number for raid device"
minor = I
- RAIDDevice.usedMajors.append(minor)
+ RAIDDevice.usedMajors[minor] = None
self.device = "md" + str(minor)
self.minor = minor
@@ -538,27 +588,37 @@ class RAIDDevice(Device):
entry = entry + "nr-raid-disks %d\n" % (self.numDisks,)
entry = entry + "chunk-size 64k\n"
entry = entry + "persistent-superblock 1\n"
- entry = entry + "#nr-spare-disks %d\n" % (self.spares,)
+ entry = entry + "nr-spare-disks %d\n" % (self.spares,)
i = 0
- for device in self.members:
+ for device in self.members[:self.numDisks]:
entry = entry + " device %s/%s\n" % (devPrefix,
device.getDevice())
entry = entry + " raid-disk %d\n" % (i,)
i = i + 1
+ i = 0
+ for device in self.members[self.numDisks:]:
+ entry = entry + " device %s/%s\n" % (devPrefix,
+ device.getDevice())
+ entry = entry + " spare-disk %d\n" % (i,)
+ i = i + 1
return entry
def setupDevice (self, chroot, devPrefix='/tmp'):
- raidtab = '/tmp/raidtab.%s' % (self.device,)
- f = open(raidtab, 'w')
- f.write(self.raidTab('/tmp'))
- for device in self.members:
- device.setupDevice()
node = "%s/%s" % (devPrefix, self.device)
- isys.makeDevInode(self.device, node, devPrefix=devPrefix)
- iutil.execWithRedirect ("/usr/sbin/mkraid",
- [ 'mkraid', '--really-force', '--configfile',
- raidtab, node ],
- stderr = "/dev/tty5", stdout = "/dev/tty5")
+ isys.makeDevInode(self.device, node)
+
+ if not self.isSetup:
+ raidtab = '/tmp/raidtab.%s' % (self.device,)
+ f = open(raidtab, 'w')
+ f.write(self.raidTab('/tmp'))
+ f.close()
+ for device in self.members:
+ device.setupDevice(chroot, devPrefix=devPrefix)
+ iutil.execWithRedirect ("/usr/sbin/mkraid",
+ ( 'mkraid', '--really-force',
+ '--configfile', raidtab, node ),
+ stderr = "/dev/tty5", stdout = "/dev/tty5")
+ self.isSetup = 1
return node
def solidify(self):
@@ -582,11 +642,10 @@ class PartitionDevice(Device):
isys.makeDevInode(self.getDevice(), path)
return path
-class PartedPartitionDevice(Device):
+class PartedPartitionDevice(PartitionDevice):
def __init__(self, partition):
- Device.__init__(self)
+ PartitionDevice.__init__(self, None)
self.partition = partition
- self.device = None
def getDevice(self):
if not self.partition:
@@ -599,12 +658,9 @@ class PartedPartitionDevice(Device):
return "%s%d" % (self.partition.geom.disk.dev.path[5:],
self.partition.num)
- def setupDevice(self, chroot, devPrefix='/tmp'):
- path = '%d/%s' % (self.getDevice(), devPrefix)
- isys.makeDevInode(self.getDevice(), path)
- return path
-
def solidify(self):
+ # drop reference on the parted partition object and note
+ # the current minor number allocation
self.device = self.getDevice()
self.partition = None
diff --git a/iw/keyboard_gui.py b/iw/keyboard_gui.py
index 92b26c538..66946851d 100644
--- a/iw/keyboard_gui.py
+++ b/iw/keyboard_gui.py
@@ -146,7 +146,7 @@ class KeyboardWindow (InstallWindow):
# self.variantList.append (("None",))
# for (key, variant) in self.rules[2].items ():
count = 0
- for (key, variant) in (("basic", (_("Enable dead keys"))),
+ for (key, variant) in (("", (_("Enable dead keys"))),
("nodeadkeys", (_("Disable dead keys")))):
loc = self.variantList.append ((variant,))
self.variantList.set_row_data (loc, key)
diff --git a/iw/progress_gui.py b/iw/progress_gui.py
index 5dfbeb1c0..de3e9b99e 100644
--- a/iw/progress_gui.py
+++ b/iw/progress_gui.py
@@ -79,6 +79,8 @@ class InstallProgressWindow (InstallWindow):
self.totalProgress.update (float (self.sizeComplete) / self.totalSize)
return
+ self.timeCompleteW.setText("%12s" % formatTime(elapsedTime))
+ self.timeTotalW.setText("%12s" % formatTime(finishTime))
def setPackage(self, header):
if len(self.pixmaps):
diff --git a/iw/upgrade_swap_gui.py b/iw/upgrade_swap_gui.py
index 7f7361037..c5a85d168 100644
--- a/iw/upgrade_swap_gui.py
+++ b/iw/upgrade_swap_gui.py
@@ -104,6 +104,7 @@ class UpgradeSwapWindow (InstallWindow):
self.swapbox = GtkVBox(FALSE, 5)
box.pack_start(self.swapbox, FALSE)
+
label = GtkLabel (_("Select the partition to put the swap file on:"))
a = GtkAlignment(0.2, 0.5)
a.add(label)
@@ -111,16 +112,9 @@ class UpgradeSwapWindow (InstallWindow):
titles = [(_("Mount Point")), (_("Partition")), (_("Free Space (MB)"))]
self.clist = GtkCList(3, titles)
- self.clist.set_usize(300, 100)
self.clist.connect("select-row", self.clist_cb)
-
- sw = GtkScrolledWindow()
- sw.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC)
- sw.add(self.clist)
-
a = GtkAlignment(0.5, 0.5)
- a.add(sw)
-
+ a.add(self.clist)
self.swapbox.pack_start(a, FALSE, TRUE, 10)
count = 0
@@ -131,7 +125,6 @@ class UpgradeSwapWindow (InstallWindow):
self.clist.select_row(0, 0)
-
label = GtkLabel (_("It is recommended that your swap file be at least %d MB. Please enter a size for the swap file:") % suggSize)
label.set_usize(400, 40)
label.set_line_wrap (TRUE)
diff --git a/partitioning.py b/partitioning.py
index 57809719f..6bad67c24 100644
--- a/partitioning.py
+++ b/partitioning.py
@@ -109,7 +109,7 @@ def get_primary_partitions(disk):
return rc
-
+# returns a list of partitions which can make up RAID devices
def get_raid_partitions(disk):
rc = []
part = disk.next_partition()
@@ -124,7 +124,54 @@ def get_raid_partitions(disk):
part = disk.next_partition(part)
return rc
-
+
+
+# returns a list of the actual raid device requests
+def get_raid_devices(requests):
+ raidRequests = []
+ for request in requests:
+ if request.type == REQUEST_RAID:
+ raidRequests.append(request)
+
+ return raidRequests
+
+
+# returns a list of raid partitions which haven't been used in a device yet
+def get_available_raid_partitions(diskset, requests):
+ rc = []
+ drives = diskset.disks.keys()
+ raiddevs = get_raid_devices(requests)
+ drives.sort()
+ for drive in drives:
+ disk = diskset.disks[drive]
+ for part in get_raid_partitions(disk):
+ for raid in raiddevs:
+ if raid.raidmembers and part in raid.raidmembers:
+ break
+ rc.append(part)
+ return rc
+
+# return minimum numer of raid members required for a raid level
+def get_raid_min_members(raidlevel):
+ if raidlevel == "RAID-0":
+ return 2
+ elif raidlevel == "RAID-1":
+ return 2
+ elif raidlevel == "RAID-5":
+ return 3
+ else:
+ raise ValueError, "invalid raidlevel in get_raid_min_members"
+
+# return max num of spares available for raidlevel and total num of members
+def get_raid_max_spares(raidlevel, nummembers):
+ if raidlevel == "RAID-0":
+ return 0
+ elif raidlevel == "RAID-1":
+ return 0
+ elif raidlevel == "RAID-5":
+ return max(0, nummembers - get_raid_min_members(raidlevel))
+ else:
+ raise ValueError, "invalid raidlevel in get_raid_max_spares"
# returns error string if something not right about request
# returns error string if something not right about request
@@ -271,6 +318,10 @@ class PartitionRequests:
if diskset:
self.setFromDisk(diskset)
+ # identifier used for raid partitions
+ self.maxcontainer = 0
+
+
def setFromDisk(self, diskset):
self.deletes = []
diskset.refreshDevices()