summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Fulbright <msf@redhat.com>2001-06-20 22:38:48 +0000
committerMike Fulbright <msf@redhat.com>2001-06-20 22:38:48 +0000
commitdf41d89bb6bf243dd355dfae69d32cd38725665f (patch)
treee2216eb9d42282c89892d84cd65c3141de854033
parenta4c0b8fd56b50048883f8aab70a7e66675641086 (diff)
fix ups to RAID sanity checking
-rw-r--r--fsset.py2
-rw-r--r--iw/partition_gui.py82
-rw-r--r--partitioning.py177
-rw-r--r--textw/partition_text.py7
4 files changed, 213 insertions, 55 deletions
diff --git a/fsset.py b/fsset.py
index cf29a477d..6ce94c5e7 100644
--- a/fsset.py
+++ b/fsset.py
@@ -27,7 +27,7 @@ defaultMountPoints = ('/', '/boot', '/home', '/tmp', '/usr', '/var')
fileSystemTypes = {}
-availRaidLevels = ['RAID-0', 'RAID-1', 'RAID-5']
+availRaidLevels = ['RAID0', 'RAID1', 'RAID5']
def fileSystemTypeGetDefault():
return fileSystemTypeGet('ext2')
diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index f8538a48b..b1b9883eb 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -305,6 +305,7 @@ def createAllowedDrivesClist(drives, reqdrives):
return driveclist
def createAllowedRaidPartitionsClist(allraidparts, reqraidpart):
+
partclist = GtkCList()
partclist.set_selection_mode (SELECTION_MULTIPLE)
@@ -322,7 +323,7 @@ def createAllowedRaidPartitionsClist(allraidparts, reqraidpart):
return partclist
-def createRaidLevelMenu(levels, reqlevel):
+def createRaidLevelMenu(levels, reqlevel, raidlevelchangeCB, sparesb):
leveloption = GtkOptionMenu()
leveloptionmenu = GtkMenu()
defindex = None
@@ -333,6 +334,8 @@ def createRaidLevelMenu(levels, reqlevel):
leveloptionmenu.add(item)
if reqlevel and lev == reqlevel:
defindex = i
+ if raidlevelchangeCB and sparesb:
+ item.connect("activate", raidlevelchangeCB, sparesb)
i = i + 1
leveloption.set_menu (leveloptionmenu)
@@ -352,6 +355,9 @@ def createFSTypeMenu(fstype, fstypechangeCB, mountCombo):
defindex = None
i = 0
for name in names:
+ if not fileSystemTypeGet(name).isSupported():
+ continue
+
if fileSystemTypeGet(name).isFormattable():
item = GtkMenuItem(name)
item.set_data ("type", types[name])
@@ -369,7 +375,24 @@ def createFSTypeMenu(fstype, fstypechangeCB, mountCombo):
return (fstypeoption, fstypeoptionMenu)
-
+def raidlevelchangeCB(widget, sparesb):
+ raidlevel = widget.get_data("level")
+ numparts = sparesb.get_data("numparts")
+ maxspares = get_raid_max_spares(raidlevel, numparts)
+ if maxspares > 0:
+ sparesb.set_sensitive(1)
+ adj = sparesb.get_adjustment()
+ value = adj.value
+ if adj.value > maxspares:
+ value = maxspares
+ adj.set_all(value, 0, maxspares,
+ adj.step_increment, adj.page_increment,
+ adj.page_size)
+ sparesb.set_adjustment(adj)
+ sparesb.set_value(value)
+ else:
+ sparesb.set_value(0)
+ sparesb.set_sensitive(0)
class PartitionWindow(InstallWindow):
def __init__(self, ics):
@@ -381,6 +404,7 @@ class PartitionWindow(InstallWindow):
def getNext(self):
self.diskStripeGraph.shutDown()
self.clearTree()
+ self.fsset.reset()
for request in self.partitions.requests:
# XXX improve sanity checking
if not request.fstype or (request.fstype.isMountable() and not request.mountpoint):
@@ -683,8 +707,6 @@ class PartitionWindow(InstallWindow):
# read out UI into a partition specification
filesystem = fstypeoptionMenu.get_active().get_data("type")
- print filesystem.getName()
-
if not newbycyl:
if fixedrb.get_active():
grow = None
@@ -726,7 +748,7 @@ class PartitionWindow(InstallWindow):
print "new requests:"
print request
- err = sanityCheck(self.partitions, request)
+ err = sanityCheckPartitionRequest(self.partitions, request)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
@@ -746,7 +768,7 @@ class PartitionWindow(InstallWindow):
else:
request.format = 0
- err = sanityCheck(self.partitions, request)
+ err = sanityCheckPartitionRequest(self.partitions, request)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
@@ -830,6 +852,12 @@ class PartitionWindow(InstallWindow):
self.tree.thaw()
self.checkNextConditions()
+# for r in self.partitions.requests:
+# print "--------------------------"
+# print r
+# print "--------------------------"
+#
+# print "\n\n"
return rc
def editCb(self, widget):
@@ -874,6 +902,8 @@ class PartitionWindow(InstallWindow):
maintable.set_col_spacings (5)
row = 0
+ availraidparts = get_available_raid_partitions(self.diskset, self.partitions.requests)
+
# Mount Point entry
maintable.attach(createAlignedLabel(_("Mount Point:")),
0, 1, row, row + 1)
@@ -895,7 +925,29 @@ class PartitionWindow(InstallWindow):
# raid level
maintable.attach(createAlignedLabel(_("RAID Level:")),
0, 1, row, row + 1)
- (leveloption, leveloptionmenu) = createRaidLevelMenu(availRaidLevels, raidrequest.raidlevel)
+
+ # Create here, pack below
+ numparts = len(availraidparts)
+ if raidrequest.raidlevel:
+ maxspares = get_raid_max_spares(raidrequest.raidlevel, numparts)
+ else:
+ maxspares = 0
+
+ spareAdj = GtkAdjustment (value = 0, lower = 0,
+ upper = maxspares, step_incr = 1)
+ sparesb = GtkSpinButton(spareAdj, digits = 0)
+ sparesb.set_data("numparts", numparts)
+
+ if maxspares > 0:
+ sparesb.set_sensitive(1)
+ else:
+ sparesb.set_value(0)
+ sparesb.set_sensitive(0)
+
+ (leveloption, leveloptionmenu) = createRaidLevelMenu(availRaidLevels,
+ raidrequest.raidlevel,
+ raidlevelchangeCB,
+ sparesb)
maintable.attach(leveloption, 1, 2, row, row + 1)
row = row + 1
@@ -904,22 +956,16 @@ class PartitionWindow(InstallWindow):
maintable.attach(createAlignedLabel(_("Raid Members:")),
0, 1, row, row + 1)
- availraidparts = []
- for drive in self.diskset.disks.keys():
- availraidparts.extend(get_raid_partitions(self.diskset.disks[drive]))
-
# XXX need to pass in currently used partitions for this device
raidclist = createAllowedRaidPartitionsClist(availraidparts,
raidrequest.raidmembers)
+
maintable.attach(raidclist, 1, 2, row, row + 1)
row = row + 1
- # number of spares
+ # number of spares - created widget above
maintable.attach(createAlignedLabel(_("Number of spares?:")),
0, 1, row, row + 1)
- spareAdj = GtkAdjustment (value = 0, lower = 0,
- upper = len(availraidparts), step_incr = 1)
- sparesb = GtkSpinButton(spareAdj, digits = 0)
maintable.attach(sparesb, 1, 2, row, row + 1)
row = row + 1
@@ -944,12 +990,16 @@ class PartitionWindow(InstallWindow):
if rc == 1:
dialog.close()
return
+ elif rc == -1:
+ # something died in dialog
+ raise ValueError, "Died inside of raid edit dialog!"
# read out UI into a partition specification
request = copy.copy(raidrequest)
filesystem = fstypeoptionMenu.get_active().get_data("type")
request.fstype = filesystem
+ print "in editraid, fs = ",filesystem.getName()
if request.fstype.isMountable():
request.mountpoint = mountCombo.entry.get_text()
@@ -971,7 +1021,7 @@ class PartitionWindow(InstallWindow):
print request
- err = sanityCheck(self.partitions, request)
+ err = sanityCheckRaidRequest(self.partitions, request)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
diff --git a/partitioning.py b/partitioning.py
index fdc92c2db..d4fcbdf6f 100644
--- a/partitioning.py
+++ b/partitioning.py
@@ -34,6 +34,11 @@ REQUEST_PREEXIST = 1
REQUEST_NEW = 2
REQUEST_RAID = 4
+# max partition size in kB
+# XXX these are just made up, need to get real values from parted!
+MAX_PART_SIZE = 1024*1024*1024
+MAX_SWAP_PART_SIZE_KB = 2147483640/1024
+
fsTypes = {}
fs_type = parted.file_system_type_get_next ()
@@ -145,45 +150,80 @@ def get_available_raid_partitions(diskset, requests):
for drive in drives:
disk = diskset.disks[drive]
for part in get_raid_partitions(disk):
+ used = 0
for raid in raiddevs:
- if raid.raidmembers and part in raid.raidmembers:
+ if raid.raidmembers:
+ for raidmem in raid.raidmembers:
+ if get_partition_name(part) == get_partition_name(raidmem.partition):
+ used = 1
+ break
+ if used:
break
- rc.append(part)
+
+ if not used:
+ 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":
+ if raidlevel == "RAID0":
return 2
- elif raidlevel == "RAID-1":
+ elif raidlevel == "RAID1":
return 2
- elif raidlevel == "RAID-5":
+ elif raidlevel == "RAID5":
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":
+ if raidlevel == "RAID0":
return 0
- elif raidlevel == "RAID-5":
+ elif raidlevel == "RAID1" or raidlevel == "RAID5":
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
-def sanityCheck(reqpartitions, newrequest):
- # see if mount point is valid if its a new partition request
+def get_raid_device_size(raidrequest):
+ if not raidrequest.raidmembers or not raidrequest.raidlevel:
+ return 0
- mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root','/mnt']
- mustbeonlinuxfs = ['/', '/boot', '/var', '/tmp', '/usr', '/home']
+ raidlevel = raidrequest.raidlevel
+ nummembers = len(raidrequest.raidmembers)
+ smallest = None
+ sum = 0
+ for member in raidrequest.raidmembers:
+ part = member.partition
+ partsize = part.geom.length * part.geom.disk.dev.sector_size
+ print "raid members, size->",get_partition_name(part), partsize
+ if raidlevel == "RAID0":
+ sum = sum + partsize
+ else:
+ if not smallest:
+ smallest = partsize
+ elif sizekb < smallest:
+ smallest = partsize
+
+ if raidlevel == "RAID0":
+ return sum
+ elif raidlevel == "RAID1":
+ return smallest
+ elif raidlevel == "RAID5":
+ return (nummembers-1) * smallest
+ else:
+ raise ValueError, "Invalid raidlevel in get_raid_device_size()"
- mntpt = newrequest.mountpoint
- fstype = newrequest.fstype
+# return name of boot mount point in current requests
+def getBootableRequest(reqpartitions):
+ bootreq = reqpartitions.getRequestByMountPoint("/boot")
+ if not bootreq:
+ bootreq = reqpartitions.getRequestByMountPoint("/")
+ return bootreq
+
+
+# sanityCheckMountPoint
+def sanityCheckMountPoint(mntpt, fstype, reqtype):
if mntpt:
passed = 1
if not mntpt:
@@ -191,41 +231,98 @@ def sanityCheck(reqpartitions, newrequest):
else:
if mntpt[0] != '/' or (len(mntpt) > 1 and mntpt[-1:] == '/'):
passed = 0
-
+
if not passed:
return _("The mount point is invalid. Mount points must start "
"with '/' and cannot end with '/', and must contain "
"printable characters.")
+ else:
+ return None
else:
- if newrequest.fstype.isMountable() and newrequest.type == REQUEST_NEW:
+ if fstype and fstype.isMountable() and reqtype == REQUEST_NEW:
return _("Please specify a mount point for this partition.")
else:
# its an existing partition so don't force a mount point
- return
+ return None
- # mount point is defined and is legal. now make sure its unique
+def isMountPointInUse(reqpartitions, newrequest):
+ mntpt = newrequest.mountpoint
+ if not mntpt:
+ return None
+
if reqpartitions and reqpartitions.requests:
for request in reqpartitions.requests:
- if request.mountpoint == mntpt and request.start != newrequest.start:
- return _("The mount point %s is already in use, please "
- "choose a different mount point." % (mntpt))
+ if request.mountpoint == mntpt:
+ used = 0
+ if newrequest.type == REQUEST_RAID:
+ if request.raidmembers != newrequest.raidmembers:
+ used = 1
+ else:
+ if request.start != newrequest.start:
+ used = 1
+ if used:
+ return _("The mount point %s is already in use, please "
+ "choose a different mount point." % (mntpt))
+
+
+ return None
- # further sanity checks
- if fstype.isLinuxNativeFS():
- if mntpt in mustbeonroot:
+def doMountPointLinuxFSChecks(newrequest):
+ mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root','/mnt']
+ mustbeonlinuxfs = ['/', '/boot', '/var', '/tmp', '/usr', '/home']
+
+ if newrequest.fstype.isLinuxNativeFS():
+ if newrequest.mountpoint in mustbeonroot:
return _("This mount point is invalid. This directory must "
"be on the / filesystem.")
- if fstype.getName() == "linux-swap":
- if newrequest.size * 1024 > MAX_SWAP_PART_SIZE_KB:
- return _("This swap partition exceeds the maximum size of "
- "%s MB.") % (MAX_SWAP_PART_SIZE_KB / 1024)
+ if newrequest.fstype.getName() == "swap":
+ if newrequest.type == REQUEST_RAID:
+ swapsize = get_raid_device_size(newrequest)
+ else:
+ swapsize = newrequest.size
+
+ print "swapsize ->",swapsize
+
+ if swapsize * 1024 > MAX_SWAP_PART_SIZE_KB:
+ return _("This swap partition exceeds the maximum size of "
+ "%s MB.") % (MAX_SWAP_PART_SIZE_KB / 1024)
+ else:
+ return None
else:
- if mntpt in mustbeonlinuxfs:
+ if newrequest.mountpoint in mustbeonlinuxfs:
return _("This mount point must be on a linux filesystem.")
return None
+
+
+
+# returns error string if something not right about request
+def sanityCheckPartitionRequest(reqpartitions, newrequest):
+ # see if mount point is valid if its a new partition request
+ mntpt = newrequest.mountpoint
+ fstype = newrequest.fstype
+ reqtype = newrequest.type
+
+ rc = sanityCheckMountPoint(mntpt, fstype, reqtype)
+ if rc:
+ return rc
+
+ rc = isMountPointInUse(reqpartitions, newrequest)
+ if rc:
+ return rc
+
+ rc = doMountPointLinuxFSChecks(newrequest)
+ if rc:
+ return rc
+
+ return None
+
+# return error string is something not right about raid request
+def sanityCheckRaidRequest(reqpartitions, newraid):
+ rc = sanityCheckPartitionRequest(reqpartitions, newraid)
+
class DeleteSpec:
def __init__(self, drive, start, end):
@@ -281,14 +378,24 @@ class PartitionSpec:
self.currentDrive = None
def __str__(self):
- return "mountpoint: %s type: %s\n" %(self.mountpoint, self.fstype.getName()) +\
+ if self.fstype:
+ fsname = self.fstype.getName()
+ else:
+ fsname = "None"
+ raidmem = []
+ if self.raidmembers:
+ for i in self.raidmembers:
+ raidmem.append(get_partition_name(i.partition))
+
+ return "mountpoint: %s type: %s\n" %(self.mountpoint, fsname) +\
" size: %sM requestSize: %sM grow: %s max: %s\n" %(self.size, self.requestSize, self.grow, self.maxSize) +\
" start: %s end: %s partnum: %s\n" %(self.start, self.end, self.partnum) +\
" drive: %s primary: %s secondary: %s\n" %(self.drive, self.primary, self.secondary) +\
" format: %s, options: %s" %(self.format, self.options) +\
- " device: %s, realDevice: %s" %(self.device, self.realDevice)+\
+ " device: %s, realDevice: %s\n" %(self.device, self.realDevice)+\
" raidlevel: %s" % (self.raidlevel)+\
- " raidspares: %s" % (self.raidspares)
+ " raidspares: %s" % (self.raidspares)+\
+ " raidmembers: %s" % (raidmem)
# turn a partition request into a fsset entry
def toEntry(self):
diff --git a/textw/partition_text.py b/textw/partition_text.py
index af94948ea..623bc998c 100644
--- a/textw/partition_text.py
+++ b/textw/partition_text.py
@@ -403,7 +403,7 @@ class PartitionWindow:
request.primary = primonly
request.maxSize = maxsize
- err = sanityCheck(self.partitions, request)
+ err = sanityCheckPartitionRequest(self.partitions, request)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
@@ -420,7 +420,7 @@ class PartitionWindow:
else:
origrequest.format = 0
- err = sanityCheck(self.partitions, origrequest)
+ err = sanityCheckPartitionRequest(self.partitions, origrequest)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
@@ -502,7 +502,7 @@ class PartitionWindow:
else:
request.format = 0
- err = sanityCheck(self.partitions, request)
+ err = sanityCheckPartitionRequest(self.partitions, request)
if err:
self.intf.messageWindow(_("Error With Request"),
"%s" % (err))
@@ -636,6 +636,7 @@ class PartitionWindow:
else:
if not self.partitions.getRequestByMountPoint("/"):
continue
+ self.fsset.reset()
for request in self.partitions.requests:
# XXX improve sanity checking
if not request.fstype or (request.fstype.isMountable() and not request.mountpoint):