summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-01-29 18:31:22 -0600
committerMike Christie <michaelc@cs.wisc.edu>2008-02-20 12:53:55 -0600
commit59f5ecab1b88753bc13d9f5f21af954b73ea646d (patch)
tree12e68b7b81d2b4ce9673a66f4adb91d35fa3930c /usr
parente908475ceae3847ac30fddb6f054a841853445dd (diff)
downloadopen-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.c56
-rw-r--r--usr/idbm.c114
-rw-r--r--usr/idbm.h15
-rw-r--r--usr/iscsiadm.c259
-rw-r--r--usr/iscsiadm.h2
-rw-r--r--usr/isns.c2
-rw-r--r--usr/mgmt_ipc.c4
-rw-r--r--usr/util.c2
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);
diff --git a/usr/idbm.c b/usr/idbm.c
index bd46824..240c134 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -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;
diff --git a/usr/idbm.h b/usr/idbm.h
index 9664031..676e8b3 100644
--- a/usr/idbm.h
+++ b/usr/idbm.h
@@ -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 */
diff --git a/usr/isns.c b/usr/isns.c
index 191b58b..69a9c83 100644
--- a/usr/isns.c
+++ b/usr/isns.c
@@ -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;
}
diff --git a/usr/util.c b/usr/util.c
index 59bcf57..90008f3 100644
--- a/usr/util.c
+++ b/usr/util.c
@@ -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;