This patch is from Fedora. The problem is that some distros are starting 
iscsid in anticipation that iscsi might be needed, and it turns out it 
might never be :( So this patch has the iscsi tools start iscsid only 
when they first need it for login/discovery.

The original patch had some Fedora start command hardcoded. I modified 
that patch so in the attached, you set the startup command in 
/etc/iscsi/iscsid.conf. For upstream I just have it start iscsid. When I 
merge the patch I will modify it to run some command in the init script 
so that everything gets set up right (subsys locks get touched, and 
modules are loaded).

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

>From 7c9040a7a3f5a433f674f3544317164a60feee63 Mon Sep 17 00:00:00 2001
From: Mike Christie <micha...@cs.wisc.edu>
Date: Sat, 7 Feb 2009 00:23:06 -0600
Subject: [PATCH] iscsid: start iscsid automatically when needed

>From  Hans de Goede:

Make iscsiadm start iscsid when needed so that iscsid will not actually be
started even if there are no iscsi disks configured yet.

>From Mike Chrisite:

Orignal path had Fedora startup string hard coded. Modified
patch so that it got read from iscsid.conf.
---
 etc/iscsid.conf    |   16 ++++++++
 usr/discovery.c    |    6 ++--
 usr/idbm.c         |   61 -------------------------------
 usr/iscsiadm.c     |    8 ++--
 usr/iscsid.c       |    2 +-
 usr/iscsistart.c   |    4 +-
 usr/session_info.c |    2 +-
 usr/util.c         |  103 +++++++++++++++++++++++++++++++++++++++++++++++-----
 usr/util.h         |    8 +++-
 9 files changed, 127 insertions(+), 83 deletions(-)

diff --git a/etc/iscsid.conf b/etc/iscsid.conf
index 4f6e08a..3b31bd0 100644
--- a/etc/iscsid.conf
+++ b/etc/iscsid.conf
@@ -14,6 +14,22 @@
 #isns.address = 192.168.0.1
 #isns.port = 3205
 
+######################
+# iscsid daemon config
+######################
+# If you want iscsid to start the first time a iscsi tool
+# needs to access it, instead of starting it when the init
+# scripts run, set the iscsid startup command here. This
+# should normally only need to be done by distro package
+# maintainers.
+#
+# Default for Fedora and RHEL. (uncomment to activate).
+# iscsid.startup = /etc/rc.d/init.d/iscsid force-start
+# 
+# Default for upstream open-iscsi scripts (uncomment to activate).
+iscsid.startup = /sbin/iscsid
+
+
 #############################
 # NIC/HBA and driver settings
 #############################
diff --git a/usr/discovery.c b/usr/discovery.c
index dab6249..01ef6f5 100644
--- a/usr/discovery.c
+++ b/usr/discovery.c
@@ -87,7 +87,7 @@ int discovery_offload_sendtargets(int host_no, int do_login,
         * and get back the results. We should do this since it would
         * allows us to then process the results like software iscsi.
         */
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 1);
        if (rc) {
                log_error("Could not offload sendtargets to %s.\n",
                          drec->address);
@@ -521,7 +521,7 @@ static int request_initiator_name(void)
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_CONFIG_INAME;
 
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 1);
        if (rc)
                return EIO;
 
@@ -531,7 +531,7 @@ static int request_initiator_name(void)
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_CONFIG_IALIAS;
 
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 0);
        if (rc)
                /* alias is optional so return ok */
                return 0;
diff --git a/usr/idbm.c b/usr/idbm.c
index 6d7aa92..9a72191 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -127,67 +127,6 @@ static struct idbm *db;
        _n++; \
 } while(0)
 
-/*
- * from linux kernel
- */
-static char *strstrip(char *s)
-{
-       size_t size;
-       char *end;
-
-       size = strlen(s);
-       if (!size)
-               return s;
-
-       end = s + size - 1;
-       while (end >= s && isspace(*end))
-               end--;
-       *(end + 1) = '\0';
-
-       while (*s && isspace(*s))
-               s++;
-
-       return s;
-}
-
-static char *get_global_string_param(char *pathname, const char *key)
-{
-       FILE *f = NULL;
-       int len;
-       char *line, buffer[1024];
-       char *name = NULL;
-
-       if (!pathname) {
-               log_error("No pathname to load %s from", key);
-               return NULL;
-       }
-
-       len = strlen(key);
-       if ((f = fopen(pathname, "r"))) {
-               while ((line = fgets(buffer, sizeof (buffer), f))) {
-
-                       line = strstrip(line);
-
-                       if (strncmp(line, key, len) == 0) {
-                               char *end = line + len;
-
-                               /*
-                                * make sure ther is something after the
-                                * key.
-                                */
-                               if (strlen(end))
-                                       name = strdup(line + len);
-                       }
-               }
-               fclose(f);
-               if (name)
-                       log_debug(5, "%s=%s", key, name);
-       } else
-               log_error("can't open %s configuration file %s", key, pathname);
-
-       return name;
-}
-
 char *get_iscsi_initiatorname(char *pathname)
 {
        char *name;
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index bec9a4d..c0a43db 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -192,7 +192,7 @@ static void kill_iscsid(int priority)
 
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_IMMEDIATE_STOP;
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 0);
        if (rc) {
                iscsid_handle_error(rc);
                log_error("Could not stop iscsid. Trying sending iscsid "
@@ -791,7 +791,7 @@ static char *get_config_file(void)
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_CONFIG_FILE;
 
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 1);
        if (rc)
                return NULL;
 
@@ -841,7 +841,7 @@ session_stats(void *data, struct session_info *info)
        req.command = MGMT_IPC_SESSION_STATS;
        req.u.session.sid = info->sid;
 
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 1);
        if (rc)
                return EIO;
 
@@ -1307,7 +1307,7 @@ static int isns_dev_attr_query(discovery_rec_t *drec,
        memset(&req, 0, sizeof(iscsiadm_req_t));
        req.command = MGMT_IPC_ISNS_DEV_ATTR_QUERY;
 
-       err = do_iscsid(&req, &rsp);
+       err = do_iscsid(&req, &rsp, 1);
        if (err) {
                iscsid_handle_error(err);
                return EIO;
diff --git a/usr/iscsid.c b/usr/iscsid.c
index 63dbf77..94f43f7 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -253,7 +253,7 @@ static int sync_session(void *data, struct session_info 
*info)
        req.u.session.sid = info->sid;
        memcpy(&req.u.session.rec, &rec, sizeof(node_rec_t));
 
-       do_iscsid(&req, &rsp);
+       do_iscsid(&req, &rsp, 0);
        return 0;
 }
 
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
index c04750c..dbc7cb8 100644
--- a/usr/iscsistart.c
+++ b/usr/iscsistart.c
@@ -113,7 +113,7 @@ static int stop_event_loop(void)
 
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_IMMEDIATE_STOP;
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 0);
        if (rc) {
                iscsid_handle_error(rc);
                log_error("Could not stop event_loop\n");
@@ -144,7 +144,7 @@ static int login_session(void)
        memset(&req, 0, sizeof(req));
        req.command = MGMT_IPC_SESSION_LOGIN;
        memcpy(&req.u.session.rec, &config_rec, sizeof(node_rec_t));
-       rc = do_iscsid(&req, &rsp);
+       rc = do_iscsid(&req, &rsp, 0);
        if (rc)
                iscsid_handle_error(rc);
        return rc;
diff --git a/usr/session_info.c b/usr/session_info.c
index a2be9bf..15337bb 100644
--- a/usr/session_info.c
+++ b/usr/session_info.c
@@ -107,7 +107,7 @@ static int print_iscsi_state(int sid, char *prefix)
        req.command = MGMT_IPC_SESSION_INFO;
        req.u.session.sid = sid;
 
-       err = do_iscsid(&req, &rsp);
+       err = do_iscsid(&req, &rsp, 1);
        /*
         * for drivers like qla4xxx, iscsid does not display
         * anything here since it does not know about it.
diff --git a/usr/util.c b/usr/util.c
index 48f90cd..27a670f 100644
--- a/usr/util.c
+++ b/usr/util.c
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <ctype.h>
 #include <sys/un.h>
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -119,9 +120,88 @@ int increase_max_files(void)
        return 0;
 }
 
+/*
+ * from linux kernel
+ */
+char *strstrip(char *s)
+{
+       size_t size;
+       char *end;
+
+       size = strlen(s);
+       if (!size)
+               return s;
+
+       end = s + size - 1;
+       while (end >= s && isspace(*end))
+               end--;
+       *(end + 1) = '\0';
+
+       while (*s && isspace(*s))
+               s++;
+
+       return s;
+}
+
+char *get_global_string_param(char *pathname, const char *key)
+{
+       FILE *f = NULL;
+       int len;
+       char *line, buffer[1024];
+       char *name = NULL;
+
+       if (!pathname) {
+               log_error("No pathname to load %s from", key);
+               return NULL;
+       }
+
+       len = strlen(key);
+       if ((f = fopen(pathname, "r"))) {
+               while ((line = fgets(buffer, sizeof (buffer), f))) {
+
+                       line = strstrip(line);
+
+                       if (strncmp(line, key, len) == 0) {
+                               char *end = line + len;
+
+                               /*
+                                * make sure there is something after the
+                                * key.
+                                */
+                               if (strlen(end))
+                                       name = strdup(line + len);
+                       }
+               }
+               fclose(f);
+               if (name)
+                       log_debug(5, "%s=%s", key, name);
+       } else
+               log_error("can't open %s configuration file %s", key, pathname);
+
+       return name;
+}
+
+/* TODO: move iscsid client helpers to file */
+static void iscsid_startup(void)
+{
+       char *startup_cmd;
+
+       startup_cmd = get_global_string_param(CONFIG_FILE, "iscsid.startup = ");
+       if (!startup_cmd) {
+               log_error("iscsid is not running. Could not start it up "
+                         "automatically using the startup command in "
+                         "/etc/iscsi/iscsid.start. Please check that the "
+                         "file exists or that your init scripts have "
+                         "started iscsid.");
+               return;
+       }
+
+       system(startup_cmd);
+}
+
 #define MAXSLEEP 128
 
-static mgmt_ipc_err_e iscsid_connect(int *fd)
+static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid)
 {
        int nsec;
        struct sockaddr_un addr;
@@ -146,8 +226,12 @@ static mgmt_ipc_err_e iscsid_connect(int *fd)
 
                /* If iscsid isn't there, there's no sense
                 * in retrying. */
-               if (errno == ECONNREFUSED)
-                       break;
+               if (errno == ECONNREFUSED) {
+                       if (start_iscsid && nsec == 1)
+                               iscsid_startup();
+                       else
+                               break;
+               }
 
                /*
                 * Delay before trying again
@@ -159,11 +243,11 @@ static mgmt_ipc_err_e iscsid_connect(int *fd)
        return MGMT_IPC_ERR_ISCSID_COMM_ERR;
 }
 
-mgmt_ipc_err_e iscsid_request(int *fd, iscsiadm_req_t *req)
+mgmt_ipc_err_e iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid)
 {
        int err;
 
-       err = iscsid_connect(fd);
+       err = iscsid_connect(fd, start_iscsid);
        if (err)
                return err;
 
@@ -193,12 +277,13 @@ mgmt_ipc_err_e iscsid_response(int fd, iscsiadm_cmd_e 
cmd, iscsiadm_rsp_t *rsp)
        return iscsi_err;
 }
 
-mgmt_ipc_err_e do_iscsid(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp)
+mgmt_ipc_err_e do_iscsid(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp,
+                        int start_iscsid)
 {
        int fd;
        mgmt_ipc_err_e err;
 
-       err = iscsid_request(&fd, req);
+       err = iscsid_request(&fd, req, start_iscsid);
        if (err)
                return err;
 
@@ -221,7 +306,7 @@ int iscsid_req_by_rec_async(iscsiadm_cmd_e cmd, node_rec_t 
*rec, int *fd)
        req.command = cmd;
        memcpy(&req.u.session.rec, rec, sizeof(node_rec_t));
 
-       return iscsid_request(fd, &req);
+       return iscsid_request(fd, &req, 1);
 }
 
 int iscsid_req_by_rec(iscsiadm_cmd_e cmd, node_rec_t *rec)
@@ -242,7 +327,7 @@ int iscsid_req_by_sid_async(iscsiadm_cmd_e cmd, int sid, 
int *fd)
        req.command = cmd;
        req.u.session.sid = sid;
 
-       return iscsid_request(fd, &req);
+       return iscsid_request(fd, &req, 1);
 }
 
 int iscsid_req_by_sid(iscsiadm_cmd_e cmd, int sid)
diff --git a/usr/util.h b/usr/util.h
index 6c4b5e3..c7c0000 100644
--- a/usr/util.h
+++ b/usr/util.h
@@ -13,9 +13,10 @@ extern int oom_adjust(void);
 extern void daemon_init(void);
 extern int increase_max_files(void);
 
-extern int do_iscsid(struct iscsiadm_req *req,  struct iscsiadm_rsp *rsp);
+extern int do_iscsid(struct iscsiadm_req *req,  struct iscsiadm_rsp *rsp,
+                    int iscsid_start);
 extern void iscsid_handle_error(int err);
-extern int iscsid_request(int *fd, struct iscsiadm_req *req);
+extern int iscsid_request(int *fd, struct iscsiadm_req *req, int iscsid_start);
 extern int iscsid_response(int fd, int cmd, struct iscsiadm_rsp *rsp);
 extern int iscsid_req_wait(int cmd, int fd);
 extern int iscsid_req_by_rec_async(int cmd, struct node_rec *rec, int *fd);
@@ -31,4 +32,7 @@ extern int __iscsi_match_session(struct node_rec *rec, char 
*targetname,
                                 char *address, int port,
                                 struct iface_rec *iface);
 
+extern char *strstrip(char *s);
+extern char *get_global_string_param(char *pathname, const char *key);
+
 #endif
-- 
1.5.6.6

Reply via email to