diff options
author | Jeremy Katz <katzj@redhat.com> | 2006-09-19 19:09:14 +0000 |
---|---|---|
committer | Jeremy Katz <katzj@redhat.com> | 2006-09-19 19:09:14 +0000 |
commit | 4ee8f85a02dc6797cdaa281ac4ec6a8b4e5c0e0d (patch) | |
tree | 9904fe731a3da68119b6430f73e0c8928a6a8350 | |
parent | 5aff3ac0510d8075206eb8de2efaca6044601f8b (diff) | |
download | anaconda-4ee8f85a02dc6797cdaa281ac4ec6a8b4e5c0e0d.tar.gz anaconda-4ee8f85a02dc6797cdaa281ac4ec6a8b4e5c0e0d.tar.xz anaconda-4ee8f85a02dc6797cdaa281ac4ec6a8b4e5c0e0d.zip |
2006-09-19 Jeremy Katz <katzj@redhat.com>
* partitioning.py (partitionObjectsInitialize): Shutdown/startup
zfcp devs here
* yuminstall.py (YumBackend.doPreInstall): Remove spurious
zfcp.conf copy
* zfcp.py: Massive reworking to work better with new UI
* ui/zfcp-config.glade: ZFCP config dialog
* iw/autopart_type.py: Use zfcp config dialog (#204145)
* installclass.py (BaseInstallClass.setSteps): Remove explicit
zfcp step
* dispatch.py (installSteps): Likewise.
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | dispatch.py | 1 | ||||
-rw-r--r-- | installclass.py | 4 | ||||
-rw-r--r-- | iw/autopart_type.py | 32 | ||||
-rw-r--r-- | partitioning.py | 4 | ||||
-rw-r--r-- | ui/zfcp-config.glade | 276 | ||||
-rw-r--r-- | yuminstall.py | 3 | ||||
-rw-r--r-- | zfcp.py | 352 |
8 files changed, 495 insertions, 194 deletions
@@ -1,3 +1,20 @@ +2006-09-19 Jeremy Katz <katzj@redhat.com> + + * partitioning.py (partitionObjectsInitialize): Shutdown/startup + zfcp devs here + + * yuminstall.py (YumBackend.doPreInstall): Remove spurious + zfcp.conf copy + + * zfcp.py: Massive reworking to work better with new UI + + * ui/zfcp-config.glade: ZFCP config dialog + * iw/autopart_type.py: Use zfcp config dialog (#204145) + + * installclass.py (BaseInstallClass.setSteps): Remove explicit + zfcp step + * dispatch.py (installSteps): Likewise. + 2006-09-19 David Cantrell <dcantrell@redhat.com> * isys/Makefile: Make nltest target depend on str.o. diff --git a/dispatch.py b/dispatch.py index ee480fff2..91487bc89 100644 --- a/dispatch.py +++ b/dispatch.py @@ -66,7 +66,6 @@ installSteps = [ ("regkey", regKeyScreen, ), ("findrootparts", findRootParts, ), ("findinstall", ), - ("zfcpconfig", ), ("partitionobjinit", partitionObjectsInitialize, ), ("parttype", ), ("autopartitionexecute", doAutoPartition, ), diff --git a/installclass.py b/installclass.py index 3443f4644..8f7a3c70f 100644 --- a/installclass.py +++ b/installclass.py @@ -115,7 +115,6 @@ class BaseInstallClass: "findrootparts", "betanag", "installtype", - "zfcpconfig", "partitionobjinit", "parttype", "autopartitionexecute", @@ -154,9 +153,6 @@ class BaseInstallClass: if not BETANAG: dispatch.skipStep("betanag", permanent=1) - if rhpl.getArch() != "s390": - dispatch.skipStep("zfcpconfig", permanent=1) - if rhpl.getArch() != "i386" and rhpl.getArch() != "x86_64": dispatch.skipStep("bootloader", permanent=1) diff --git a/iw/autopart_type.py b/iw/autopart_type.py index bf64e5bcb..0f5084b5b 100644 --- a/iw/autopart_type.py +++ b/iw/autopart_type.py @@ -164,6 +164,36 @@ class PartitionTypeWindow(InstallWindow): dialog.destroy() return rc + + + def addZfcpDrive(self): + (dxml, dialog) = gui.getGladeWidget("zfcp-config.glade", + "zfcpDialog") + gui.addFrame(dialog) + dialog.show_all() + sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) + map(lambda x: sg.add_widget(dxml.get_widget(x)), + ("devnumEntry", "wwpnEntry", "fcplunEntry")) + + while 1: + rc = dialog.run() + if rc != gtk.RESPONSE_OK: + break + return rc + + devnum = dxml.get_widget("devnumEntry").get_text().strip() + wwpn = dxml.get_widget("wwpnEntry").get_text().strip() + fcplun = dxml.get_widget("fcplunEntry").get_text().strip() + + try: + self.anaconda.id.zfcp.addFCP(devnum, wwpn, fcplun) + except ValueError, e: + self.intf.messageWindow(_("Error"), e) + continue + break + + dialog.destroy() + return rc def addDrive(self, button): @@ -179,7 +209,7 @@ class PartitionTypeWindow(InstallWindow): if dxml.get_widget("iscsiRadio").get_active(): rc = self.addIscsiDrive() elif dxml.get_widget("zfcpRadio").get_active(): - print "do zfcp" + rc = self.addZfcpDrive() dialog.destroy() if rc != gtk.RESPONSE_CANCEL: diff --git a/partitioning.py b/partitioning.py index 5c5a60df7..01f173ef5 100644 --- a/partitioning.py +++ b/partitioning.py @@ -30,6 +30,7 @@ def partitionObjectsInitialize(anaconda): anaconda.id.diskset.closeDevices() anaconda.id.diskset.stopMdRaid() anaconda.id.iscsi.shutdown() + anaconda.id.zfcp.shutdown() # clean slate about drives isys.flushDriveDict() @@ -40,6 +41,9 @@ def partitionObjectsInitialize(anaconda): # ensure iscsi devs are up anaconda.id.iscsi.startup(anaconda.intf) + # ensure zfcp devs are up + anaconda.id.zfcp.startup() + # pull in the new iscsi drive isys.flushDriveDict() diff --git a/ui/zfcp-config.glade b/ui/zfcp-config.glade new file mode 100644 index 000000000..8a096734b --- /dev/null +++ b/ui/zfcp-config.glade @@ -0,0 +1,276 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkDialog" id="zfcpDialog"> + <property name="title" translatable="yes">Add FCP device</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_CENTER</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + <property name="has_separator">True</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child internal-child="action_area"> + <widget class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + + <child> + <widget class="GtkButton" id="button1"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-cancel</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-6</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="button2"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-add</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-10</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">GTK_PACK_END</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="label" translatable="yes">zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide a 16 bit device number, a 64 bit World Wide Port Name (WWPN), and a 64 bit FCP LUN for each device.</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">True</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkTable" id="zfcpTable"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="homogeneous">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + + <child> + <widget class="GtkLabel" id="devnumLabel"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Device number:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="devnumEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">•</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="wwwpnLabel"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>WWPN:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="wwpnEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="fcplunLabel"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>FCP LUN:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="fcplunEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options"></property> + <property name="y_options"></property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/yuminstall.py b/yuminstall.py index 041efac8f..0e8366587 100644 --- a/yuminstall.py +++ b/yuminstall.py @@ -1114,9 +1114,6 @@ class YumBackend(AnacondaBackend): if os.access("/tmp/modprobe.conf", os.R_OK): shutil.copyfile("/tmp/modprobe.conf", anaconda.rootPath + "/etc/modprobe.conf") - 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) @@ -23,59 +23,25 @@ from rhpl.translate import _, N_ import logging log = logging.getLogger("anaconda") +import warnings -class ZFCP: - def __init__(self): - self.description = _("zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide 5 parameters for each device: a 16 bit device number, a 16bit SCSI ID, a 64 bit World Wide Port Name (WWPN), a 16bit SCSI LUN and a 64 bit FCP LUN.") - self.options = [ - (_("Device number"), 1, - _("You have not specified a device number or the number is invalid"), - self.sanitizeDeviceInput, self.checkValidDevice), - (_("SCSI Id"), 0, - _("You have not specified a SCSI ID or the ID is invalid."), - self.sanitizeHexInput, self.checkValidID), - (_("WWPN"), 1, - _("You have not specified a worldwide port name or the name is invalid."), - self.sanitizeHexInput, self.checkValid64BitHex), - (_("SCSI LUN"), 0, - _("You have not specified a SCSI LUN or the number is invalid."), - self.sanitizeHexInput, self.checkValidID), - (_("FCP LUN"), 1, - _("You have not specified a FCP LUN or the number is invalid."), - self.sanitizeFCPLInput, self.checkValid64BitHex)] - self.readConfig() +class ZFCPDevice: + def __init__(self, devnum, wwpn, fcplun): + self.devnum = self.sanitizeDeviceInput(devnum) + self.wwpn = self.sanitizeWWPNInput(wwpn) + self.fcplun = self.sanitizeFCPLInput(fcplun) - def hextest(self, hex): - try: - int(hex, 16) - return 0 - except: - return -1 - - def checkValidDevice(self, id): - if id is None or id == "": - return -1 - if len(id) != 8: # p.e. 0.0.0600 - return -1 - if id[0] not in string.digits or id[2] not in string.digits: - return -1 - if id[1] != "." or id[3] != ".": - return -1 - return self.hextest(id[4:]) + if not self.checkValidDevice(self.devnum): + raise ValueError, _("You have not specified a device number or the number is invalid") + if not self.checkValidWWPN(self.wwpn): + raise ValueError, _("You have not specified a worldwide port name or the name is invalid.") + if not self.checkValidFCPLun(self.fcplun): + raise ValueError, _("You have not specified a FCP LUN or the number is invalid.") - def checkValidID(self, hex): - if hex is None or hex == "": - return -1 - if len(hex) > 6: - return -1 - return self.hextest(hex) + self.onlineStatus = False - def checkValid64BitHex(self, hex): - if hex is None or hex == "": - return -1 - if len(hex) != 18: - return -1 - return self.hextest(hex) + def __str__(self): + return "%s %s %s" %(self.devnum, self.wwpn, self.fcplun) def sanitizeDeviceInput(self, dev): if dev is None or dev == "": @@ -89,7 +55,7 @@ class ZFCP: else: return bus + dev - def sanitizeHexInput(self, id): + def sanitizeWWPNInput(self, id): if id is None or id == "": return None id = id.lower() @@ -109,159 +75,175 @@ class ZFCP: lun = lun + "0" * (16 - len(lun) + 2) return lun - - def updateConfig(self, fcpdevices, diskset, intf): - self.writeFcpSysfs(fcpdevices) - self.writeModprobeConf(fcpdevices) - self.writeZFCPconf(fcpdevices) - # XXX this should use partitions.partitionObjectsInitialize() - isys.flushDriveDict() - diskset.refreshDevices(intf) + def _hextest(self, hex): try: - iutil.makeDriveDeviceNodes() + int(hex, 16) + return True except: - pass + return False - # remove the configuration from sysfs, required when the user - # steps backward from the partitioning screen and changes fcp configuration - def cleanFcpSysfs(self, fcpdevices): - if not len(fcpdevices): - return - on = "/sys/bus/ccw/drivers/zfcp/%s/online" - pr = "/sys/bus/ccw/drivers/zfcp/%s/port_remove" - ur = "/sys/bus/ccw/drivers/zfcp/%s/%s/unit_remove" - for i in range(len(fcpdevices)): - fno = on % (fcpdevices[i][0],) - fnp = pr % (fcpdevices[i][0],) - fnu = ur % (fcpdevices[i][0],fcpdevices[i][2],) - try: - fo = open(fno, "w") - log.info("echo %s > %s" % (0, fno)) - fo.write("0") - fo.close() - try: - fu = open(fnu, "w") - log.info("echo %s > %s" % (fcpdevices[i][4], fnu)) - fu.write("%s\n" % (fcpdevices[i][4],)) - fu.close() - try: - fp = open(fnp, "w") - log.info("echo %s > %s" % (fcpdevices[i][2], fnp)) - fp.write("%s\n" % (fcpdevices[i][2],)) - fp.close() - except: - continue - except: - continue - except: - continue + def checkValidDevice(self, id): + if id is None or id == "": + return False + if len(id) != 8: # p.e. 0.0.0600 + return False + if id[0] not in string.digits or id[2] not in string.digits: + return False + if id[1] != "." or id[3] != ".": + return False + return self._hextest(id[4:]) + + def checkValid64BitHex(self, hex): + if hex is None or hex == "": + return False + if len(hex) != 18: + return False + return self._hextest(hex) + checkValidWWPN = checkValidFCPLun = checkValid64BitHex + + def onlineDevice(self): + if self.onlineStatus: + return True + + online = "/sys/bus/ccw/drivers/zfcp/%s/online" %(self.devnum,) + portadd = "/sys/bus/ccw/drivers/zfcp/%s/port_add" %(self.devnum,) + unitadd = "/sys/bus/ccw/drivers/zfcp/%s/%s/unit_add" %(self.devnum, + self.wwpn) + try: + if not os.path.exists(unitadd): + f = open(portadd, "w") + log.debug("echo %s > %s" % (self.wwpn, portadd)) + f.write("%s\n" % (self.wwpn,)) + f.close() + + f = open(unitadd, "w") + log.debug("echo %s > %s" % (self.fcplun, unitadd)) + f.write("%s\n" % (self.fcplun,)) + f.close() + + f = open(online, "w") + log.debug("echo %s > %s" % (1, online)) + f.write("1") + f.close() + except Exception, e: + log.warn("error bringing zfcp device %s online: %s" + %(self.devnum, e)) + return False + + self.onlineStatus = True + return True + + def offlineDevice(self): + if not self.offlineStatus: + return True + + offline = "/sys/bus/ccw/drivers/zfcp/%s/offline" %(self.devnum,) + portremove = "/sys/bus/ccw/drivers/zfcp/%s/port_remove" %(self.devnum,) + unitremove = "/sys/bus/ccw/drivers/zfcp/%s/%s/unit_remove" %(self.devnum, + self.wwpn) - # initialize devices via sysfs - def writeFcpSysfs(self,fcpdevices): - if not len(fcpdevices): - return - on = "/sys/bus/ccw/drivers/zfcp/%s/online" - pa = "/sys/bus/ccw/drivers/zfcp/%s/port_add" - ua = "/sys/bus/ccw/drivers/zfcp/%s/%s/unit_add" - for i in range(len(fcpdevices)): - fno = on % (fcpdevices[i][0],) - fnp = pa % (fcpdevices[i][0],) - fnu = ua % (fcpdevices[i][0],fcpdevices[i][2],) - try: - fp = open(fnp, "w") - log.info("echo %s > %s" % (fcpdevices[i][2], fnp)) - fp.write("%s\n" % (fcpdevices[i][2],)) - fp.close() - try: - fu = open(fnu, "w") - log.info("echo %s > %s" % (fcpdevices[i][4], fnu)) - fu.write("%s\n" % (fcpdevices[i][4],)) - fu.close() - try: - fo = open(fno, "w") - log.info("echo %s > %s" % (1, fno)) - fo.write("1") - fo.close() - except: - log.warning("opening %s failed" %(fno,)) - continue - except: - log.warning("opening %s failed" %(fnu,)) - continue - except: - log.warning("opening %s failed" %(fnp,)) - continue - - def writeModprobeConf(self, fcpdevices): - lines = [] try: - f = open("/tmp/modprobe.conf", "r") - lines = f.readlines() + f = open(offline, "w") + log.debug("echo %s > %s" % (0, offline)) + f.write("0") f.close() + + f = open(unitremove, "w") + log.debug("echo %s > %s" %(self.fcplun, unitremove)) + f.write("%s\n" %(self.fcplun,)) + f.close() + + f = open(portremove, "w") + log.debug("echo %s > %s" %(self.wwpn, portremove)) + f.write("%s\n" %(self.wwpn,)) + f.close() + except Exception, e: + log.warn("error bringing zfcp device %s offline: %s" + %(self.devnum, e)) + return False + + self.onlineStatus = False + return True + +class ZFCP: + def __init__(self): + self.fcpdevs = [] + + self.readConfig() + + def readConfig(self): + try: + f = open("/tmp/fcpconfig", "r") except: - pass - foundalias = 0 + log.info("no /tmp/fcpconfig; not configuring zfcp") + return + + lines = f.readlines() + f.close() for line in lines: - if string.find(string.strip(line), "alias scsi_hostadapter zfcp") == 0: - foundalias = 1 - break - if len(fcpdevices): - if not foundalias: - try: - f = open("/tmp/modprobe.conf", "a") - f.write("alias scsi_hostadapter zfcp\n") - f.close() - except: - pass - if not len(fcpdevices): - if foundalias: - try: - f = open("/tmp/modprobe.conf", "w") - for line in lines: - if string.find(string.strip(line), "alias scsi_hostadapter zfcp") != 0: - f.write(line) - f.close() - except: - pass - - def writeZFCPconf(self, fcpdevices): - if not len(fcpdevices): + # each line is a string separated list of values to describe a dev + # there are two valid formats for the line: + # devnum scsiid wwpn scsilun fcplun (scsiid + scsilun ignored) + # devnum wwpn fcplun + line = string.strip(line).lower() + if line.startswith("#"): + continue + fcpconf = string.split(line) + if len(fcpconf) == 3: + devnum = fcpconf[0] + wwpn = fcpconf[1] + fcplun = fcpconf[2] + elif len(fcpconf) == 5: + warnings.warn("SCSI ID and SCSI LUN values for ZFCP devices are ignored and deprecated.", DeprecationWarning) + devnum = fcpconf[0] + wwpn = fcpconf[2] + fcplun = fcpconf[4] + else: + log.warn("Invalid line found in /tmp/fcpconfig!") + continue + + try: + self.addFCP(devnum, wwpn, fcplun) + except ValueError, e: + log.warn("Invalid FCP device configuration: %s" %(e,)) + continue + + def addFCP(self, devnum, wwpn, fcplun): + d = ZFCPDevice(devnum, wwpn, fcplun) + if d.onlineDevice(): + self.fcpdevs.append(d) + f = open("/tmp/zfcp.conf", "a") + f.write("%s\n" %(d,)) + f.close() + + def shutdown(self): + if len(self.fcpdevs) == 0: return - f = open("/tmp/zfcp.conf", "w") - for dev in fcpdevices: - f.write("%s %s %s %s %s\n" % (dev[0], dev[1], dev[2], dev[3], dev[4],)) + for d in self.fcpdevs: + d.offlineDevice() + # empty zfcp.conf as we'll write things back out when we initialize + f = open("/tmp/zfcp.conf", "w+") f.close() + def startup(self): + if len(self.fcpdevs) == 0: + return + for d in self.fcpdevs: + if d.onlineDevice(): + f = open("/tmp/zfcp.conf", "a") + f.write("%s\n" %(d,)) + f.close() + def writeKS(self,fcpdevices): # FIXME KH not implemented yet return def write(self, instPath): + if len(self.fcpdevs) == 0: + return if os.path.exists("/tmp/zfcp.conf"): shutil.copyfile("/tmp/zfcp.conf", instPath + "/etc/zfcp.conf") - - def readConfig(self): - self.fcpdevices = [] - try: - f = open("/tmp/fcpconfig", "r") - except: - pass else: - lines = f.readlines() - f.close() - for line in lines: - invalid = 0 - line = string.strip(line).lower() - fcpconf = string.split(line) - if len(fcpconf) != 5 or fcpconf[0][:1] == "#": - continue - for i in range(len(self.options)): - fcpconf[i] = self.options[i][3](fcpconf[i]) - if self.options[i][4](fcpconf[i]) == -1: - invalid = 1 - break - if not invalid: - self.fcpdevices.append(fcpconf) - + return # vim:tw=78:ts=4:et:sw=4 |