diff -aurp open-iscsi-2.0-872-rc4-bnx2i/doc/iscsistart.8 open-iscsi-2.0-872-rc4-bnx2i.test/doc/iscsistart.8 --- open-iscsi-2.0-872-rc4-bnx2i/doc/iscsistart.8 2012-02-26 05:07:41.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.test/doc/iscsistart.8 2012-02-26 03:02:23.000000000 -0600 @@ -51,6 +51,10 @@ Bring up the network as specified by iBF .BI [-f|--fwparam_print] Print the iBFT or OF info to STDOUT .TP +.BI [-P|--param=]\fINAME=VALUE\fP +Set the parameter with the name NAME to VALUE. NAME is one of the settings +in the node record or iscsid.conf. Multiple params can be passed in. +.TP .BI [-h|--help] Display this help and exit .TP diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c open-iscsi-2.0-872-rc4-bnx2i.test/usr/idbm.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.c 2012-02-26 05:07:41.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.test/usr/idbm.c 2012-02-26 03:02:23.000000000 -0600 @@ -2298,6 +2298,38 @@ idbm_slp_defaults(struct iscsi_slp_confi sizeof(struct iscsi_slp_config)); } +int idbm_parse_param(char *param, struct node_rec *rec) +{ + char *name, *value; + recinfo_t *info; + int rc; + + name = param; + + value = strchr(param, '='); + if (!value) { + log_error("Invalid --param %s. Missing setting.\n", param); + return ISCSI_ERR_INVAL; + } + *value = '\0'; + value++; + + info = idbm_recinfo_alloc(MAX_KEYS); + if (!info) { + log_error("Could not allocate memory to setup params.\n"); + return ISCSI_ERR_NOMEM; + } + + idbm_recinfo_node(rec, info); + + rc = idbm_rec_update_param(info, name, value, 0); + if (rc) + log_error("Could not set %s to %s. Check that %s is a " + "valid parameter.\n", name, value, name); + free(info); + return rc; +} + int idbm_node_set_param(void *data, node_rec_t *rec) { struct db_set_param *param = data; diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h open-iscsi-2.0-872-rc4-bnx2i.test/usr/idbm.h --- open-iscsi-2.0-872-rc4-bnx2i/usr/idbm.h 2012-02-26 05:07:41.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.test/usr/idbm.h 2012-02-26 03:02:23.000000000 -0600 @@ -145,6 +145,7 @@ extern int idbm_discovery_read(discovery extern int idbm_rec_read(node_rec_t *out_rec, char *target_name, int tpgt, char *addr, int port, struct iface_rec *iface); +extern int idbm_parse_param(char *param, struct node_rec *rec); extern int idbm_node_set_param(void *data, node_rec_t *rec); extern int idbm_discovery_set_param(void *data, discovery_rec_t *rec); extern void idbm_node_setup_defaults(node_rec_t *rec); diff -aurp open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c open-iscsi-2.0-872-rc4-bnx2i.test/usr/iscsistart.c --- open-iscsi-2.0-872-rc4-bnx2i/usr/iscsistart.c 2012-02-26 05:07:41.000000000 -0600 +++ open-iscsi-2.0-872-rc4-bnx2i.test/usr/iscsistart.c 2012-02-26 05:07:28.000000000 -0600 @@ -56,6 +56,12 @@ struct iscsi_daemon_config *dconfig = &d static node_rec_t config_rec; static LIST_HEAD(targets); +static LIST_HEAD(user_params); + +struct user_param { + struct list_head list; + char *param_string; +}; static char program_name[] = "iscsistart"; @@ -76,6 +82,7 @@ static struct option const long_options[ {"fwparam_connect", no_argument, NULL, 'b'}, {"fwparam_network", no_argument, NULL, 'N'}, {"fwparam_print", no_argument, NULL, 'f'}, + {"param", required_argument, NULL, 'P'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0}, @@ -103,6 +110,7 @@ Open-iSCSI initiator.\n\ -b, --fwparam_connect create a session to the target using iBFT or OF\n\ -N, --fwparam_network bring up the network as specified by iBFT or OF\n\ -f, --fwparam_print print the iBFT or OF info to STDOUT \n\ + -P, --param=NAME=VALUE set parameter with the name NAME to VALUE\n\ -h, --help display this help and exit\n\ -v, --version display version and exit\n\ "); @@ -126,20 +134,69 @@ static int stop_event_loop(void) return rc; } +static int apply_params(struct node_rec *rec) +{ + struct user_param *param; + int rc; + + /* Must init this so we can check if user overrode them */ + rec->session.initial_login_retry_max = -1; + rec->conn[0].timeo.noop_out_interval = -1; + rec->conn[0].timeo.noop_out_timeout = -1; + + list_for_each_entry(param, &user_params, list) { + rc = idbm_parse_param(param->param_string, rec); + if (rc) + return rc; + } + + /* + * For root boot we could not change this in older versions so + * if user did not override then use the defaults. + * + * Increase to account for boot using static setup. + */ + if (rec->session.initial_login_retry_max == -1) + rec->session.initial_login_retry_max = 30; + /* we used to not be able to answer so turn off */ + if (rec->conn[0].timeo.noop_out_interval == -1) + rec->conn[0].timeo.noop_out_interval = 0; + if (rec->conn[0].timeo.noop_out_timeout == -1) + rec->conn[0].timeo.noop_out_timeout = 0; + + return 0; +} + +static int alloc_param(char *param_string) +{ + struct user_param *param; + + param = calloc(1, sizeof(*param)); + if (!param) { + printf("Could not allocate for param.\n"); + return ISCSI_ERR_NOMEM; + } + + INIT_LIST_HEAD(¶m->list); + param->param_string = strdup(param_string); + if (!param->param_string) { + printf("Could not allocate for param.\n"); + free(param); + return ISCSI_ERR_NOMEM; + } + list_add(¶m->list, &user_params); + return 0; +} static int login_session(struct node_rec *rec) { iscsiadm_req_t req; iscsiadm_rsp_t rsp; int rc, retries = 0; - /* - * For root boot we cannot change this so increase to account - * for boot using static setup. - */ - rec->session.initial_login_retry_max = 30; - /* we cannot answer so turn off */ - rec->conn[0].timeo.noop_out_interval = 0; - rec->conn[0].timeo.noop_out_timeout = 0; + + rc = apply_params(rec); + if (rc) + exit(rc); printf("%s: Logging into %s %s:%d,%d\n", program_name, rec->name, rec->conn[0].address, rec->conn[0].port, @@ -241,7 +298,7 @@ int main(int argc, char *argv[]) struct boot_context *context, boot_context; struct sigaction sa_old; struct sigaction sa_new; - int control_fd, mgmt_ipc_fd; + int control_fd, mgmt_ipc_fd, err; pid_t pid; idbm_node_setup_defaults(&config_rec); @@ -262,7 +319,7 @@ int main(int argc, char *argv[]) if (iscsi_sysfs_check_class_version()) exit(ISCSI_ERR_SYSFS_LOOKUP); - while ((ch = getopt_long(argc, argv, "i:t:g:a:p:d:u:w:U:W:bNfvh", + while ((ch = getopt_long(argc, argv, "P:i:t:g:a:p:d:u:w:U:W:bNfvh", long_options, &longindex)) >= 0) { switch (ch) { case 'i': @@ -341,6 +398,11 @@ int main(int argc, char *argv[]) fw_free_targets(&targets); exit(0); + case 'P': + err = alloc_param(optarg); + if (err) + exit(err); + break; case 'v': printf("%s version %s\n", program_name, ISCSI_VERSION_STR);