summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Katz <katzj@redhat.com>2006-09-19 19:09:14 +0000
committerJeremy Katz <katzj@redhat.com>2006-09-19 19:09:14 +0000
commit4ee8f85a02dc6797cdaa281ac4ec6a8b4e5c0e0d (patch)
tree9904fe731a3da68119b6430f73e0c8928a6a8350
parent5aff3ac0510d8075206eb8de2efaca6044601f8b (diff)
downloadanaconda-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--ChangeLog17
-rw-r--r--dispatch.py1
-rw-r--r--installclass.py4
-rw-r--r--iw/autopart_type.py32
-rw-r--r--partitioning.py4
-rw-r--r--ui/zfcp-config.glade276
-rw-r--r--yuminstall.py3
-rw-r--r--zfcp.py352
8 files changed, 495 insertions, 194 deletions
diff --git a/ChangeLog b/ChangeLog
index e022db68a..dec8da116 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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">&lt;b&gt;Device number:&lt;/b&gt;</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">&lt;b&gt;WWPN:&lt;/b&gt;</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">&lt;b&gt;FCP LUN:&lt;/b&gt;</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)
diff --git a/zfcp.py b/zfcp.py
index cdbe84e02..0a8667181 100644
--- a/zfcp.py
+++ b/zfcp.py
@@ -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