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)