[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Various iSCSI fixes [PATCH 3/4]: anaconda-iscsi-rhel5-to-master1.patch



Hi All,

Forward port the following rhel5 iscsi changes to master:
96255750791e859dd06004fe1fbcc101a26e9e47 Add support for iSCSI iBFT table to an d410362972805fa50444f9bd4bbfd4c985ae0313 Make iscsi/ibft work; with this it at ad6c2adda67b1f1d77ad0d1db9a5c75e7e20cb3f Fix iscsi so that mkinitrd can actuall a4a4a5ecf8dca9fa121f5ad06dd7b949fc02b37b Make sure ISCSIADM and such are define 0d7795b5d06b5449f0b2c0c6c5028ea99104d9ca Better fixes for iscsi probing (patch 059c0ca2c34c123173041751b5c7337b0215242a Set an attribute when iscsid is starte 6b4b816bb9305d740db2e5c499a73968e564a9b7 Fix wrong function names for iscsi log

Regards,

Hans
Forward port the following rhel5 iscsi changes to master:
96255750791e859dd06004fe1fbcc101a26e9e47 Add support for iSCSI iBFT table to anaconda and use the configured targets in it (#307761)
d410362972805fa50444f9bd4bbfd4c985ae0313 Make iscsi/ibft work; with this it at least detects the iBFT and finds the disks.
ad6c2adda67b1f1d77ad0d1db9a5c75e7e20cb3f Fix iscsi so that mkinitrd can actually talk to the running daemon
a4a4a5ecf8dca9fa121f5ad06dd7b949fc02b37b Make sure ISCSIADM and such are defined (rhbz#431924)
0d7795b5d06b5449f0b2c0c6c5028ea99104d9ca Better fixes for iscsi probing (patch from jlaska)
059c0ca2c34c123173041751b5c7337b0215242a Set an attribute when iscsid is started (#431904).
6b4b816bb9305d740db2e5c499a73968e564a9b7 Fix wrong function names for iscsi login/start (rhbz#295154)
diff --git a/iscsi.py b/iscsi.py
index da60d76..a00a43d 100644
--- a/iscsi.py
+++ b/iscsi.py
@@ -35,14 +35,34 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
 
 
 # Note that stage2 copies all files under /sbin to /usr/sbin
-ISCSID="/usr/sbin/iscsid"
-ISCSIADM = "/usr/sbin/iscsiadm"
+global ISCSID
+ISCSID=""
+global ISCSIADM
+ISCSIADM = ""
 INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
 
+def find_iscsi_files():
+    global ISCSID
+    if ISCSID == "":
+        for dir in ("/usr/sbin", "/tmp/updates", "/mnt/source/RHupdates"):
+            path="%s/iscsid" % (dir,)
+            if os.access(path, os.X_OK):
+                ISCSID=path
+    global ISCSIADM
+    if ISCSIADM == "":
+        for dir in ("/usr/sbin", "/tmp/updates", "/mnt/source/RHupdates"):
+            path="%s/iscsiadm" % (dir,)
+            if os.access(path, os.X_OK):
+                ISCSIADM=path
 
 def has_iscsi():
-    if not os.access(ISCSID, os.X_OK) or not os.access(ISCSIADM, os.X_OK):
+    find_iscsi_files()
+    if ISCSID == "" or ISCSIADM == "":
         return False
+
+    log.info("ISCSID is %s" % (ISCSID,))
+    log.info("ISCSIADM is %s" % (ISCSIADM,))
+
     # make sure the module is loaded
     if not os.access("/sys/module/iscsi_tcp", os.X_OK):
         return False
@@ -60,6 +80,8 @@ class iscsiTarget:
         self._portal = None
         self._nodes = []
 
+        find_iscsi_files()
+
     def _getPortal(self):
         if self._portal is None:
             argv = [ "-m", "discovery", "-t", "st", "-p", self.ipaddr ]
@@ -80,18 +102,16 @@ class iscsiTarget:
                     self._portal = portal
                     self._nodes.append(node)
         return self._portal
+    portal = property(_getPortal)
+
     def _getNode(self):
         if len(self._nodes) == 0:
             # _getPortal() fills the list, if possible.
             self._getPortal()
         return self._nodes
-    portal = property(_getPortal)
     nodes = property(_getNode)
 
     def discover(self):
-        if flags.test:
-            return True
-
         argv = [ "-m", "discovery", "-t", "st", "-p", 
                  "%s:%s" % (self.ipaddr, self.port) ]
         log.debug("iscsiadm %s" %(string.join(argv),))
@@ -102,33 +122,35 @@ class iscsiTarget:
             return False
         return True
 
+    def startNode(self, node):
+        argv = [ "-m", "node", "-T", node, "-p", self.portal,
+                 "-o", "update", "-n", "node.conn[0].startup",
+                 "-v", "automatic" ]
+        log.debug("iscsiadm %s" %(string.join(argv),))
+        iutil.execWithRedirect(ISCSIADM, argv,
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+
+    def loginToNode(self, node):
+        argv = [ "-m", "node", "-T", node, "-p", self.portal, "--login" ]
+        log.debug("iscsiadm %s" %(string.join(argv),))
+        rc = iutil.execWithRedirect(ISCSIADM, argv,
+                                    stdout = "/dev/tty5", stderr="/dev/tty5")
+        if rc != 0:
+            log.warn("iscsiadm failed to login to %s" %(self.ipaddr,))
+            return False
+        return True
+
     def login(self):
         if len(self.nodes) == 0 or self.portal is None:
             log.warn("unable to find portal information")
             return False
-        def _login(node, portal):
-            argv = [ "-m", "node", "-T", node, "-p", portal, "--login" ]
-            log.debug("iscsiadm %s" %(string.join(argv),))
-            rc = iutil.execWithRedirect(ISCSIADM, argv,
-                                    stdout = "/dev/tty5", stderr="/dev/tty5")
-            if rc != 0:
-                log.warn("iscsiadm failed to login to %s" %(self.ipaddr,))
-                return False
-            return True
-
-        def _autostart(node, portal):
-            argv = [ "-m", "node", "-T", node, "-p", portal,
-                     "-o", "update", "-n", "node.conn[0].startup",
-                     "-v", "automatic" ]
-            log.debug("iscsiadm %s" %(string.join(argv),))
-            iutil.execWithRedirect(ISCSIADM, argv,
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
+
 
         ret = False
         for node in self.nodes:
-            if _login(node, self.portal):
+            if self.loginToNode(node):
                 ret = True
-                _autostart(node, self.portal)
+                self.startNode(node)
 
         # we return True if there were any successful logins for our portal.
         return ret
@@ -140,6 +162,7 @@ class iscsiTarget:
             rc = iutil.execWithRedirect(ISCSIADM, argv,
                                     stdout = "/dev/tty5", stderr="/dev/tty5")
 
+
 def randomIname():
     """Generate a random initiator name the same way as iscsi-iname"""
     
@@ -156,59 +179,158 @@ def randomIname():
 
 class iscsi(object):
     def __init__(self):
+        self.fwinfo = self._queryFirmware()
         self.targets = []
         self._initiator = ""
         self.initiatorSet = False
+        self.oldInitiatorFile = None
         self.iscsidStarted = False
 
+        if self.fwinfo and self.fwinfo.has_key("iface.initiatorname"):
+            self._initiator = self.fwinfo["iface.initiatorname"]
+            self.initiatorSet = True
+            self.startup()
+
     def _getInitiator(self):
         if self._initiator != "":
             return self._initiator
-        return randomIname()
+
+        if self.fwinfo and self.fwinfo.has_key("iface.initiatorname"):
+            return self.fwinfo["iface.initiatorname"]
+        else:
+            return randomIname()
+
     def _setInitiator(self, val):
         if self._initiator != "" and val != self._initiator:
             raise ValueError, "Unable to change iSCSI initiator name once set"
         if len(val) == 0:
             raise ValueError, "Must provide a non-zero length string"
         self._initiator = val
-        self.initiatorSet = True        
+        self.initiatorSet = True
+
     initiator = property(_getInitiator, _setInitiator)
 
-    def shutdown(self):
-        if not self.iscsidStarted:
+    def _queryFirmware(self):
+        # Example:
+        # [root elm3b87 ~]# iscsiadm -m fw
+        # iface.initiatorname = iqn.2007-05.com.ibm.beaverton.elm3b87:01
+        # iface.hwaddress = 00:14:5e:b3:8e:b2
+        # node.name = iqn.1992-08.com.netapp:sn.84183797
+        # node.conn[0].address = 9.47.67.152
+        # node.conn[0].port = 3260
+
+        find_iscsi_files()
+
+        if not has_iscsi():
             return
 
-        log.info("iSCSI shutdown")
-        for t in self.targets:
-            t.logout()
+        retval = {}
+
+        argv = [ "-m", "fw" ]
+        log.debug("queryFirmware: ISCSIADM is %s" % (ISCSIADM,))
+        result = iutil.execWithCapture(ISCSIADM, argv)
+        result = result.strip()
+        for line in result.split("\n"):
+            SPLIT = " = "
+            idx = line.find(SPLIT)
+            if idx != -1:
+                lhs = line[:idx]
+                rhs = line[idx+len(SPLIT):]
+                retval[lhs] = rhs
+
+        return retval
+
+    def _startIscsiDaemon(self):
+        psout = iutil.execWithCapture("/usr/bin/pidof", ["iscsid"])
+        if psout.strip() == "":
+            log.info("iSCSI startup")
+            iutil.execWithRedirect(ISCSID, [],
+                                   stdout="/dev/tty5", stderr="/dev/tty5")
+            self.iscsidStarted = True
+            time.sleep(2)
+
+    def _stopIscsiDaemon(self):
+        result = iutil.execWithCapture(ISCSIADM, ["-k", "0"])
+        result.strip()
+        if result == "":
+            return
 
-        # XXX use iscsiadm shutdown when it's available.
-        psout = iutil.execWithCapture("/usr/bin/pidof", ["iscsiadm"])
+        psout = iutil.execWithCapture("/usr/bin/pidof", ["iscsid"])
         if psout.strip() != "":
-            pid = string.atoi(psout.split()[0])
-            log.info("Killing %s %d" % (ISCSID, pid))
-            os.kill(pid, signal.SIGKILL)
+            log.info("iSCSI shutdown")
+            for t in self.targets:
+                t.logout()
 
-        self.iscsidStarted = False;
+            for pidstr in psout.split():
+                pid = string.atoi(pidstr)
+                login.info("killing %s %d" % (ISCSID, pid))
 
-    def startup(self, intf = None):
-        if flags.test:
+                os.kill(pid, signal.SIGKILL)
+
+            self.iscsidStarted = False
+
+    def shutdown(self):
+        if not has_iscsi():
             return
+
+        if flags.test:
+            if self.oldInitiatorFile != None:
+                f = open(INITIATOR_FILE, "w")
+                for line in self.oldInitiatorFile:
+                    f.write(line)
+                f.close ()
+                self.oldInitiatorFile = None
+        self._stopIscsiDaemon()
+
+    def loginToDefaultDrive(self):
+        # Example:
+        # [root elm3b87 ~]# iscsiadm -m fw -l
+        # Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.84183797, portal: 9.47.67.152,3260]
+
+        find_iscsi_files()
+
+        argv = [ "-m", "fw", "-l" ]
+        result = iutil.execWithCapture(ISCSIADM, argv)
+
+        TARGET = "target: "
+        PORTAL = ", portal: "
+        END = "]"
+        idxTarget = result.find(TARGET)
+        idxPortal = result.find(PORTAL)
+        idxEnd = result.find(END)
+
+        if idxTarget == -1 or idxPortal == -1 or idxEnd == -1:
+            return None
+
+        target = result[idxTarget + len(TARGET) : idxPortal]
+        portal = result[idxPortal + len(PORTAL) : idxEnd]
+        port = 3260
+        idxPort = portal.find(',')
+        if idxPort != -1:
+            port = portal[idxPort + 1 :]
+            portal = portal[:idxPort]
+
+        return (target, portal, port)
+
+    def startup(self, intf = None):
         if not has_iscsi():
             return
+
         if not self.initiatorSet:
             log.info("no initiator set")
             return
-        if self.iscsidStarted:
-            return
-        
-        log.info("iSCSI initiator name %s", self.initiator)
+        if flags.test:
+            if os.access(INITIATOR_FILE, os.R_OK):
+                f = open(INITIATOR_FILE, "r")
+                self.oldInitiatorFile = f.readlines()
+                f.close()
 
         if intf:
             w = intf.waitWindow(_("Initializing iSCSI initiator"),
                                 _("Initializing iSCSI initiator"))
 
         log.debug("Setting up %s" % (INITIATOR_FILE, ))
+        log.info("iSCSI initiator name %s", self.initiator)
         if os.path.exists(INITIATOR_FILE):
             os.unlink(INITIATOR_FILE)
         if not os.path.isdir("/etc/iscsi"):
@@ -217,11 +339,29 @@ class iscsi(object):
         os.write(fd, "InitiatorName=%s\n" %(self.initiator))
         os.close(fd)
 
-        log.info("ISCSID is %s", ISCSID)
-        iutil.execWithRedirect(ISCSID, [],
-                               stdout="/dev/tty5", stderr="/dev/tty5")
-        self.iscsidStarted = True
-        time.sleep(2)
+        if not os.path.isdir("/var/lib/iscsi"):
+            os.makedirs("/var/lib/iscsi", 0660)
+        for dir in ['nodes','send_targets','ifaces']:
+            fulldir = "/var/lib/iscsi/%s" % (dir,)
+            if not os.path.isdir(fulldir):
+                os.makedirs(fulldir, 0660)
+
+        self._startIscsiDaemon()
+
+        # If there is a default drive in the iSCSI configuration, then
+        # automatically attach to it. Do this before testing the initiator
+        # name, because it is provided by the iBFT too
+
+        # this will actually log us in, but it won't create the iscsi db
+        # entries.
+        default = self.loginToDefaultDrive()
+        if not default is None:
+            (node, ipaddr, port) = default
+            t = iscsiTarget(ipaddr, port, None, None)
+            # this actually creates the entries.
+            t.discover()
+            # and this sets them to auto-start
+            t.startNode(node)
 
         for t in self.targets:
             if not t.discover():
@@ -263,17 +403,18 @@ class iscsi(object):
         if not self.initiatorSet:
             return
 
-        if not os.path.isdir(instPath + "/etc/iscsi"):
-            os.makedirs(instPath + "/etc/iscsi", 0755)
-        fd = os.open(instPath + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
-        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
-        os.close(fd)
-
-        # copy "db" files.  *sigh*
-        if not os.path.isdir(instPath + "/var/lib/iscsi"):
-            os.makedirs(instPath + "/var/lib/iscsi", 0755)
-        for d in ("/var/lib/iscsi/nodes", "/var/lib/iscsi/send_targets"):
-            if os.path.isdir(d):
-                shutil.copytree(d, instPath + d)
+        if not flags.test:
+            if not os.path.isdir(instPath + "/etc/iscsi"):
+                os.makedirs(instPath + "/etc/iscsi", 0755)
+            fd = os.open(instPath + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
+            os.write(fd, "InitiatorName=%s\n" %(self.initiator))
+            os.close(fd)
+
+            # copy "db" files.  *sigh*
+            if not os.path.isdir(instPath + "/var/lib/iscsi"):
+                os.makedirs(instPath + "/var/lib/iscsi", 0755)
+            for d in ("/var/lib/iscsi/nodes", "/var/lib/iscsi/send_targets"):
+                if os.path.isdir(d):
+                    shutil.copytree(d, instPath + d)
 
 # vim:tw=78:ts=4:et:sw=4
diff --git a/loader/loader.c b/loader/loader.c
index 9b524e1..4211988 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -1937,7 +1937,7 @@ int main(int argc, char ** argv) {
     if (isVioConsole())
         setenv("TERM", "vt100", 1);
 
-    mlLoadModuleSet("cramfs:vfat:nfs:loop:floppy:edd:pcspkr:squashfs:ext4dev:ext3:ext2:iscsi_tcp");
+    mlLoadModuleSet("cramfs:vfat:nfs:loop:floppy:edd:pcspkr:squashfs:ext4dev:ext3:ext2:iscsi_tcp:iscsi_ibft");
 
     if (!FL_NOIPV6(flags))
         mlLoadModule("ipv6", NULL);
diff --git a/scripts/mk-images b/scripts/mk-images
index 279833b..fa32513 100755
--- a/scripts/mk-images
+++ b/scripts/mk-images
@@ -110,7 +110,7 @@ COMMONMODS="fat vfat nfs sunrpc lockd floppy cramfs loop edd pcspkr squashfs ipv
 USBMODS="ohci-hcd uhci-hcd ehci-hcd hid mousedev usb-storage sd_mod sr_mod ub appletouch"
 FIREWIREMODS="ohci1394 sbp2 fw-ohci fw-sbp2 firewire-sbp2 firewire-ohci"
 IDEMODS="ide-cd ide-cd_mod"
-SCSIMODS="sr_mod sg st sd_mod scsi_mod iscsi_tcp"
+SCSIMODS="sr_mod sg st sd_mod scsi_mod iscsi_tcp iscsi_ibft"
 FSMODS="fat msdos vfat ext2 ext3 ext4dev reiserfs jfs xfs gfs2 lock_nolock cifs"
 LVMMODS="dm-mod dm-zero dm-snapshot dm-mirror dm-multipath dm-round-robin dm-emc dm-crypt"
 RAIDMODS="raid0 raid1 raid5 raid6 raid456 raid10 linear"

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]