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