On 31.03., David Alten wrote:
> Hello,
>
> I???m having issues getting iscsid to work with my Synology NAS.
>
> The first issue was that the NAS was returning an error code. Turns out
> it didn???t like not?? missing the default SessionType=Normal.
>
> The second issue was that the login sequence never comleted. It seems we
> keep hardcoding MaxConnections and MaxRecvDataSegmentLength in
> connection.c:conn_gen_kvp() instead of negotiating to the lowest value.
> So I just bypassed that function entirely and hardcoded all the default
> settings in initiator.c.
>
> This makes the login step complete, but then nothing else happens after
> that. I would expect a new scsi device to be attached so I could use it.
>
> I did notice that MaxConnection shows as 0, but the NAS does show the
> connection as established.
>
> b1# iscsictl show?? ??
> Initiator: ISID base 80d3cf6f qalifier 6e7d
>
> Session 'disk2':
> ?? ?? SessionType: normal MaxConnections: 0
> ?? ?? TargetName: iqn.2000-01.com.synology:Target.02
> ?? ?? TargetAddr: 192.168.0.4:iscsi
> ?? ?? InitiatorName: iqn.1995-11.org.openbsd.iscsid:b1
> ?? ?? InitiatorAddr: 192.168.0.9
> command successful
>
> b1$ cat /etc/iscsi.conf?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 
> ?? ?? ?? ?? ?? ?? ??
> ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ????
> target disk2 {
> ?? ?? ?? ?? initiatoraddr 192.168.0.9
> ?? ?? ?? ?? targetaddr 192.168.0.4
> ?? ?? ?? ?? targetname "iqn.2000-01.com.synology:Target.02"
> }
> Any suggestions on where to go from here?
>
> Thanks,
>
> -David
>

Hi David,

I had the same problem some years ago when I tried to attach an iSCSI
LUN from my Synology to my APU box. I wrote the patch below which fixed
the problem for me. Maybe you can give it a try?

Cheers,
Bruno


Index: usr.sbin/iscsid/connection.c
===================================================================
RCS file: /cvs/src/usr.sbin/iscsid/connection.c,v
retrieving revision 1.21
diff -u -p -r1.21 connection.c
--- usr.sbin/iscsid/connection.c        5 Dec 2015 06:38:18 -0000       1.21
+++ usr.sbin/iscsid/connection.c        1 Apr 2021 05:18:29 -0000
@@ -316,44 +316,6 @@ log_debug("conn_parse_kvp: %s = %s", k->
 #undef SET_NUM
 #undef SET_BOOL

-int
-conn_gen_kvp(struct connection *c, struct kvp *kvp, size_t *nkvp)
-{
-       struct session *s = c->session;
-       size_t i = 0;
-
-       if (s->mine.MaxConnections != iscsi_sess_defaults.MaxConnections) {
-               if (kvp && i < *nkvp) {
-                       kvp[i].key = strdup("MaxConnections");
-                       if (kvp[i].key == NULL)
-                               return -1;
-                       if (asprintf(&kvp[i].value, "%hu",
-                           s->mine.MaxConnections) == -1) {
-                               kvp[i].value = NULL;
-                               return -1;
-                       }
-               }
-               i++;
-       }
-       if (c->mine.MaxRecvDataSegmentLength !=
-           iscsi_conn_defaults.MaxRecvDataSegmentLength) {
-               if (kvp && i < *nkvp) {
-                       kvp[i].key = strdup("MaxRecvDataSegmentLength");
-                       if (kvp[i].key == NULL)
-                               return -1;
-                       if (asprintf(&kvp[i].value, "%u",
-                           c->mine.MaxRecvDataSegmentLength) == -1) {
-                               kvp[i].value = NULL;
-                               return -1;
-                       }
-               }
-               i++;
-       }
-
-       *nkvp = i;
-       return 0;
-}
-
 void
 conn_pdu_write(struct connection *c, struct pdu *p)
 {
Index: usr.sbin/iscsid/initiator.c
===================================================================
RCS file: /cvs/src/usr.sbin/iscsid/initiator.c,v
retrieving revision 1.15
diff -u -p -r1.15 initiator.c
--- usr.sbin/iscsid/initiator.c 16 Jan 2015 15:57:06 -0000      1.15
+++ usr.sbin/iscsid/initiator.c 1 Apr 2021 05:18:29 -0000
@@ -250,39 +250,113 @@ initiator_nop_in_imm(struct connection *
        conn_task_issue(c, t);
 }

+#define WRITE_BOOL(k, v)       \
+do {                           \
+       if (v)                  \
+               k = "Yes";      \
+       else                    \
+               k = "No";       \
+} while (0)
+
+#define WRITE_NUM(k, v)                                \
+do {                                           \
+       if (asprintf(&k, "%hu", v) == -1)       \
+               errors++;                       \
+} while (0)
+
+#define WRITE_INT(k, v)                                \
+do {                                           \
+       if (asprintf(&k, "%u", v) == -1)        \
+               errors++;                       \
+} while (0)
+
+#define WRITE_DIGEST(k, v)     \
+do {                           \
+       if (v)                  \
+               k = "CRC32";    \
+       else                    \
+               k = "None";     \
+} while (0)                    \
+
 struct kvp *
 initiator_login_kvp(struct connection *c, u_int8_t stage)
 {
+       int errors = 0;
        struct kvp *kvp;
-       size_t nkvp;
+       struct session *s;

        switch (stage) {
        case ISCSI_LOGIN_STG_SECNEG:
-               if (!(kvp = calloc(4, sizeof(*kvp))))
+               if (!(kvp = calloc(5, sizeof(*kvp))))
                        return NULL;
                kvp[0].key = "AuthMethod";
                kvp[0].value = "None";
                kvp[1].key = "InitiatorName";
                kvp[1].value = c->session->config.InitiatorName;
+               kvp[2].key = "SessionType";

                if (c->session->config.SessionType == SESSION_TYPE_DISCOVERY) {
-                       kvp[2].key = "SessionType";
                        kvp[2].value = "Discovery";
                } else {
-                       kvp[2].key = "TargetName";
-                       kvp[2].value = c->session->config.TargetName;
+                       kvp[2].value = "Normal";
+                       kvp[3].key = "TargetName";
+                       kvp[3].value = c->session->config.TargetName;
                }
                break;
        case ISCSI_LOGIN_STG_OPNEG:
-               if (conn_gen_kvp(c, NULL, &nkvp) == -1)
-                       return NULL;
-               nkvp += 1; /* add slot for terminator */
-               if (!(kvp = calloc(nkvp, sizeof(*kvp))))
+               if (!(kvp = calloc(15, sizeof(*kvp))))
                        return NULL;
-               if (conn_gen_kvp(c, kvp, &nkvp) == -1) {
+
+               s = c->session;
+
+               kvp[0].key = "MaxConnections";
+               WRITE_NUM(kvp[0].value, s->mine.MaxConnections);
+
+               kvp[1].key = "InitialR2T";
+               WRITE_BOOL(kvp[1].value, s->mine.InitialR2T);
+
+               kvp[2].key = "ImmediateData";
+               WRITE_BOOL(kvp[2].value, s->mine.ImmediateData);
+
+               kvp[3].key = "MaxRecvDataSegmentLength";
+               WRITE_INT(kvp[3].value, c->mine.MaxRecvDataSegmentLength);
+
+               kvp[4].key = "MaxBurstLength";
+               WRITE_INT(kvp[4].value, s->mine.MaxBurstLength);
+
+               kvp[5].key = "FirstBurstLength";
+               WRITE_INT(kvp[5].value, s->mine.FirstBurstLength);
+
+               kvp[6].key = "HeaderDigest";
+               WRITE_DIGEST(kvp[6].value, s->config.HeaderDigest);
+
+               kvp[7].key = "DataDigest";
+               WRITE_DIGEST(kvp[7].value, s->config.DataDigest);
+
+               kvp[8].key = "MaxOutstandingR2T";
+               WRITE_NUM(kvp[8].value, s->mine.MaxOutstandingR2T);
+
+               kvp[9].key = "DataPDUInOrder";
+               WRITE_BOOL(kvp[9].value, s->mine.DataPDUInOrder);
+
+               kvp[10].key = "DataSequenceInOrder";
+               WRITE_BOOL(kvp[10].value, s->mine.DataSequenceInOrder);
+
+               kvp[11].key = "ErrorRecoveryLevel";
+               WRITE_INT(kvp[11].value, s->mine.ErrorRecoveryLevel);
+
+               kvp[12].key = "DefaultTime2Wait";
+               WRITE_NUM(kvp[12].value, s->mine.DefaultTime2Wait);
+
+               kvp[13].key = "DefaultTime2Retain";
+               WRITE_NUM(kvp[13].value, s->mine.DefaultTime2Retain);
+
+               if (errors) {
                        free(kvp);
+                       log_warnx("initiator_login_kvp: errors found");
                        return NULL;
                }
+
                break;
        default:
                log_warnx("initiator_login_kvp: exit stage left");
@@ -290,6 +364,11 @@ initiator_login_kvp(struct connection *c
        }
        return kvp;
 }
+
+#undef WRITE_DIGEST
+#undef WRITE_INT
+#undef WRITE_NUM
+#undef WRITE_BOOL

 struct pdu *
 initiator_login_build(struct connection *c, struct task_login *tl)

Reply via email to