summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--fsset.py103
-rw-r--r--iscsi.py23
-rw-r--r--isys/isys.py33
-rw-r--r--iw/iscsi_gui.py6
-rw-r--r--kickstart.py8
-rw-r--r--partitioning.py10
-rw-r--r--yuminstall.py4
-rw-r--r--zfcp.py5
9 files changed, 163 insertions, 58 deletions
diff --git a/ChangeLog b/ChangeLog
index 3315df7c3..d1f2983d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
2006-06-21 Jeremy Katz <katzj@redhat.com>
+ * iw/iscsi_gui.py (iscsiWindow.getNext): Don't need to do the
+ startup here now.
+
+ * isys/isys.py (compareDrives): Sort xvd devices first since
+ they're the "bootable" ones for Xen
+ (driveIsIscsi): Determine if a drive is iscsi or not. Kind of ugly.
+
+ * zfcp.py (ZFCP.write): Copy zfcp.conf here.
+
+ * yuminstall.py (YumBackend.doPreInstall): Write out network, zfcp
+ and iscsi info prior to the install starting.
+
+ * partitioning.py (partitionObjectsInitialize): Flush drive dict
+ on initialization, set up iscsi devices here, make device nodes
+ for drives
+
+ * kickstart.py (AnacondaKSHandlers.doIscsi): Initial iscsi
+ kickstart support. This syntax *will* change
+
+ * iscsi.py (iscsi.action): Set nodes to start up automatically on
+ boot in the db
+ (iscsi.startup): Give a popup while we're waiting on iscsi devs
+ to initialize
+ (iscsi.write): Write out iscsi config
+
+ * fsset.py: Add various bits so that we can set that a device
+ should be marked as _netdev in the fstab and use it appropriately
+ for iscsi.
+
* autopart.py (getDriveList): Sort drive list "correctly"
2006-06-20 Jeremy Katz <katzj@redhat.com>
diff --git a/fsset.py b/fsset.py
index 06868198c..8f127cbb0 100644
--- a/fsset.py
+++ b/fsset.py
@@ -929,38 +929,6 @@ class prepbootFileSystem(FileSystemType):
self.formattable = 0
def formatDevice(self, entry, progress, chroot='/'):
- # copy and paste job from booty/bootloaderInfo.py...
- def getDiskPart(dev):
- cut = len(dev)
- if (dev.startswith('rd/') or dev.startswith('ida/') or
- dev.startswith('cciss/') or dev.startswith('i2o/')
- or dev.startswith("sx8/")):
- if dev[-2] == 'p':
- cut = -1
- elif dev[-3] == 'p':
- cut = -2
- else:
- if dev[-2] in string.digits:
- cut = -2
- elif dev[-1] in string.digits:
- cut = -1
-
- name = dev[:cut]
-
- # hack off the trailing 'p' from /dev/cciss/*, for example
- if name[-1] == 'p':
- for letter in name:
- if letter not in string.letters and letter != "/":
- name = name[:-1]
- break
-
- if cut < 0:
- partNum = int(dev[cut:])
- else:
- partNum = None
-
- return (name, partNum)
-
# FIXME: oh dear is this a hack beyond my wildest imagination.
# parted doesn't really know how to do these, so we're going to
# exec sfdisk and make it set the partition type. this is bloody
@@ -1613,15 +1581,20 @@ MAILADDR root
sys.exit(0)
def createLogicalVolumes (self, chroot='/'):
+ vgs = {}
# first set up the volume groups
for entry in self.entries:
if entry.fsystem.name == "volume group (LVM)":
entry.device.setupDevice(chroot)
+ vgs[entry.device.name] = entry.device
# then set up the logical volumes
for entry in self.entries:
if isinstance(entry.device, LogicalVolumeDevice):
- entry.device.setupDevice(chroot)
+ vg = None
+ if vgs.has_key(entry.device.vgname):
+ vg = vgs[entry.device.vgname]
+ entry.device.setupDevice(chroot, vgdevice = vg)
self.volumesCreated = 1
@@ -1893,6 +1866,7 @@ class FileSystemSetEntry:
self.options = options
else:
self.options = fsystem.getDefaultOptions(mountpoint)
+ self.options += device.getDeviceOptions()
self.mountcount = 0
self.label = None
if fsck == -1:
@@ -2001,10 +1975,10 @@ class FileSystemSetEntry:
class Device:
def __init__(self, device = "none"):
self.device = device
- self.fsoptions = {}
self.label = None
self.isSetup = 0
self.doLabel = 1
+ self.deviceOptions = ""
def getComment (self):
return ""
@@ -2030,6 +2004,20 @@ class Device:
except:
return ""
+ def setAsNetdev(self):
+ """Ensure we're set up so that _netdev is in our device options."""
+ if "_netdev" not in self.deviceOptions:
+ self.deviceOptions += ",_netdev"
+
+ def isNetdev(self):
+ """Check to see if we're set as a netdev"""
+ if "_netdev" in self.deviceOptions:
+ return True
+ return False
+
+ def getDeviceOptions(self):
+ return self.deviceOptions
+
class DevDevice(Device):
"""Device with a device node rooted in /dev that we just always use
the pre-created device node for."""
@@ -2159,8 +2147,9 @@ class RAIDDevice(Device):
if not self.isSetup:
for device in self.members:
- PartitionDevice(device).setupDevice(chroot,
- devPrefix=devPrefix)
+ pd = PartitionDevice(device)
+ pd.setupDevice(chroot, devPrefix=devPrefix)
+ if pd.isNetdev(): self.setAsNetdev()
args = ["/usr/sbin/mdadm", "--create", "/dev/%s" %(self.device,),
"--run", "--chunk=%s" %(self.chunksize,),
@@ -2217,6 +2206,7 @@ class VolumeGroupDevice(Device):
for volume in self.physicalVolumes:
# XXX the lvm tools are broken and will only work for /dev
node = volume.setupDevice(chroot, devPrefix="/dev")
+ if volume.isNetdev(): self.setAsNetdev()
# XXX I should check if the pv is set up somehow so that we
# can have preexisting vgs and add new pvs to them.
@@ -2286,7 +2276,7 @@ class LogicalVolumeDevice(Device):
# self.extents
# self.readaheadsectors
- def setupDevice(self, chroot="/", devPrefix='/tmp'):
+ def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None):
if not self.isSetup:
lvm.writeForceConf()
rc = iutil.execWithRedirect("lvm",
@@ -2302,6 +2292,8 @@ class LogicalVolumeDevice(Device):
lvm.unlinkConf()
self.isSetup = 1
+ if vgdevice and vgdevice.isNetdev(): self.setAsNetdev()
+
return "/dev/%s" % (self.getDevice(),)
def getDevice(self, asBoot = 0):
@@ -2318,6 +2310,10 @@ class PartitionDevice(Device):
raise ValueError, "partition must be a string"
self.device = partition
+ (disk, pnum) = getDiskPart(partition)
+ if isys.driveIsIscsi(disk):
+ self.setAsNetdev()
+
def setupDevice(self, chroot="/", devPrefix='/tmp'):
path = '%s/%s' % (devPrefix, self.getDevice(),)
isys.makeDevInode(self.getDevice(), path)
@@ -2778,6 +2774,39 @@ def ext2FormatFilesystem(argList, messageFile, windowCreator, mntpoint):
return 1
+# copy and paste job from booty/bootloaderInfo.py...
+def getDiskPart(dev):
+ cut = len(dev)
+ if (dev.startswith('rd/') or dev.startswith('ida/') or
+ dev.startswith('cciss/') or dev.startswith('sx8/') or
+ dev.startswith('mapper/')):
+ if dev[-2] == 'p':
+ cut = -1
+ elif dev[-3] == 'p':
+ cut = -2
+ else:
+ if dev[-2] in string.digits:
+ cut = -2
+ elif dev[-1] in string.digits:
+ cut = -1
+
+ name = dev[:cut]
+
+ # hack off the trailing 'p' from /dev/cciss/*, for example
+ if name[-1] == 'p':
+ for letter in name:
+ if letter not in string.letters and letter != "/":
+ name = name[:-1]
+ break
+
+ if cut < 0:
+ partNum = int(dev[cut:]) - 1
+ else:
+ partNum = None
+
+ return (name, partNum)
+
+
if __name__ == "__main__":
fsset = readFstab("fstab")
diff --git a/iscsi.py b/iscsi.py
index fc8282ba5..fcc844412 100644
--- a/iscsi.py
+++ b/iscsi.py
@@ -17,8 +17,11 @@ import signal
import iutil
from flags import flags
import logging
+import shutil
log = logging.getLogger("anaconda")
+from rhpl.translate import _, N_
+
# Note that stage2 copies all files under /sbin to /usr/sbin
ISCSID="iscsid"
@@ -59,6 +62,13 @@ class iscsi:
stdout = "/dev/tty5",
stderr = "/dev/tty5")
+ # ... and now we have to make it start automatically
+ argv = [ ISCSIADM, "-m", "node", "-r", "%s" %(recnum,),
+ "-o", "update", "-n", "node.startup",
+ "-v", "automatic" ]
+ iutil.execWithRedirect(argv[0], argv, searchPath = 1,
+ stdout = "/dev/tty5",
+ stderr = "/dev/tty5")
def shutdown(self):
if not self.iscsidStarted:
@@ -78,7 +88,7 @@ class iscsi:
self.iscsidStarted = False;
- def startup(self):
+ def startup(self, intf = None):
log.info("iSCSI IP address %s, port %s" % (self.ipaddr, self.port))
log.info("iSCSI initiator name %s", self.initiator)
@@ -91,6 +101,10 @@ class iscsi:
log.info("iSCSI: Not starting, no iscsi IP address specified")
return
+ if intf:
+ w = intf.waitWindow(_("Initializing iSCSI initiator"),
+ _("Initializing iSCSI initiator"))
+
log.debug("Setting up %s" % (INITIATOR_FILE, ))
if os.path.exists(INITIATOR_FILE):
os.unlink(INITIATOR_FILE)
@@ -112,6 +126,9 @@ class iscsi:
self.action("--login")
self.iscsidStarted = True
+ if intf:
+ w.pop()
+
def writeKS(self):
# XXX Useful if we have auto-generated kickstart files.
return
@@ -121,8 +138,8 @@ class iscsi:
os.write(fd, "InitiatorName=%s\n" %(self.initiator))
os.close(fd)
- if not os.path.isdir(instPath + "/var/db/iscsi"):
- iutil.mkdirChain(instPath + "/var/db/iscsi")
+ if not os.path.isdir(instPath + "/var/db"):
+ iutil.mkdirChain(instPath + "/var/db")
shutil.copytree("/var/db/iscsi", instPath + "/var/db/iscsi")
# vim:tw=78:ts=4:et:sw=4
diff --git a/isys/isys.py b/isys/isys.py
index 166f3fd27..9ec1cba04 100644
--- a/isys/isys.py
+++ b/isys/isys.py
@@ -26,6 +26,7 @@ import kudzu
import iutil
import warnings
import resource
+import re
import rhpl
import struct
@@ -465,9 +466,6 @@ for d in range(80, 80 + 15):
biosdisks[disk] = d
def compareDrives(first, second):
- type1 = first[0:2]
- type2 = second[0:2]
-
if biosdisks.has_key(first) and biosdisks.has_key(second):
one = biosdisks[first]
two = biosdisks[second]
@@ -476,17 +474,21 @@ def compareDrives(first, second):
elif (one > two):
return 1
- if type1 == "hd":
- type1 = 0
- elif type1 == "sd":
- type1 = 1
+ if first.startswith("hd"):
+ type1 = 0
+ elif first.startswith("sd"):
+ type1 = 1
+ elif first.startswith("xvd"):
+ type1 = -1
else:
- type1 = 2
+ type1 = 2
- if type2 == "hd":
- type2 = 0
- elif type2 == "sd":
+ if second.startswith("hd"):
+ type2 = 0
+ elif second.startswith("sd"):
type2 = 1
+ elif second.startswith("xvd"):
+ type2 = -1
else:
type2 = 2
@@ -789,6 +791,15 @@ def driveIsRemovable(device):
return False
+def driveIsIscsi(device):
+ # ewww. just ewww.
+ if not os.path.islink("/sys/block/%s/device" %(device,)):
+ return False
+ target = os.readlink("/sys/block/%s/device" %(device,))
+ if re.search("/platform/host[0-9]*/session[0-9]*/target[0-9]*:[0-9]*:[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*", target) is not None:
+ return True
+ return False
+
def vtActivate (num):
_isys.vtActivate (num)
diff --git a/iw/iscsi_gui.py b/iw/iscsi_gui.py
index efeefc3ff..e147c234c 100644
--- a/iw/iscsi_gui.py
+++ b/iw/iscsi_gui.py
@@ -39,12 +39,6 @@ class iscsiWindow(InstallWindow):
self.iscsi.port = self.port.get_text()
self.iscsi.initiator = self.initiator.get_text()
- w = self.intf.waitWindow(_("Initializing iSCSI initiator"), "")
- self.iscsi.startup()
- import time # XXX mmmm. hacktastic.
- time.sleep(5)
- w.pop()
-
return None
def getScreen(self, anaconda):
diff --git a/kickstart.py b/kickstart.py
index 63ed1e540..1e5c913df 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -184,6 +184,14 @@ class AnacondaKSHandlers(KickstartHandlers):
def doInteractive(self, id, args):
KickstartHandlers.doInteractive(self, args)
+ def doIscsi(self, id, args):
+ KickstartHandlers.doIscsi(self, args)
+ self.skipSteps.append("iscsi")
+
+ id.iscsi.ipaddr = self.ksdata.iscsi["target"]
+ id.iscsi.port = self.ksdata.iscsi["port"]
+ id.iscsi.initiator = self.ksdata.iscsi["initiator"]
+
def doKeyboard(self, id, args):
KickstartHandlers.doKeyboard(self, args)
id.instClass.setKeyboard(id, self.ksdata.keyboard)
diff --git a/partitioning.py b/partitioning.py
index 02351ff3a..0a6d5e28e 100644
--- a/partitioning.py
+++ b/partitioning.py
@@ -40,9 +40,16 @@ from rhpl.translate import _
def partitionObjectsInitialize(anaconda):
if anaconda.dir == DISPATCH_BACK:
anaconda.id.diskset.closeDevices()
+ anaconda.id.iscsi.shutdown()
isys.flushDriveDict()
return
+ # clean slate about drives
+ isys.flushDriveDict()
+
+ # ensure iscsi devs are up
+ anaconda.id.iscsi.startup(anaconda.intf)
+
# read in drive info
anaconda.id.diskset.refreshDevices(anaconda.intf, anaconda.id.partitions.reinitializeDisks,
anaconda.id.partitions.zeroMbr, anaconda.id.partitions.autoClearPartDrives)
@@ -52,6 +59,9 @@ def partitionObjectsInitialize(anaconda):
anaconda.id.partitions.setFromDisk(anaconda.id.diskset)
anaconda.id.partitions.setProtected(anaconda.dispatch)
+ # make sure we have all the device nodes we'll want
+ iutil.makeDriveDeviceNodes()
+
def partitioningComplete(anaconda):
if anaconda.dir == DISPATCH_BACK and anaconda.id.fsset.isActive():
rc = anaconda.intf.messageWindow(_("Installation cannot continue."),
diff --git a/yuminstall.py b/yuminstall.py
index cb43d11dd..0efc9c8ee 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -1000,6 +1000,9 @@ class YumBackend(AnacondaBackend):
if os.access("/tmp/zfcp.conf", os.R_OK):
shutil.copyfile("/tmp/zfcp.conf",
anaconda.rootPath + "/etc/zfcp.conf")
+ anaconda.id.network.write(anaconda.rootPath)
+ anaconda.id.iscsi.write(anaconda.rootPath)
+ anaconda.id.zfcp.write(anaconda.rootPath)
# make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly
f = open(anaconda.rootPath + "/etc/mtab", "w+")
@@ -1080,7 +1083,6 @@ class YumBackend(AnacondaBackend):
else:
w = anaconda.intf.waitWindow(_("Post Install"),
_("Performing post install configuration..."))
- anaconda.id.network.write(anaconda.rootPath)
self.copyExtraModules(anaconda)
diff --git a/zfcp.py b/zfcp.py
index bf05cb797..bd1dea8be 100644
--- a/zfcp.py
+++ b/zfcp.py
@@ -17,6 +17,7 @@ import string
import os
import iutil
import isys
+import shutil
from rhpl.translate import _, N_
@@ -234,6 +235,10 @@ class ZFCP:
# FIXME KH not implemented yet
return
+ def write(self, instPath):
+ if os.path.exists("/tmp/zfcp.conf"):
+ shutil.copyfile("/tmp/zfcp.conf", instPath + "/etc/zfcp.conf")
+
def readConfig(self):
self.fcpdevices = []
try: