From: Gleb C. <lna...@ya...> - 2023-08-22 07:03:15
|
Commit: 3c8f66e GitHub URL: https://github.com/SCST-project/scst/commit/3c8f66e2b8876d4bbd9e14b56f48ab011de8d1bd Author: Brian Meagher Date: 2023-08-22T10:02:40+03:00 Log Message: ----------- Add support for iSCSI TargetAlias This includes both support during iSCSI LOGIN and iSNS. Modified Paths: -------------- iscsi-scst/README | 5 ++ iscsi-scst/usr/config.c | 26 +++++++ iscsi-scst/usr/ctldev.c | 12 +++- iscsi-scst/usr/event.c | 53 +++++++++++++++ iscsi-scst/usr/iscsid.c | 2 + iscsi-scst/usr/iscsid.h | 2 + iscsi-scst/usr/isns.c | 16 ++++- iscsi-scst/usr/param.h | 1 + 8 files changed, 115 insertions(+), 2 deletions(-) =================================================================== diff --git a/iscsi-scst/README b/iscsi-scst/README index 9f67fac..d086c6e 100644 --- a/iscsi-scst/README +++ b/iscsi-scst/README @@ -283,6 +283,10 @@ Each target subdirectory contains the following entries: - tid - TID of this target. + - alias - TargetAlias of this target. If not set, it will default to the + empty string and no TargetAlias will be reported in LOGIN RESPONSE or iSNS + for this target. + The "sessions" subdirectory contains the following attribute: - thread_pid - the process identifiers (PIDs) of the iscsird and iscsiwr @@ -559,6 +563,7 @@ both iSCSI-SCST targets will look like: | | |-- NopInInterval | | |-- QueuedCommands | | |-- RspTimeout +| | |-- alias | | |-- enabled | | |-- ini_groups | | | `-- mgmt diff --git a/iscsi-scst/usr/config.c b/iscsi-scst/usr/config.c index e90a05b..35fb16b 100644 --- a/iscsi-scst/usr/config.c +++ b/iscsi-scst/usr/config.c @@ -265,6 +265,32 @@ char *config_sep_string(char **pp) return p; } +/* + * Strip leading and trailing whitespace. + * + * Modifies the contents of the parameter string. + */ +char *config_strip_string(char *s) +{ + size_t size; + char *end; + + size = strlen(s); + + if (!size) + return s; + + end = s + size - 1; + while (end >= s && isspace(*end)) + end--; + *(end + 1) = '\0'; + + while (*s && isspace(*s)) + s++; + + return s; +} + static char *config_gets(char *buf, int size, const char *data, int *offset) { int offs = *offset, i = 0; diff --git a/iscsi-scst/usr/ctldev.c b/iscsi-scst/usr/ctldev.c index 70258cc..49efe56 100644 --- a/iscsi-scst/usr/ctldev.c +++ b/iscsi-scst/usr/ctldev.c @@ -78,7 +78,12 @@ int kernel_target_create(struct target *target, u32 *tid, u32 cookie) info.tid = (tid != NULL) ? *tid : 0; info.cookie = cookie; - info.attrs_num = 2; + /* + * ISCSI_PER_PORTAL_ACL_ATTR_NAME + * ISCSI_TARGET_REDIRECTION_ATTR_NAME + * ISCSI_TARGET_ALIAS_ATTR_NAME + */ + info.attrs_num = 3; for (j = 0; j < session_key_last; j++) { if (session_keys[j].show_in_sysfs) @@ -117,6 +122,11 @@ int kernel_target_create(struct target *target, u32 *tid, u32 cookie) sizeof(ISCSI_TARGET_REDIRECTION_ATTR_NAME)); i++; + kern_attrs[i].mode = 0644; + strlcpy(kern_attrs[i].name, ISCSI_TARGET_ALIAS_ATTR_NAME, + sizeof(ISCSI_TARGET_ALIAS_ATTR_NAME)); + i++; + for (j = 0; j < session_key_last; j++) { if (!session_keys[j].show_in_sysfs) continue; diff --git a/iscsi-scst/usr/event.c b/iscsi-scst/usr/event.c index 61cb132..e08cd4b 100644 --- a/iscsi-scst/usr/event.c +++ b/iscsi-scst/usr/event.c @@ -611,6 +611,17 @@ 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 *res_str = '\0'; + } else if (strcasecmp(ISCSI_TARGET_ALIAS_ATTR_NAME, pp) == 0) { + if (target == NULL) { + log_error("Target expected for attr %s", pp); + res = -EINVAL; + goto out_free; + } + if (target->alias) { + snprintf(res_str, sizeof(res_str), "%s\n", target->alias); + add_key_mark(res_str, sizeof(res_str), 0); + } else + *res_str = '\0'; } else if (strcasecmp(ISCSI_ISNS_SERVER_ATTR_NAME, pp) == 0) { if (target != NULL) { log_error("Not NULL target %s for global attribute %s", @@ -955,6 +966,48 @@ static int handle_e_set_attr_value(int fd, const struct iscsi_kern_event *event) res = handle_target_redirect(target, p); if (res != 0) goto out_free; + } else if (strcasecmp(ISCSI_TARGET_ALIAS_ATTR_NAME, pp) == 0) { + bool alias_changed = false; + + if (target == NULL) { + log_error("Target expected for attr %s", pp); + res = -EINVAL; + goto out_free; + } + p = config_strip_string(p); + if (*p == '\0') { + if (target->alias) { + free(target->alias); + target->alias = NULL; + alias_changed = true; + } + } else { + char *newval = strdup(p); + + if (newval == NULL) { + log_error("Unable to duplicate alias name %s", p); + res = -ENOMEM; + goto out_free; + } + if (target->alias) + free(target->alias); + target->alias = newval; + alias_changed = true; + } + /* If we previously registered an alias and we need to update it */ + if (alias_changed && target->isns_registered) { + if (target->alias) { + isns_target_register(target->name); + } else { + /* + * We have cleared a previously set alias. + * Work-around to make change visible in + * open-isns server. + */ + isns_target_deregister(target->name); + isns_target_register(target->name); + } + } } else if (strcasecmp(ISCSI_ISNS_SERVER_ATTR_NAME, pp) == 0) { if (target != NULL) { log_error("Not NULL target %s for global attribute %s", diff --git a/iscsi-scst/usr/iscsid.c b/iscsi-scst/usr/iscsid.c index 773fa50..1ef94ce 100644 --- a/iscsi-scst/usr/iscsid.c +++ b/iscsi-scst/usr/iscsid.c @@ -921,6 +921,8 @@ static void login_start(struct connection *conn) return; } } + if (target->alias) + text_key_add(conn, "TargetAlias", target->alias); log_debug(1, "target %s, sessions_count %d", target_name, target->sessions_count); } diff --git a/iscsi-scst/usr/iscsid.h b/iscsi-scst/usr/iscsid.h index 4155d2a..69146bd 100644 --- a/iscsi-scst/usr/iscsid.h +++ b/iscsi-scst/usr/iscsid.h @@ -198,6 +198,7 @@ struct target { unsigned int tgt_enabled:1; unsigned int per_portal_acl:1; + unsigned int isns_registered:1; unsigned int target_params[target_key_last]; unsigned int session_params[session_key_last]; @@ -353,6 +354,7 @@ extern int nl_open(void); /* config.c */ extern char *config_sep_string(char **pp); +extern char *config_strip_string(char *s); extern int config_parse_main(const char *data, u32 cookie); extern int config_load(const char *config_name); extern int config_target_create(u32 *tid, char *name); diff --git a/iscsi-scst/usr/isns.c b/iscsi-scst/usr/isns.c index 75ffa8a..323e00c 100644 --- a/iscsi-scst/usr/isns.c +++ b/iscsi-scst/usr/isns.c @@ -482,7 +482,7 @@ int isns_target_register(char *name) uint32_t port = htonl(server_port); uint32_t node = htonl(ISNS_NODE_TARGET); uint32_t type = htonl(2); - struct target *target; + struct target *target, *alias_target; int err, initial = list_length_is_one(&targets_list); int max_buf; @@ -499,6 +499,7 @@ int isns_target_register(char *name) tlv = (struct isns_tlv *)hdr->pdu; max_buf = sizeof(buf) - offsetof(struct isns_hdr, pdu); + alias_target = target_find_by_name(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, @@ -566,6 +567,14 @@ int isns_target_register(char *name) goto out; length += err; + if (alias_target && alias_target->alias) { + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_ALIAS, + strlen(alias_target->alias) + 1, alias_target->alias); + if (err < 0) + goto out; + length += err; + } + err = isns_tlv_set(&tlv, max_buf - length, ISNS_ATTR_ISCSI_NODE_TYPE, sizeof(node), &node); if (err < 0) @@ -579,6 +588,8 @@ int isns_target_register(char *name) err = write(isns_fd, buf, length + sizeof(struct isns_hdr)); if (err < 0) log_error("%s %d: %s", __func__, __LINE__, strerror(errno)); + else if (alias_target) + alias_target->isns_registered = 1; if (scn_listen_port) isns_scn_register(); @@ -662,6 +673,9 @@ int isns_target_deregister(char *name) if (err < 0) log_error("%s %d: %s", __func__, __LINE__, strerror(errno)); + if (target) + target->isns_registered = 0; + out: return err; } diff --git a/iscsi-scst/usr/param.h b/iscsi-scst/usr/param.h index 994232c..6a1d8b7 100644 --- a/iscsi-scst/usr/param.h +++ b/iscsi-scst/usr/param.h @@ -25,6 +25,7 @@ #define ISCSI_TARGET_REDIRECTION_ATTR_NAME "redirect" #define ISCSI_TARGET_REDIRECTION_VALUE_TEMP "temp" #define ISCSI_TARGET_REDIRECTION_VALUE_PERM "perm" +#define ISCSI_TARGET_ALIAS_ATTR_NAME "alias" struct iscsi_key; |