Hi leeman
I think it is because iscsi_login_portal() has no protection to avoid parallel searching the sysfs for the same session.
Can we use something like sem to serialize the searching from different processes ?
Since I don’t see any communication with iscsid in this login operation, I’m not sure if it is a good idea to do the synchronization in iscsid.
Thanks.
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
open-iscsi+...@googlegroups.com.
To post to this group, send email to
open-...@googlegroups.com.
Visit this group at https://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.
Hi leeman
I think I have found the problem.
On the client side, iscsiadm checks if an session exists in sysfs and if session_count >= rec->session.nr_sessions.
But without any lock protection.
So when multiple commands run in parallel, multiple same sessions could be created because we set rec->session.multiple = 1.
iscsi_login_portal()
|--> rec->session.multiple = 1
On the server side, iscsid runs __session_login_task() serially. And we checks if a same session exists in session_is_running().
__session_login_task()
|--> session_is_running()
|--> iscsi_sysfs_for_each_session()
|--> if (rec->session.multiple)
log_debug(2, "Adding a copy of an existing session"); // But we didn’t check if session_count >= rec->session.nr_sessions here.
I think we should also check if session_count >= rec->session.nr_sessions on server side.
Here is a simple patch. If you think it is OK, I’ll send a new one.
Thanks.
diff --git a/usr/initiator.c b/usr/initiator.c
index 9d02f47..d1ceea3 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -1870,14 +1870,12 @@ static iscsi_session_t* session_find_by_rec(node_rec_t *rec)
* a session could be running in the kernel but not in iscsid
* due to a resync or becuase some other app started the session
*/
-static int session_is_running(node_rec_t *rec)
+static int session_is_running(node_rec_t *rec, int *nr_found)
{
- int nr_found = 0;
-
if (session_find_by_rec(rec))
return 1;
- if (iscsi_sysfs_for_each_session(rec, &nr_found, iscsi_match_session,
+ if (iscsi_sysfs_for_each_session(rec, nr_found, iscsi_match_session,
0))
return 1;
@@ -1889,12 +1887,17 @@ static int __session_login_task(node_rec_t *rec, queue_task_t *qtask)
iscsi_session_t *session;
iscsi_conn_t *conn;
struct iscsi_transport *t;
- int rc;
-
- if (session_is_running(rec)) {
- if (rec->session.multiple)
+ int rc, nr_found;
+
+ if (session_is_running(rec, &nr_found)) {
+ if (rec->session.multiple) {
+ if (nr_found >= rec->session.nr_sessions) {
+ log_debug(2, "Cannot add more copy of session,"
+ " %d found.\n", nr_found);
+ return ISCSI_ERR_SESS_EXISTS;
+ }
log_debug(2, "Adding a copy of an existing session");
- else
+ } else
return ISCSI_ERR_SESS_EXISTS;
}
--
1.8.3.1
To unsubscribe from this group and stop receiving emails from it, send an email to open-iscsi+unsubscribe@googlegroups.com.
To post to this group, send email to open-...@googlegroups.com.
Visit this group at https://groups.google.com/group/open-iscsi.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-iscsi+unsubscribe@googlegroups.com.