iscsi: Manage PG-IG maps of the target by linked list

This patch is a preparation for dynamic reconfiguration of PG-IG maps.

Current PG-IG map is implemented by a fixed-size array. Linked list
will make much easier to support dynamic reconfiguration of PG-IG maps.

Current:
target - (1..n) ---> PG_map (1..1) -> PG
                 |
                 --> IG_map (1..1) -> IG

This proposal:
target - (1..n) -> PG_map --- (1..1) -> PG
                           |
                           -- (1..m) -> IG_map - (1..1) -> IG

Change-Id: I92f668b81cdd8003aff222926f8f1ed96b61e56d
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/385532
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Shuhei Matsumoto 2017-11-30 10:43:01 +09:00 committed by Jim Harris
parent d07df58419
commit c5e5047d99
5 changed files with 380 additions and 216 deletions

View File

@ -255,6 +255,8 @@ spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,
{ {
struct spdk_json_write_ctx *w; struct spdk_json_write_ctx *w;
struct spdk_iscsi_tgt_node *tgtnode; struct spdk_iscsi_tgt_node *tgtnode;
struct spdk_iscsi_pg_map *pg_map;
struct spdk_iscsi_ig_map *ig_map;
int i; int i;
if (params != NULL) { if (params != NULL) {
@ -283,13 +285,15 @@ spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,
spdk_json_write_name(w, "pg_ig_maps"); spdk_json_write_name(w, "pg_ig_maps");
spdk_json_write_array_begin(w); spdk_json_write_array_begin(w);
for (i = 0; i < tgtnode->maxmap; i++) { TAILQ_FOREACH(pg_map, &tgtnode->pg_map_head, tailq) {
spdk_json_write_object_begin(w); TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
spdk_json_write_name(w, "pg_tag"); spdk_json_write_object_begin(w);
spdk_json_write_int32(w, tgtnode->map[i].pg->tag); spdk_json_write_name(w, "pg_tag");
spdk_json_write_name(w, "ig_tag"); spdk_json_write_int32(w, pg_map->pg->tag);
spdk_json_write_int32(w, tgtnode->map[i].ig->tag); spdk_json_write_name(w, "ig_tag");
spdk_json_write_object_end(w); spdk_json_write_int32(w, ig_map->ig->tag);
spdk_json_write_object_end(w);
}
} }
spdk_json_write_array_end(w); spdk_json_write_array_end(w);

View File

@ -228,9 +228,11 @@ static const char *target_nodes_section = \
static void static void
spdk_iscsi_config_dump_target_nodes(FILE *fp) spdk_iscsi_config_dump_target_nodes(FILE *fp)
{ {
int l = 0, m = 0; int l = 0;
struct spdk_scsi_dev *dev = NULL; struct spdk_scsi_dev *dev = NULL;
struct spdk_iscsi_tgt_node *target = NULL; struct spdk_iscsi_tgt_node *target = NULL;
struct spdk_iscsi_pg_map *pg_map;
struct spdk_iscsi_ig_map *ig_map;
/* Create target nodes section */ /* Create target nodes section */
fprintf(fp, "%s", target_nodes_section); fprintf(fp, "%s", target_nodes_section);
@ -247,13 +249,12 @@ spdk_iscsi_config_dump_target_nodes(FILE *fp)
idx = target->num; idx = target->num;
fprintf(fp, TARGET_NODE_TMPL, idx, idx, target->name, spdk_scsi_dev_get_name(dev)); fprintf(fp, TARGET_NODE_TMPL, idx, idx, target->name, spdk_scsi_dev_get_name(dev));
for (m = 0; m < target->maxmap; m++) { TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
if (NULL == target->map[m].pg) continue; TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
if (NULL == target->map[m].ig) continue; fprintf(fp, TARGET_NODE_PGIG_MAPPING_TMPL,
pg_map->pg->tag,
fprintf(fp, TARGET_NODE_PGIG_MAPPING_TMPL, ig_map->ig->tag);
target->map[m].pg->tag, }
target->map[m].ig->tag);
} }
if (target->auth_chap_disabled) if (target->auth_chap_disabled)

View File

@ -214,13 +214,17 @@ spdk_iscsi_init_grp_allow_iscsi_name(struct spdk_iscsi_init_grp *igp,
return -1; return -1;
} }
static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_find_pg_map(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_portal_grp *pg);
bool bool
spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn, spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_tgt_node *target, const char *iqn, const char *addr) struct spdk_iscsi_tgt_node *target, const char *iqn, const char *addr)
{ {
struct spdk_iscsi_portal_grp *pg; struct spdk_iscsi_portal_grp *pg;
struct spdk_iscsi_init_grp *igp; struct spdk_iscsi_pg_map *pg_map;
int i; struct spdk_iscsi_ig_map *ig_map;
int rc; int rc;
bool allowed = false; bool allowed = false;
@ -230,17 +234,17 @@ spdk_iscsi_tgt_node_access(struct spdk_iscsi_conn *conn,
SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "pg=%d, iqn=%s, addr=%s\n", SPDK_DEBUGLOG(SPDK_TRACE_ISCSI, "pg=%d, iqn=%s, addr=%s\n",
pg->tag, iqn, addr); pg->tag, iqn, addr);
for (i = 0; i < target->maxmap; i++) { pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
/* skip excluding self portal group tag */ if (pg_map == NULL) {
if (pg != target->map[i].pg) return false;
continue; }
igp = target->map[i].ig; TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &allowed); rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &allowed);
if (rc == 0) { if (rc == 0) {
if (allowed == false) { if (allowed == false) {
goto denied; goto denied;
} else { } else {
if (spdk_iscsi_init_grp_allow_addr(igp, addr)) { if (spdk_iscsi_init_grp_allow_addr(ig_map->ig, addr)) {
return true; return true;
} }
} }
@ -259,28 +263,21 @@ denied:
static bool static bool
spdk_iscsi_tgt_node_allow_iscsi_name(struct spdk_iscsi_tgt_node *target, const char *iqn) spdk_iscsi_tgt_node_allow_iscsi_name(struct spdk_iscsi_tgt_node *target, const char *iqn)
{ {
struct spdk_iscsi_init_grp *igp; struct spdk_iscsi_pg_map *pg_map;
int i, j; struct spdk_iscsi_ig_map *ig_map;
int rc; int rc;
bool result = false; bool result = false;
if (target == NULL || iqn == NULL) if (target == NULL || iqn == NULL)
return false; return false;
for (i = 0; i < target->maxmap; i++) { TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
igp = target->map[i].ig; TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
/* skip same ig_tag */ rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &result);
for (j = 0; j < i; j++) { if (rc == 0) {
if (target->map[j].ig->tag == igp->tag) { return result;
goto skip_ig_tag;
} }
} }
rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &result);
if (rc == 0) {
return result;
}
skip_ig_tag:
;
} }
return false; return false;
@ -293,14 +290,13 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
{ {
char buf[MAX_TMPBUF]; char buf[MAX_TMPBUF];
struct spdk_iscsi_portal_grp *pg; struct spdk_iscsi_portal_grp *pg;
struct spdk_iscsi_portal *p; struct spdk_iscsi_pg_map *pg_map;
struct spdk_iscsi_portal *p;
struct spdk_iscsi_tgt_node *target; struct spdk_iscsi_tgt_node *target;
char *host; char *host;
int total; int total;
int len; int len;
int rc; int rc;
int pg_tag;
int i, j;
if (conn == NULL) if (conn == NULL)
return 0; return 0;
@ -336,53 +332,41 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
"TargetName=%s", target->name); "TargetName=%s", target->name);
total += len + 1; total += len + 1;
for (i = 0; i < target->maxmap; i++) { /* write to data */
pg_tag = target->map[i].pg->tag; TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
/* skip same pg_tag */ pg = pg_map->pg;
for (j = 0; j < i; j++) { TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
if (target->map[j].pg->tag == pg_tag) { if (alloc_len - total < 1) {
goto skip_pg_tag; pthread_mutex_unlock(&g_spdk_iscsi.mutex);
SPDK_ERRLOG("data space small %d\n", alloc_len);
return total;
} }
} host = p->host;
/* write to data */ /* wildcard? */
TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) { if (strcasecmp(host, "[::]") == 0
if (pg->tag != pg_tag) || strcasecmp(host, "0.0.0.0") == 0) {
continue; if (spdk_sock_is_ipv6(conn->sock)) {
TAILQ_FOREACH(p, &pg->head, per_pg_tailq) { snprintf(buf, sizeof buf, "[%s]",
if (alloc_len - total < 1) { conn->target_addr);
pthread_mutex_unlock(&g_spdk_iscsi.mutex); host = buf;
SPDK_ERRLOG("data space small %d\n", alloc_len); } else if (spdk_sock_is_ipv4(conn->sock)) {
return total; snprintf(buf, sizeof buf, "%s",
conn->target_addr);
host = buf;
} else {
/* skip portal for the family */
continue;
} }
host = p->host;
/* wildcard? */
if (strcasecmp(host, "[::]") == 0
|| strcasecmp(host, "0.0.0.0") == 0) {
if (spdk_sock_is_ipv6(conn->sock)) {
snprintf(buf, sizeof buf, "[%s]",
conn->target_addr);
host = buf;
} else if (spdk_sock_is_ipv4(conn->sock)) {
snprintf(buf, sizeof buf, "%s",
conn->target_addr);
host = buf;
} else {
/* skip portal for the family */
continue;
}
}
SPDK_DEBUGLOG(SPDK_TRACE_ISCSI,
"TargetAddress=%s:%s,%d\n",
host, p->port, pg->tag);
len = snprintf((char *) data + total,
alloc_len - total,
"TargetAddress=%s:%s,%d",
host, p->port, pg->tag);
total += len + 1;
} }
SPDK_DEBUGLOG(SPDK_TRACE_ISCSI,
"TargetAddress=%s:%s,%d\n",
host, p->port, pg->tag);
len = snprintf((char *) data + total,
alloc_len - total,
"TargetAddress=%s:%s,%d",
host, p->port, pg->tag);
total += len + 1;
} }
skip_pg_tag:
;
} }
} }
pthread_mutex_unlock(&g_spdk_iscsi.mutex); pthread_mutex_unlock(&g_spdk_iscsi.mutex);
@ -446,6 +430,241 @@ spdk_iscsi_tgt_node_unregister(struct spdk_iscsi_tgt_node *target)
return -1; return -1;
} }
static struct spdk_iscsi_ig_map *
spdk_iscsi_pg_map_find_ig_map(struct spdk_iscsi_pg_map *pg_map,
struct spdk_iscsi_init_grp *ig)
{
struct spdk_iscsi_ig_map *ig_map;
TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
if (ig_map->ig == ig) {
return ig_map;
}
}
return NULL;
}
static struct spdk_iscsi_ig_map *
spdk_iscsi_pg_map_add_ig_map(struct spdk_iscsi_pg_map *pg_map,
struct spdk_iscsi_init_grp *ig)
{
struct spdk_iscsi_ig_map *ig_map;
if (spdk_iscsi_pg_map_find_ig_map(pg_map, ig) != NULL) {
return NULL;
}
ig_map = malloc(sizeof(*ig_map));
if (ig_map == NULL) {
return NULL;
}
ig_map->ig = ig;
ig->ref++;
pg_map->num_ig_maps++;
TAILQ_INSERT_TAIL(&pg_map->ig_map_head, ig_map, tailq);
return ig_map;
}
static void
_spdk_iscsi_pg_map_delete_ig_map(struct spdk_iscsi_pg_map *pg_map,
struct spdk_iscsi_ig_map *ig_map)
{
TAILQ_REMOVE(&pg_map->ig_map_head, ig_map, tailq);
pg_map->num_ig_maps--;
ig_map->ig->ref--;
free(ig_map);
}
static int
spdk_iscsi_pg_map_delete_ig_map(struct spdk_iscsi_pg_map *pg_map,
struct spdk_iscsi_init_grp *ig)
{
struct spdk_iscsi_ig_map *ig_map;
ig_map = spdk_iscsi_pg_map_find_ig_map(pg_map, ig);
if (ig_map == NULL) {
return -ENOENT;
}
_spdk_iscsi_pg_map_delete_ig_map(pg_map, ig_map);
return 0;
}
static void
spdk_iscsi_pg_map_delete_all_ig_maps(struct spdk_iscsi_pg_map *pg_map)
{
struct spdk_iscsi_ig_map *ig_map, *tmp;
TAILQ_FOREACH_SAFE(ig_map, &pg_map->ig_map_head, tailq, tmp) {
_spdk_iscsi_pg_map_delete_ig_map(pg_map, ig_map);
}
}
static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_find_pg_map(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_portal_grp *pg)
{
struct spdk_iscsi_pg_map *pg_map;
TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
if (pg_map->pg == pg) {
return pg_map;
}
}
return NULL;
}
static struct spdk_iscsi_pg_map *
spdk_iscsi_tgt_node_add_pg_map(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_portal_grp *pg)
{
struct spdk_iscsi_pg_map *pg_map;
if (spdk_iscsi_tgt_node_find_pg_map(target, pg) != NULL) {
return NULL;
}
pg_map = malloc(sizeof(*pg_map));
if (pg_map == NULL) {
return NULL;
}
TAILQ_INIT(&pg_map->ig_map_head);
pg_map->num_ig_maps = 0;
pg->ref++;
pg_map->pg = pg;
target->num_pg_maps++;
TAILQ_INSERT_TAIL(&target->pg_map_head, pg_map, tailq);
return pg_map;
}
static void
_spdk_iscsi_tgt_node_delete_pg_map(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_pg_map *pg_map)
{
TAILQ_REMOVE(&target->pg_map_head, pg_map, tailq);
target->num_pg_maps--;
pg_map->pg->ref--;
free(pg_map);
}
static int
spdk_iscsi_tgt_node_delete_pg_map(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_portal_grp *pg)
{
struct spdk_iscsi_pg_map *pg_map;
pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
if (pg_map == NULL) {
return -ENOENT;
}
if (pg_map->num_ig_maps > 0) {
return -ENOTEMPTY;
}
_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
return 0;
}
static void
spdk_iscsi_tgt_node_delete_ig_maps(struct spdk_iscsi_tgt_node *target,
struct spdk_iscsi_init_grp *ig)
{
struct spdk_iscsi_pg_map *pg_map, *tmp;
TAILQ_FOREACH_SAFE(pg_map, &target->pg_map_head, tailq, tmp) {
spdk_iscsi_pg_map_delete_ig_map(pg_map, ig);
if (pg_map->num_ig_maps == 0) {
_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
}
}
}
static void
spdk_iscsi_tgt_node_delete_all_pg_maps(struct spdk_iscsi_tgt_node *target)
{
struct spdk_iscsi_pg_map *pg_map, *tmp;
TAILQ_FOREACH_SAFE(pg_map, &target->pg_map_head, tailq, tmp) {
spdk_iscsi_pg_map_delete_all_ig_maps(pg_map);
_spdk_iscsi_tgt_node_delete_pg_map(target, pg_map);
}
}
static void
spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target)
{
if (target == NULL) {
return;
}
free(target->name);
free(target->alias);
spdk_iscsi_tgt_node_delete_all_pg_maps(target);
spdk_scsi_dev_destruct(target->dev);
pthread_mutex_destroy(&target->mutex);
free(target);
}
static int
spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target,
int pg_tag, int ig_tag)
{
struct spdk_iscsi_portal_grp *pg;
struct spdk_iscsi_pg_map *pg_map;
struct spdk_iscsi_init_grp *ig;
struct spdk_iscsi_ig_map *ig_map;
bool new_pg_map = false;
pthread_mutex_lock(&g_spdk_iscsi.mutex);
pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag);
if (pg == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag);
return -ENOENT;
}
ig = spdk_iscsi_init_grp_find_by_tag(ig_tag);
if (ig == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag);
return -ENOENT;
}
/* get existing pg_map or create new pg_map and add it to target */
pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
if (pg_map == NULL) {
pg_map = spdk_iscsi_tgt_node_add_pg_map(target, pg);
if (pg_map == NULL) {
goto failed;
}
new_pg_map = true;
}
/* create new ig_map and add it to pg_map */
ig_map = spdk_iscsi_pg_map_add_ig_map(pg_map, ig);
if (ig_map == NULL) {
goto failed;
}
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
return 0;
failed:
if (new_pg_map) {
spdk_iscsi_tgt_node_delete_pg_map(target, pg);
}
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
return -1;
}
static int static int
spdk_check_iscsi_name(const char *name) spdk_check_iscsi_name(const char *name)
{ {
@ -488,64 +707,6 @@ spdk_check_iscsi_name(const char *name)
return 0; return 0;
} }
static void
spdk_iscsi_tgt_node_destruct(struct spdk_iscsi_tgt_node *target)
{
int i;
if (target == NULL) {
return;
}
free(target->name);
free(target->alias);
spdk_scsi_dev_destruct(target->dev);
for (i = 0; i < target->maxmap; i++) {
target->map[i].pg->ref--;
target->map[i].ig->ref--;
}
pthread_mutex_destroy(&target->mutex);
free(target);
}
static struct spdk_iscsi_tgt_node_map *
spdk_iscsi_tgt_node_add_map(struct spdk_iscsi_tgt_node *target,
int pg_tag, int ig_tag)
{
struct spdk_iscsi_tgt_node_map *map;
struct spdk_iscsi_portal_grp *pg;
struct spdk_iscsi_init_grp *ig;
if (target->maxmap >= MAX_TARGET_MAP) {
SPDK_ERRLOG("%s: no space for new map\n", target->name);
return NULL;
}
pthread_mutex_lock(&g_spdk_iscsi.mutex);
pg = spdk_iscsi_portal_grp_find_by_tag(pg_tag);
if (pg == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
SPDK_ERRLOG("%s: PortalGroup%d not found\n", target->name, pg_tag);
return NULL;
}
ig = spdk_iscsi_init_grp_find_by_tag(ig_tag);
if (ig == NULL) {
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
SPDK_ERRLOG("%s: InitiatorGroup%d not found\n", target->name, ig_tag);
return NULL;
}
pg->ref++;
ig->ref++;
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
map = &target->map[target->maxmap];
map->pg = pg;
map->ig = ig;
target->maxmap++;
return map;
}
_spdk_iscsi_tgt_node * _spdk_iscsi_tgt_node *
spdk_iscsi_tgt_node_construct(int target_index, spdk_iscsi_tgt_node_construct(int target_index,
const char *name, const char *alias, const char *name, const char *alias,
@ -557,19 +718,18 @@ spdk_iscsi_tgt_node_construct(int target_index,
{ {
char fullname[MAX_TMPBUF], port_name[MAX_TMPBUF]; char fullname[MAX_TMPBUF], port_name[MAX_TMPBUF];
struct spdk_iscsi_tgt_node *target; struct spdk_iscsi_tgt_node *target;
struct spdk_iscsi_tgt_node_map *map;
struct spdk_iscsi_portal_grp *unique_portal_groups[SPDK_SCSI_DEV_MAX_PORTS];
struct spdk_iscsi_portal_grp *pg; struct spdk_iscsi_portal_grp *pg;
struct spdk_iscsi_pg_map *pg_map;
int num_unique_portal_groups; int num_unique_portal_groups;
int i, j, rc; int i, rc;
if (auth_chap_disabled && auth_chap_required) { if (auth_chap_disabled && auth_chap_required) {
SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n"); SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n");
return NULL; return NULL;
} }
if ((num_maps > MAX_TARGET_MAP) || (num_maps == 0)) { if (num_maps == 0) {
SPDK_ERRLOG("num_maps = %d out of range\n", num_maps); SPDK_ERRLOG("num_maps = 0\n");
return NULL; return NULL;
} }
@ -635,37 +795,31 @@ spdk_iscsi_tgt_node_construct(int target_index,
return NULL; return NULL;
} }
num_unique_portal_groups = 0; TAILQ_INIT(&target->pg_map_head);
for (i = 0; i < num_maps; i++) { for (i = 0; i < num_maps; i++) {
map = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i], rc = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i],
ig_tag_list[i]); ig_tag_list[i]);
if (map == NULL) { if (rc != 0) {
SPDK_ERRLOG("could not add map to target\n"); SPDK_ERRLOG("could not add map to target\n");
spdk_iscsi_tgt_node_destruct(target); spdk_iscsi_tgt_node_destruct(target);
return NULL; return NULL;
} }
}
for (j = 0; j < num_unique_portal_groups; j++) { num_unique_portal_groups = 0;
if (unique_portal_groups[j] == map->pg) { TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
break;
}
}
if (j == SPDK_SCSI_DEV_MAX_PORTS) { if (++num_unique_portal_groups > SPDK_SCSI_DEV_MAX_PORTS) {
SPDK_ERRLOG("too many unique portal groups\n"); SPDK_ERRLOG("too many unique portal groups\n");
spdk_iscsi_tgt_node_destruct(target); spdk_iscsi_tgt_node_destruct(target);
return NULL; return NULL;
} }
if (j == num_unique_portal_groups) { pg = pg_map->pg;
pg = map->pg; snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x",
snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x", name, pg->tag);
name, pg->tag); spdk_scsi_dev_add_port(target->dev, pg->tag, port_name);
spdk_scsi_dev_add_port(target->dev, pg->tag, port_name);
unique_portal_groups[j] = pg;
num_unique_portal_groups++;
}
} }
target->auth_chap_disabled = auth_chap_disabled; target->auth_chap_disabled = auth_chap_disabled;
@ -1002,37 +1156,15 @@ void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group,
struct spdk_iscsi_init_grp *initiator_group) struct spdk_iscsi_init_grp *initiator_group)
{ {
struct spdk_iscsi_tgt_node *target; struct spdk_iscsi_tgt_node *target;
int i = 0;
int j = 0;
int flag = 0;
pthread_mutex_lock(&g_spdk_iscsi.mutex);
TAILQ_FOREACH(target, &g_spdk_iscsi.target_head, tailq) { TAILQ_FOREACH(target, &g_spdk_iscsi.target_head, tailq) {
loop: if (portal_group) {
flag = 0; spdk_iscsi_tgt_node_delete_pg_map(target, portal_group);
for (i = 0; i < target->maxmap; i++) { }
if (portal_group) { if (initiator_group) {
if (target->map[i].pg->tag == portal_group->tag) { spdk_iscsi_tgt_node_delete_ig_maps(target, initiator_group);
flag = 1;
}
}
if (initiator_group) {
if (target->map[i].ig->tag == initiator_group->tag) {
flag = 1;
}
}
if (flag == 1) {
target->map[i].pg->ref--;
target->map[i].ig->ref--;
for (j = i; j < target->maxmap - 1; j++) {
target->map[j].pg = target->map[j + 1].pg;
target->map[j].ig = target->map[j + 1].ig;
}
target->map[target->maxmap - 1].pg = NULL;
target->map[target->maxmap - 1].ig = NULL;
target->maxmap -= 1;
goto loop;
}
} }
} }
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
} }

View File

@ -40,14 +40,24 @@
#include "spdk/scsi.h" #include "spdk/scsi.h"
struct spdk_iscsi_conn; struct spdk_iscsi_conn;
struct spdk_iscsi_init_grp;
struct spdk_iscsi_portal_grp;
struct spdk_iscsi_portal;
#define SPDK_ISCSI_MAX_QUEUE_DEPTH 64 #define SPDK_ISCSI_MAX_QUEUE_DEPTH 64
#define MAX_TARGET_MAP 256 #define MAX_TARGET_MAP 256
#define SPDK_TN_TAG_MAX 0x0000ffff #define SPDK_TN_TAG_MAX 0x0000ffff
struct spdk_iscsi_tgt_node_map { struct spdk_iscsi_ig_map {
struct spdk_iscsi_portal_grp *pg; struct spdk_iscsi_init_grp *ig;
struct spdk_iscsi_init_grp *ig; TAILQ_ENTRY(spdk_iscsi_ig_map) tailq;
};
struct spdk_iscsi_pg_map {
struct spdk_iscsi_portal_grp *pg;
int num_ig_maps;
TAILQ_HEAD(, spdk_iscsi_ig_map) ig_map_head;
TAILQ_ENTRY(spdk_iscsi_pg_map) tailq ;
}; };
struct spdk_iscsi_tgt_node { struct spdk_iscsi_tgt_node {
@ -73,8 +83,8 @@ struct spdk_iscsi_tgt_node {
uint32_t num_active_conns; uint32_t num_active_conns;
int lcore; int lcore;
int maxmap; int num_pg_maps;
struct spdk_iscsi_tgt_node_map map[MAX_TARGET_MAP]; TAILQ_HEAD(, spdk_iscsi_pg_map) pg_map_head;
TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq; TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq;
}; };

View File

@ -186,6 +186,7 @@ node_access_allowed(void)
struct spdk_iscsi_portal portal; struct spdk_iscsi_portal portal;
struct spdk_iscsi_initiator_name iname; struct spdk_iscsi_initiator_name iname;
struct spdk_iscsi_initiator_netmask imask; struct spdk_iscsi_initiator_netmask imask;
struct spdk_iscsi_pg_map *pg_map;
char *iqn, *addr; char *iqn, *addr;
bool result; bool result;
@ -209,10 +210,10 @@ node_access_allowed(void)
/* target initialization */ /* target initialization */
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node)); memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
tgtnode.maxmap = 1;
tgtnode.name = "iqn.2017-10.spdk.io:0001"; tgtnode.name = "iqn.2017-10.spdk.io:0001";
tgtnode.map[0].pg = &pg; TAILQ_INIT(&tgtnode.pg_map_head);
tgtnode.map[0].ig = &ig; pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);
/* portal initialization */ /* portal initialization */
memset(&portal, 0, sizeof(struct spdk_iscsi_portal)); memset(&portal, 0, sizeof(struct spdk_iscsi_portal));
@ -229,6 +230,9 @@ node_access_allowed(void)
result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr); result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
CU_ASSERT(result == true); CU_ASSERT(result == true);
spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig);
spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
} }
static void static void
@ -240,6 +244,7 @@ node_access_denied_by_empty_netmask(void)
struct spdk_iscsi_conn conn; struct spdk_iscsi_conn conn;
struct spdk_iscsi_portal portal; struct spdk_iscsi_portal portal;
struct spdk_iscsi_initiator_name iname; struct spdk_iscsi_initiator_name iname;
struct spdk_iscsi_pg_map *pg_map;
char *iqn, *addr; char *iqn, *addr;
bool result; bool result;
@ -261,10 +266,10 @@ node_access_denied_by_empty_netmask(void)
/* target initialization */ /* target initialization */
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node)); memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
tgtnode.maxmap = 1;
tgtnode.name = "iqn.2017-10.spdk.io:0001"; tgtnode.name = "iqn.2017-10.spdk.io:0001";
tgtnode.map[0].pg = &pg; TAILQ_INIT(&tgtnode.pg_map_head);
tgtnode.map[0].ig = &ig; pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);
/* portal initialization */ /* portal initialization */
memset(&portal, 0, sizeof(struct spdk_iscsi_portal)); memset(&portal, 0, sizeof(struct spdk_iscsi_portal));
@ -282,6 +287,8 @@ node_access_denied_by_empty_netmask(void)
result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr); result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
CU_ASSERT(result == false); CU_ASSERT(result == false);
spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig);
spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
} }
#define IQN1 "iqn.2017-11.spdk.io:0001" #define IQN1 "iqn.2017-11.spdk.io:0001"
@ -300,18 +307,17 @@ node_access_multi_initiator_groups_cases(void)
struct spdk_iscsi_init_grp ig1, ig2; struct spdk_iscsi_init_grp ig1, ig2;
struct spdk_iscsi_initiator_name iname1, iname2; struct spdk_iscsi_initiator_name iname1, iname2;
struct spdk_iscsi_initiator_netmask imask1, imask2; struct spdk_iscsi_initiator_netmask imask1, imask2;
struct spdk_iscsi_pg_map *pg_map;
char *iqn, *addr; char *iqn, *addr;
bool result; bool result;
/* target initialization */ /* target initialization */
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node)); memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
tgtnode.maxmap = 2;
tgtnode.name = IQN1; tgtnode.name = IQN1;
TAILQ_INIT(&tgtnode.pg_map_head);
tgtnode.map[0].pg = &pg; pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
tgtnode.map[0].ig = &ig1; spdk_iscsi_pg_map_add_ig_map(pg_map, &ig1);
tgtnode.map[1].pg = &pg; spdk_iscsi_pg_map_add_ig_map(pg_map, &ig2);
tgtnode.map[1].ig = &ig2;
/* portal group initialization */ /* portal group initialization */
memset(&pg, 0, sizeof(struct spdk_iscsi_portal_grp)); memset(&pg, 0, sizeof(struct spdk_iscsi_portal_grp));
@ -533,23 +539,30 @@ node_access_multi_initiator_groups_cases(void)
result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr); result = spdk_iscsi_tgt_node_access(&conn, &tgtnode, iqn, addr);
CU_ASSERT(result == false); CU_ASSERT(result == false);
spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig1);
spdk_iscsi_pg_map_delete_ig_map(pg_map, &ig2);
spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg);
} }
static void static void
allow_iscsi_name_multi_maps_case(void) allow_iscsi_name_multi_maps_case(void)
{ {
struct spdk_iscsi_tgt_node tgtnode; struct spdk_iscsi_tgt_node tgtnode;
struct spdk_iscsi_portal_grp pg1, pg2;
struct spdk_iscsi_init_grp ig; struct spdk_iscsi_init_grp ig;
struct spdk_iscsi_initiator_name iname; struct spdk_iscsi_initiator_name iname;
struct spdk_iscsi_pg_map *pg_map1, *pg_map2;
char *iqn; char *iqn;
bool result; bool result;
/* target initialization */ /* target initialization */
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node)); memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
tgtnode.maxmap = 2; TAILQ_INIT(&tgtnode.pg_map_head);
pg_map1 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg1);
tgtnode.map[0].ig = &ig; pg_map2 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg2);
tgtnode.map[1].ig = &ig; spdk_iscsi_pg_map_add_ig_map(pg_map1, &ig);
spdk_iscsi_pg_map_add_ig_map(pg_map2, &ig);
/* initiator group initialization */ /* initiator group initialization */
memset(&ig, 0, sizeof(struct spdk_iscsi_init_grp)); memset(&ig, 0, sizeof(struct spdk_iscsi_init_grp));
@ -571,8 +584,12 @@ allow_iscsi_name_multi_maps_case(void)
result = spdk_iscsi_tgt_node_allow_iscsi_name(&tgtnode, iqn); result = spdk_iscsi_tgt_node_allow_iscsi_name(&tgtnode, iqn);
CU_ASSERT(result == false); CU_ASSERT(result == false);
}
spdk_iscsi_pg_map_delete_ig_map(pg_map1, &ig);
spdk_iscsi_pg_map_delete_ig_map(pg_map2, &ig);
spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg1);
spdk_iscsi_tgt_node_delete_pg_map(&tgtnode, &pg2);
}
int int
main(int argc, char **argv) main(int argc, char **argv)