diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-01-29 18:31:22 -0600 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2008-02-20 12:53:55 -0600 |
commit | 59f5ecab1b88753bc13d9f5f21af954b73ea646d (patch) | |
tree | 12e68b7b81d2b4ce9673a66f4adb91d35fa3930c /usr | |
parent | e908475ceae3847ac30fddb6f054a841853445dd (diff) | |
download | open-iscsi-59f5ecab1b88753bc13d9f5f21af954b73ea646d.tar.gz |
Add options to modify the db manipulation behavior during discovery
Instead of overwriting existing node records, you can modify the
behavior by passing in different ops.
Pass -o new to add new nodes.
Pass -o delete to delete stale ones.
Pass -o update to update the records of existing nodes.
And pass combos of different ops for different behavior.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Diffstat (limited to 'usr')
-rw-r--r-- | usr/discovery.c | 56 | ||||
-rw-r--r-- | usr/idbm.c | 114 | ||||
-rw-r--r-- | usr/idbm.h | 15 | ||||
-rw-r--r-- | usr/iscsiadm.c | 259 | ||||
-rw-r--r-- | usr/iscsiadm.h | 2 | ||||
-rw-r--r-- | usr/isns.c | 2 | ||||
-rw-r--r-- | usr/mgmt_ipc.c | 4 | ||||
-rw-r--r-- | usr/util.c | 2 |
8 files changed, 342 insertions, 112 deletions
diff --git a/usr/discovery.c b/usr/discovery.c index 80fc866..c5b6ac0 100644 --- a/usr/discovery.c +++ b/usr/discovery.c @@ -183,12 +183,13 @@ iterate_targets(iscsi_session_t *session, uint32_t ttt) return 1; } -static int add_portal(idbm_t *db, discovery_rec_t *drec, - struct list_head *ifaces, node_rec_t *rec, - char *address, char *port, char *tag) +static int add_portal(idbm_t *db, struct list_head *rec_list, + discovery_rec_t *drec, char *targetname, char *address, + char *port, char *tag) { struct sockaddr_storage ss; char host[NI_MAXHOST]; + struct node_rec *rec; /* resolve the address, in case it was a DNS name */ if (resolve_address(address, port, &ss)) { @@ -200,6 +201,16 @@ static int add_portal(idbm_t *db, discovery_rec_t *drec, getnameinfo((struct sockaddr *) &ss, sizeof(ss), host, sizeof(host), NULL, 0, NI_NUMERICHOST); + rec = calloc(1, sizeof(*rec)); + if (!rec) + return 0; + + idbm_node_setup_from_conf(db, rec); + rec->disc_type = drec->type; + rec->disc_port = drec->port; + strcpy(rec->disc_address, drec->address); + + strncpy(rec->name, targetname, TARGET_NAME_MAXLEN); if (tag && *tag) rec->tpgt = atoi(tag); else @@ -210,21 +221,18 @@ static int add_portal(idbm_t *db, discovery_rec_t *drec, rec->conn[0].port = ISCSI_LISTEN_PORT; strncpy(rec->conn[0].address, address, NI_MAXHOST); - if (idbm_add_nodes(db, rec, drec, ifaces)) - log_error("Could not add record for %s %s,%d,%d\n", - rec->name, address, rec->conn[0].port, rec->tpgt); + list_add_tail(&rec->list, rec_list); return 1; } static int add_target_record(idbm_t *db, char *name, char *end, - discovery_rec_t *drec, struct list_head *ifaces, + discovery_rec_t *drec, struct list_head *rec_list, char *default_port) { char *text = NULL; char *nul = name; size_t length; - node_rec_t rec; /* address = IPv4 * address = [IPv6] @@ -251,10 +259,6 @@ add_target_record(idbm_t *db, char *name, char *end, log_error("TargetName %s too long, ignoring", name); return 0; } - - idbm_node_setup_from_conf(db, &rec); - strncpy(rec.name, name, TARGET_NAME_MAXLEN); - text = name + length; /* skip NULs after the name */ @@ -267,7 +271,7 @@ add_target_record(idbm_t *db, char *name, char *end, log_error("no default address known for target %s", name); return 0; - } else if (!add_portal(db, drec, ifaces, &rec, drec->address, + } else if (!add_portal(db, rec_list, drec, name, drec->address, default_port, NULL)) { log_error("failed to add default portal, ignoring " "target %s", name); @@ -305,7 +309,7 @@ add_target_record(idbm_t *db, char *name, char *end, *temp = '\0'; } - if (!add_portal(db, drec, ifaces, &rec, address, port, + if (!add_portal(db, rec_list, drec, name, address, port, tag)) { log_error("failed to add default portal, " "ignoring target %s", name); @@ -323,7 +327,7 @@ add_target_record(idbm_t *db, char *name, char *end, static int process_sendtargets_response(idbm_t *db, struct string_buffer *sendtargets, int final, discovery_rec_t *drec, - struct list_head *ifaces, + struct list_head *rec_list, char *default_port) { char *start = buffer_data(sendtargets); @@ -375,7 +379,7 @@ process_sendtargets_response(idbm_t *db, struct string_buffer *sendtargets, * "TargetName=" prefix. */ if (!add_target_record(db, record + 11, text, - drec, ifaces, + drec, rec_list, default_port)) { log_error( "failed to add target record"); @@ -404,7 +408,7 @@ process_sendtargets_response(idbm_t *db, struct string_buffer *sendtargets, "line %s", record, record); if (add_target_record (db, record + 11, text, - drec, ifaces, default_port)) { + drec, rec_list, default_port)) { num_targets++; record = NULL; truncate_buffer(sendtargets, 0); @@ -684,7 +688,7 @@ setup_authentication(iscsi_session_t *session, static int process_recvd_pdu(idbm_t *db, struct iscsi_hdr *pdu, discovery_rec_t *drec, - struct list_head *ifaces, + struct list_head *rec_list, iscsi_session_t *session, struct string_buffer *sendtargets, char *default_port, @@ -721,22 +725,12 @@ process_recvd_pdu(idbm_t *db, struct iscsi_hdr *pdu, memcpy(buffer_data(sendtargets) + curr_data_length, data, dlength); - /* - * we got a response so clear out the current - * db values - * - * TODO: should we make whether rm the current - * values configurable (maybe a --clear option) - */ - if (!*valid_text) - idbm_new_discovery(db, drec); *valid_text = 1; - /* process as much as we can right now */ process_sendtargets_response(db, sendtargets, final, drec, - ifaces, + rec_list, default_port); if (final) { @@ -828,7 +822,7 @@ done: } int discovery_sendtargets(idbm_t *db, discovery_rec_t *drec, - struct list_head *ifaces) + struct list_head *rec_list) { iscsi_session_t *session; struct pollfd pfd; @@ -1125,7 +1119,7 @@ repoll: /* * process iSCSI PDU received */ - rc = process_recvd_pdu(db, pdu, drec, ifaces, + rc = process_recvd_pdu(db, pdu, drec, rec_list, session, &sendtargets, default_port, &active, &valid_text, data); @@ -2094,14 +2094,16 @@ free_portal: return rc; } -static int -idbm_add_discovery(idbm_t *db, discovery_rec_t *newrec) +int +idbm_add_discovery(idbm_t *db, discovery_rec_t *newrec, int overwrite) { discovery_rec_t rec; int rc; if (!idbm_discovery_read(db, &rec, newrec->address, newrec->port)) { + if (!overwrite) + return 0; log_debug(7, "overwriting existing record"); } else log_debug(7, "adding new DB record"); @@ -2159,7 +2161,8 @@ static int setup_disc_to_node_link(char *disc_portal, node_rec_t *rec) return rc; } -int idbm_add_node(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec) +int idbm_add_node(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, + int overwrite) { node_rec_t rec; char *node_portal, *disc_portal; @@ -2168,7 +2171,10 @@ int idbm_add_node(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec) if (!idbm_rec_read(db, &rec, newrec->name, newrec->tpgt, newrec->conn[0].address, newrec->conn[0].port, &newrec->iface)) { - rc = idbm_delete_node(db, NULL, &rec); + if (!overwrite) + return 0; + + rc = idbm_delete_node(db, &rec); if (rc) return rc; log_debug(7, "overwriting existing record"); @@ -2221,8 +2227,26 @@ free_portal: return rc; } -int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, - struct list_head *ifaces) +static int idbm_bind_iface_to_node(struct node_rec *new_rec, + struct iface_rec *iface, + struct list_head *bound_recs) +{ + struct node_rec *clone_rec; + + clone_rec = calloc(1, sizeof(*clone_rec)); + if (!clone_rec) + return ENOMEM; + + memcpy(clone_rec, new_rec, sizeof(*clone_rec)); + INIT_LIST_HEAD(&clone_rec->list); + iface_copy(&clone_rec->iface, iface); + list_add_tail(&clone_rec->list, bound_recs); + return 0; +} + +int idbm_bind_ifaces_to_node(idbm_t *db, struct node_rec *new_rec, + struct list_head *ifaces, + struct list_head *bound_recs) { struct iface_rec *iface, *tmp; struct iscsi_transport *t; @@ -2239,18 +2263,75 @@ int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, list_for_each_entry_safe(iface, tmp, &def_ifaces, list) { list_del(&iface->list); t = get_transport_by_name(iface->transport_name); - if (!t) { + if (!t || t->caps & CAP_FW_DB) { free(iface); continue; } - if (t->caps & CAP_FW_DB) { + rc = idbm_bind_iface_to_node(new_rec, iface, + bound_recs); + free(iface); + if (rc) + return rc; + found = 1; + } + + /* create default iface with old/default behavior */ + if (!found) { + struct iface_rec def_iface; + + iface_init(&def_iface); + return idbm_bind_iface_to_node(new_rec, &def_iface, + bound_recs); + } + } else { + list_for_each_entry(iface, ifaces, list) { + if (strcmp(iface->name, DEFAULT_IFACENAME) && + !iface_is_bound(iface)) { + log_error("iface %s is not bound. Will not " + "bind node to it. Iface settings " + iface_fmt, iface->name, + iface_str(iface)); + continue; + } + + rc = idbm_bind_iface_to_node(new_rec, iface, + bound_recs); + if (rc) + return rc; + } + } + return 0; +} + +/* + * remove this when isns is converted + */ +int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, + struct list_head *ifaces, int update) +{ + struct iface_rec *iface, *tmp; + struct iscsi_transport *t; + int rc = 0, found = 0; + + if (!ifaces || list_empty(ifaces)) { + struct list_head def_ifaces; + + INIT_LIST_HEAD(&def_ifaces); + idbm_lock(db); + idbm_read_def_ifaces(&def_ifaces); + idbm_unlock(db); + + list_for_each_entry_safe(iface, tmp, &def_ifaces, list) { + list_del(&iface->list); + t = get_transport_by_name(iface->transport_name); + if (!t || t->caps & CAP_FW_DB) { free(iface); continue; } iface_copy(&newrec->iface, iface); - rc = idbm_add_node(db, newrec, drec); + rc = idbm_add_node(db, newrec, drec, update); free(iface); if (rc) return rc; @@ -2260,7 +2341,7 @@ int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, /* create default iface with old/default behavior */ if (!found) { iface_init(&newrec->iface); - return idbm_add_node(db, newrec, drec); + return idbm_add_node(db, newrec, drec, update); } } else { list_for_each_entry(iface, ifaces, list) { @@ -2274,7 +2355,7 @@ int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, } iface_copy(&newrec->iface, iface); - rc = idbm_add_node(db, newrec, drec); + rc = idbm_add_node(db, newrec, drec, update); if (rc) return rc; } @@ -2282,13 +2363,6 @@ int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, return 0; } -void idbm_new_discovery(idbm_t *db, discovery_rec_t *drec) -{ - idbm_delete_discovery(db, drec); - if (idbm_add_discovery(db, drec)) - log_error("can not update discovery record."); -} - static void idbm_rm_disc_node_links(idbm_t *db, char *disc_dir) { char *target = NULL, *tpgt = NULL, *port = NULL; @@ -2328,7 +2402,7 @@ static void idbm_rm_disc_node_links(idbm_t *db, char *disc_dir) strncpy(rec->conn[0].address, address, NI_MAXHOST); strncpy(rec->iface.name, iface_id, ISCSI_MAX_IFACE_LEN); - if (idbm_delete_node(db, NULL, rec)) + if (idbm_delete_node(db, rec)) log_error("Could not delete node %s/%s/%s,%s/%s", NODE_CONFIG_DIR, target, address, port, iface_id); @@ -2438,7 +2512,7 @@ done: return rc; } -int idbm_delete_node(idbm_t *db, void *data, node_rec_t *rec) +int idbm_delete_node(idbm_t *db, node_rec_t *rec) { struct stat statb; char *portal; @@ -110,13 +110,18 @@ extern int idbm_print_discovered(idbm_t *db, discovery_rec_t *drec, int info_level); extern int idbm_delete_discovery(idbm_t *db, discovery_rec_t *rec); extern void idbm_node_setup_defaults(node_rec_t *rec); -extern int idbm_delete_node(idbm_t *db, void *data, node_rec_t *rec); -extern int idbm_add_node(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec); - +extern int idbm_delete_node(idbm_t *db, node_rec_t *rec); +extern int idbm_add_node(idbm_t *db, node_rec_t *newrec, discovery_rec_t *drec, + int overwrite); struct list_head; +extern int idbm_bind_ifaces_to_node(idbm_t *db, struct node_rec *new_rec, + struct list_head *ifaces, + struct list_head *bound_recs); extern int idbm_add_nodes(idbm_t *db, node_rec_t *newrec, - discovery_rec_t *drec, struct list_head *ifaces); -extern void idbm_new_discovery(idbm_t *db, discovery_rec_t *drec); + discovery_rec_t *drec, struct list_head *ifaces, + int overwrite); +extern int idbm_add_discovery(idbm_t *db, discovery_rec_t *newrec, + int overwrite); extern void idbm_sendtargets_defaults(idbm_t *db, struct iscsi_sendtargets_config *cfg); extern void idbm_slp_defaults(idbm_t *db, struct iscsi_slp_config *cfg); diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index e86f00d..ad074b8 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -55,10 +55,11 @@ enum iscsiadm_mode { }; enum iscsiadm_op { - OP_NEW, - OP_DELETE, - OP_UPDATE, - OP_SHOW, + OP_NOOP = 0x0, + OP_NEW = 0x1, + OP_DELETE = 0x2, + OP_UPDATE = 0x4, + OP_SHOW = 0x8, }; static struct option const long_options[] = @@ -121,7 +122,7 @@ str_to_op(char *str) else if (!strcmp("show", str)) op = OP_SHOW; else - op = -1; + op = OP_NOOP; return op; } @@ -1321,7 +1322,7 @@ static int add_static_rec(idbm_t *db, int *found, char *targetname, int tpgt, iface_copy(&rec->iface, iface); } - rc = idbm_add_node(db, rec, drec); + rc = idbm_add_node(db, rec, drec, 1); if (!rc) { (*found)++; printf("New iSCSI node [%s:" iface_fmt " %s,%d,%d %s] added\n", @@ -1431,35 +1432,196 @@ static int login_discovered_portal(void *data, struct list_head *list, return 0; } +/* TODO merge with initiator.c implementation */ +/* And add locking */ +static int check_for_session_through_iface(struct node_rec *rec) +{ + int nr_found = 0; + if (sysfs_for_each_session(rec, &nr_found, iscsi_match_session)) + return 1; + return 0; +} + +static int delete_node(struct idbm *db, void *data, struct node_rec *rec) +{ + if (check_for_session_through_iface(rec)) { + /* + * perf is not important in this path, so do not worry + * about doing a async logout + */ + switch (iscsid_req(MGMT_IPC_SESSION_LOGOUT, rec)) { + case MGMT_IPC_ERR_NOT_FOUND: + case MGMT_IPC_OK: + break; + default: + log_error("Could not remove record, because there " + "is a session to the portal that cannot " + "stopped. Please log out session: " + "[iface: %s, target: %s, portal: %s,%d]" + "and then remove record.", + rec->iface.name, rec->name, + rec->conn[0].address, rec->conn[0].port); + return EINVAL; + } + } + return idbm_delete_node(db, rec); +} + +static int delete_stale_recs(struct idbm *db, void *data, struct node_rec *rec) +{ + struct list_head *new_rec_list = data; + struct node_rec *new_rec; + + list_for_each_entry(new_rec, new_rec_list, list) { + /* + * We could also move this to idbm.c and instead of looping + * over every node just loop over disc to node links. + */ + if (rec->disc_type != new_rec->disc_type || + rec->disc_port != new_rec->disc_port || + strcmp(rec->disc_address, new_rec->disc_address)) + /* + * if we are not from the same discovery source + * ignore it + */ + return 0; + + /* + * we only care if the target endpoint matches, because + * it is gone and we want to logout all sessions with + * that endpoint, so we pass in null for the iface. + */ + if (__iscsi_match_session(rec, + new_rec->name, + new_rec->conn[0].address, + new_rec->conn[0].port, + &new_rec->iface)) + return 0; + } + /* if there is a error we can continue on */ + delete_node(db, NULL, rec); + return 0; +} + static int -do_sofware_sendtargets(idbm_t *db, discovery_rec_t *drec, - struct list_head *ifaces, int info_level, int do_login) +update_discovery_recs(idbm_t *db, discovery_rec_t *drec, + struct list_head *new_rec_list, struct list_head *ifaces, + int info_level, int do_login, int op) { - int rc, err, nr_found = 0; - struct list_head rec_list; + int rc, err, found = 0; + struct list_head bound_rec_list; + struct node_rec *new_rec, *tmp; + + INIT_LIST_HEAD(&bound_rec_list); + + /* bind ifaces to node recs so we know what we have */ + list_for_each_entry(new_rec, new_rec_list, list) { + rc = idbm_bind_ifaces_to_node(db, new_rec, ifaces, + &bound_rec_list); + if (rc) + goto free_bound_recs; + } + + + /* clean up node db */ + if (op & OP_DELETE) + idbm_for_each_rec(db, &found, &bound_rec_list, + delete_stale_recs); + + if (op & OP_NEW || op & OP_UPDATE) { + /* now add/update records */ + list_for_each_entry(new_rec, &bound_rec_list, list) { + int update = op & OP_UPDATE; + + if (update && + check_for_session_through_iface(new_rec)) { + log_warning("Could not update record for " + "[iface: %s, target: %s, portal: " + "%s,%d], because session is " + "logged in. Log out session " + "then retry operation, or run " + "discovery without the 'update' " + "option.", + new_rec->iface.name, new_rec->name, + new_rec->conn[0].address, + new_rec->conn[0].port); + continue; + } - drec->type = DISCOVERY_TYPE_SENDTARGETS; - rc = discovery_sendtargets(db, drec, ifaces); - if (rc) - return rc; + rc = idbm_add_node(db, new_rec, drec, update); + if (rc) + log_error("Could not add/update " + "[%s:" iface_fmt " %s,%d,%d %s]", + new_rec->iface.transport_name, + iface_str(&new_rec->iface), + new_rec->conn[0].address, + new_rec->conn[0].port, + new_rec->tpgt, new_rec->name); + } + } idbm_print_discovered(db, drec, info_level); - if (!do_login) - return 0; + if (!do_login) { + rc = 0; + goto free_bound_recs; + } - INIT_LIST_HEAD(&rec_list); - rc = idbm_for_each_rec(db, &nr_found, &rec_list, link_recs); - err = __login_portals(drec, &nr_found, &rec_list, + err = __login_portals(drec, &found, &bound_rec_list, login_discovered_portal); if (err && !rc) rc = err; + +free_bound_recs: + list_for_each_entry_safe(new_rec, tmp, &bound_rec_list, list) { + list_del(&new_rec->list); + free(new_rec); + } + return rc; +} + +static int +do_sofware_sendtargets(idbm_t *db, discovery_rec_t *drec, + struct list_head *ifaces, int info_level, int do_login, + int op) +{ + struct list_head new_rec_list; + struct node_rec *new_rec, *tmp; + int rc; + + INIT_LIST_HEAD(&new_rec_list); + /* + * compat: if the user did not pass any op then we do all + * ops for them + */ + if (!op) + op = OP_NEW | OP_DELETE | OP_UPDATE; + + drec->type = DISCOVERY_TYPE_SENDTARGETS; + rc = discovery_sendtargets(db, drec, &new_rec_list); + if (rc) + return rc; + + rc = idbm_add_discovery(db, drec, op & OP_UPDATE); + if (rc) { + log_error("Could not add new discovery record."); + goto free_new_recs; + } + + rc = update_discovery_recs(db, drec, &new_rec_list, ifaces, + info_level, do_login, op); + +free_new_recs: + list_for_each_entry_safe(new_rec, tmp, &new_rec_list, list) { + list_del(&new_rec->list); + free(new_rec); + } return rc; } static int do_sendtargets(idbm_t *db, discovery_rec_t *drec, struct list_head *ifaces, - int info_level, int do_login) + int info_level, int do_login, int op) { struct iface_rec *tmp, *iface; int rc, host_no; @@ -1519,7 +1681,8 @@ do_sendtargets(idbm_t *db, discovery_rec_t *drec, struct list_head *ifaces, return ENODEV; sw_st: - return do_sofware_sendtargets(db, drec, ifaces, info_level, do_login); + return do_sofware_sendtargets(db, drec, ifaces, info_level, do_login, + op); } /* TODO: merge this with the idbm code */ @@ -1584,16 +1747,6 @@ static void catch_sigint( int signo ) { exit(1); } -/* TODO merge with initiator.c implementation */ -/* And add locking */ -static int check_for_session_through_iface(struct node_rec *rec) -{ - int nr_found = 0; - if (sysfs_for_each_session(rec, &nr_found, iscsi_match_session)) - return 1; - return 0; -} - static int exec_iface_op(idbm_t *db, int op, int do_show, int info_level, struct iface_rec *iface, char *name, char *value) { @@ -1641,13 +1794,8 @@ new_fail: } if (iface_is_bound(&rec->iface)) { - if (check_for_session_through_iface(rec)) { - rc = EBUSY; - goto delete_fail; - } - - /* delete node records using it first */ - rc = __for_each_rec(db, 0, rec, NULL, idbm_delete_node); + /* logout and delete records using it first */ + rc = __for_each_rec(db, 0, rec, NULL, delete_node); if (rc && rc != ENODEV) goto delete_fail; } @@ -1732,7 +1880,7 @@ update_fail: iface->name); break; default: - if (op < 0 || op == OP_SHOW) + if (op == OP_NOOP || op == OP_SHOW) rc = print_ifaces(db, info_level); else rc = EINVAL; @@ -1781,14 +1929,14 @@ static int exec_node_op(idbm_t *db, int op, int do_login, int do_logout, goto out; } - if ((do_login || do_logout) && op >= 0) { + if ((do_login || do_logout) && op > OP_NOOP) { log_error("either operation or login/logout " "at the time allowed!"); rc = -1; goto out; } - if ((!do_login && !do_logout && op < 0) && + if ((!do_login && !do_logout && op == OP_NOOP) && (!strlen(rec->name) && !strlen(rec->conn[0].address) && !strlen(rec->iface.name))) { rc = print_nodes(db, info_level, rec); @@ -1807,7 +1955,7 @@ static int exec_node_op(idbm_t *db, int op, int do_login, int do_logout, goto out; } - if (op < 0 || (!do_login && !do_logout && op == OP_SHOW)) { + if (op == OP_NOOP || (!do_login && !do_logout && op == OP_SHOW)) { if (for_each_rec(db, rec, &do_show, idbm_print_node_info)) rc = -1; goto out; @@ -1824,11 +1972,19 @@ static int exec_node_op(idbm_t *db, int op, int do_login, int do_logout, set_param.name = name; set_param.value = value; + if (check_for_session_through_iface(rec)) { + log_error("Could not update record, because a " + "session is accessing it. Please log " + "out session, then retry operation."); + rc = -1; + goto out; + } + if (for_each_rec(db, rec, &set_param, idbm_node_set_param)) rc = -1; goto out; } else if (op == OP_DELETE) { - if (for_each_rec(db, rec, NULL, idbm_delete_node)) + if (for_each_rec(db, rec, NULL, delete_node)) rc = -1; goto out; } else { @@ -1962,9 +2118,9 @@ main(int argc, char **argv) char *ip = NULL, *name = NULL, *value = NULL; char *targetname = NULL, *group_session_mgmt_mode = NULL; int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0; - int rc=0, sid=-1, op=-1, type=-1, do_logout=0, do_stats=0, do_show=0; + int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0; int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0; - int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1; + int tpgt = PORTAL_GROUP_TAG_UNKNOWN, killiscsid=-1, do_show=0; idbm_t *db = NULL; struct sigaction sa_old; struct sigaction sa_new; @@ -2006,8 +2162,8 @@ main(int argc, char **argv) type = str_to_type(optarg); break; case 'o': - op = str_to_op(optarg); - if (op < 0) { + op |= str_to_op(optarg); + if (op == OP_NOOP) { log_error("can not recognize operation: '%s'", optarg); return -1; @@ -2167,7 +2323,7 @@ main(int argc, char **argv) drec.port = port; if (do_sendtargets(db, &drec, &ifaces, info_level, - do_login)) { + do_login, op)) { rc = -1; goto out; } @@ -2199,7 +2355,8 @@ main(int argc, char **argv) if (do_login && drec.type == DISCOVERY_TYPE_SENDTARGETS) { do_sendtargets(db, &drec, &ifaces, - info_level, do_login); + info_level, do_login, + op); } else if (do_login && drec.type == DISCOVERY_TYPE_SLP) { log_error("SLP discovery is not fully " @@ -2212,7 +2369,7 @@ main(int argc, char **argv) "implemented yet."); rc = -1; goto out; - } else if (op < 0 || op == OP_SHOW) { + } else if (op == OP_NOOP || op == OP_SHOW) { if (!idbm_print_discovery_info(db, &drec, do_show)) { log_error("no records found!"); @@ -2230,7 +2387,7 @@ main(int argc, char **argv) goto out; } - } else if (op < 0 || op == OP_SHOW) { + } else if (op == OP_NOOP || op == OP_SHOW) { if (!idbm_print_all_discovery(db, info_level)) rc = -1; goto out; diff --git a/usr/iscsiadm.h b/usr/iscsiadm.h index f707984..76ac2ec 100644 --- a/usr/iscsiadm.h +++ b/usr/iscsiadm.h @@ -29,7 +29,7 @@ struct discovery_rec; struct list_head; extern int discovery_sendtargets(struct idbm *db, struct discovery_rec *drec, - struct list_head *ifaces); + struct list_head *rec_list); extern int discovery_offload_sendtargets(struct idbm *db, int host_no, int do_login, discovery_rec_t *drec); #endif /* ISCSIADM_H */ @@ -309,7 +309,7 @@ static void add_new_target_node(char *targetname, uint8_t *ip, int port, /* TODO?: shoudl we set the address and port of the server ? */ memset(&drec, 0, sizeof(discovery_rec_t)); drec.type = DISCOVERY_TYPE_ISNS; - err = idbm_add_nodes(db, &rec, &drec, NULL); + err = idbm_add_nodes(db, &rec, &drec, NULL, 0); if (err) log_error("Could not add new target node:%s %s,%d", targetname, dst, port); diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c index cb6daa1..3567ac0 100644 --- a/usr/mgmt_ipc.c +++ b/usr/mgmt_ipc.c @@ -139,7 +139,7 @@ mgmt_ipc_session_logout(queue_task_t *qtask) iscsi_session_t *session; if (!(session = session_find_by_rec(rec))) { - log_error("session [%s,%s,%d] not found!", rec->name, + log_debug(1, "session [%s,%s,%d] not found!", rec->name, rec->conn[0].address, rec->conn[0].port); return MGMT_IPC_ERR_NOT_FOUND; } @@ -172,7 +172,7 @@ mgmt_ipc_session_info(queue_task_t *qtask) struct ipc_msg_session_state *info; if (!(session = session_find_by_sid(sid))) { - log_error("session with sid %d not found!", sid); + log_debug(1, "session with sid %d not found!", sid); return MGMT_IPC_ERR_NOT_FOUND; } @@ -313,7 +313,7 @@ int __iscsi_match_session(node_rec_t *rec, char *targetname, if (rec->conn[0].port != -1 && port != rec->conn[0].port) return 0; - if (strlen(rec->iface.transport_name) && + if (iface && strlen(rec->iface.transport_name) && strcmp(rec->iface.transport_name, iface->transport_name)) return 0; |