From 94418431ce64f2b1c56981e013d227b620dd38a7 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Sun, 18 Sep 2011 00:58:15 +0000 Subject: [PATCH] Patch from Abhilash Sankar with some fixes Issue: ------------ The DevRegAttribute is sending a different Source Attribute (ISCSI name) which represents the Storage Node for each target. So Microsoft isns server considers the last request as the storage node and doesn't discover the previous targets. Root Cause ---------------- Function ISNS_FUNC_DEV_ATTR_REG Target A Source attribute ISCSI-Name = Operating Attribute ISCSI-Name = Flags Replace Access = 1 Target B Source attribute ISCSI-Name = Operating Attribute ISCSI-Name = Replace Access = 1 So as per the request format Microsoft isns Server always takes the last target as the source node. and register the same. Hence it doesn't discover the targets other than last one. The Source Attribute has to be fixed for all targets. It would be better if we use the first target iscsi name (rather than the last target iscsi name) as source attribute iscsi name to represent the storage node. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3863 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/usr/event.c | 15 +++++++++++++-- iscsi-scst/usr/iscsi_scstd.c | 4 ++++ iscsi-scst/usr/iscsid.h | 1 + iscsi-scst/usr/isns.c | 28 ++++++++++++++++------------ iscsi-scst/usr/param.h | 1 + 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/iscsi-scst/usr/event.c b/iscsi-scst/usr/event.c index 53211de45..56d2389d1 100644 --- a/iscsi-scst/usr/event.c +++ b/iscsi-scst/usr/event.c @@ -616,7 +616,15 @@ static int handle_e_get_attr_value(int fd, const struct iscsi_kern_event *event) add_key_mark(res_str, sizeof(res_str), 0); } else snprintf(res_str, sizeof(res_str), "%s\n", ""); - } else { + } else if (strcasecmp(ISCSI_ISNS_ENTITY_ATTR_NAME, pp) == 0) { + if (target != NULL) { + log_error("Not NULL target %s for global attribute %s", + target->name, pp); + res = -EINVAL; + goto out_free; + } + snprintf(res_str, sizeof(res_str), "%s", isns_entity_target_name); + } else { log_error("Unknown attribute %s", pp); res = -EINVAL; goto out_free; @@ -992,7 +1000,10 @@ static int handle_e_set_attr_value(int fd, const struct iscsi_kern_event *event) } } else goto out_free_server; - } else { + } else if (strcasecmp(ISCSI_ISNS_ENTITY_ATTR_NAME, pp) == 0) { + pp = config_sep_string(&p); + strlcpy(isns_entity_target_name, pp, sizeof(isns_entity_target_name)); + } else { log_error("Unknown attribute %s", pp); res = -EINVAL; goto out_free; diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index de2cf8906..5680b545d 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -721,6 +721,10 @@ int main(int argc, char **argv) S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR, 0); if (err != 0) exit(err); + err = kernel_attr_add(NULL, ISCSI_ISNS_ENTITY_ATTR_NAME, + S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR, 0); + if (err != 0) + exit(err); #endif if ((ipc_fd = iscsi_adm_request_listen()) < 0) { diff --git a/iscsi-scst/usr/iscsid.h b/iscsi-scst/usr/iscsid.h index e93980e50..b5e5d1c57 100644 --- a/iscsi-scst/usr/iscsid.h +++ b/iscsi-scst/usr/iscsid.h @@ -375,6 +375,7 @@ extern int iscsi_attr_replace(struct __qelem *attrs_list, const char *sysfs_name /* isns.c */ extern char *isns_server; extern int isns_access_control; +extern char isns_entity_target_name[ISCSI_NAME_LEN]; extern int isns_timeout; extern int isns_init(void); extern int isns_handle(int is_timeout); diff --git a/iscsi-scst/usr/isns.c b/iscsi-scst/usr/isns.c index b579e6c43..f23eec7b8 100644 --- a/iscsi-scst/usr/isns.c +++ b/iscsi-scst/usr/isns.c @@ -58,6 +58,7 @@ struct isns_initiator { char *isns_server; int isns_access_control; +char isns_entity_target_name[ISCSI_NAME_LEN]; int isns_timeout = -1; static LIST_HEAD(qry_list); @@ -299,16 +300,15 @@ static int isns_scn_register(void) tlv = (struct isns_tlv *)hdr->pdu; max_buf = sizeof(buf) - offsetof(struct isns_hdr, pdu); - target = list_entry(targets_list.q_forw, struct target, tlist); - - err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, + if (strlen(isns_entity_target_name) < 1) { + target = list_entry(targets_list.q_forw, struct target, tlist); + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, strlen(target->name) + 1, target->name); - if (err < 0) - goto out; - length += err; + } else { + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, + strlen(isns_entity_target_name) + 1, isns_entity_target_name); + } - err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, - strlen(target->name) + 1, target->name); if (err < 0) goto out; length += err; @@ -502,11 +502,15 @@ int isns_target_register(char *name) tlv = (struct isns_tlv *)hdr->pdu; max_buf = sizeof(buf) - offsetof(struct isns_hdr, pdu); - target = list_entry(targets_list.q_back, struct target, tlist); - - err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, + if (strlen(isns_entity_target_name) < 1) { + target = list_entry(targets_list.q_forw, struct target, tlist); + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, strlen(target->name) + 1, target->name); - if (err < 0) + } else { + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NAME, + strlen(isns_entity_target_name) + 1, isns_entity_target_name); + } +if (err < 0) goto out; length += err; diff --git a/iscsi-scst/usr/param.h b/iscsi-scst/usr/param.h index f6f91c72d..ae6f94c1a 100644 --- a/iscsi-scst/usr/param.h +++ b/iscsi-scst/usr/param.h @@ -20,6 +20,7 @@ #define ISCSI_ISNS_SERVER_ATTR_NAME "iSNSServer" #define ISCSI_ISNS_ACCESS_CONTROL_ATTR_NAME "iSNSAccessControl" #define ISCSI_ENABLED_ATTR_NAME "enabled" +#define ISCSI_ISNS_ENTITY_ATTR_NAME "isns_entity_name" #define ISCSI_ALLOWED_PORTAL_ATTR_NAME "allowed_portal" #define ISCSI_PER_PORTAL_ACL_ATTR_NAME "per_portal_acl" #define ISCSI_TARGET_REDIRECTION_ATTR_NAME "redirect"