Add support for iSCSI TargetAlias

This includes both support during iSCSI LOGIN and iSNS.
This commit is contained in:
Brian Meagher
2023-08-17 09:40:48 -07:00
committed by Gleb Chesnokov
parent c00af8aab9
commit 3c8f66e2b8
8 changed files with 115 additions and 2 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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",

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;