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:
parent
d07df58419
commit
c5e5047d99
@ -255,6 +255,8 @@ spdk_rpc_get_target_nodes(struct spdk_jsonrpc_request *request,
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
struct spdk_iscsi_tgt_node *tgtnode;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
struct spdk_iscsi_ig_map *ig_map;
|
||||
int i;
|
||||
|
||||
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_array_begin(w);
|
||||
for (i = 0; i < tgtnode->maxmap; i++) {
|
||||
spdk_json_write_object_begin(w);
|
||||
spdk_json_write_name(w, "pg_tag");
|
||||
spdk_json_write_int32(w, tgtnode->map[i].pg->tag);
|
||||
spdk_json_write_name(w, "ig_tag");
|
||||
spdk_json_write_int32(w, tgtnode->map[i].ig->tag);
|
||||
spdk_json_write_object_end(w);
|
||||
TAILQ_FOREACH(pg_map, &tgtnode->pg_map_head, tailq) {
|
||||
TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
|
||||
spdk_json_write_object_begin(w);
|
||||
spdk_json_write_name(w, "pg_tag");
|
||||
spdk_json_write_int32(w, pg_map->pg->tag);
|
||||
spdk_json_write_name(w, "ig_tag");
|
||||
spdk_json_write_int32(w, ig_map->ig->tag);
|
||||
spdk_json_write_object_end(w);
|
||||
}
|
||||
}
|
||||
spdk_json_write_array_end(w);
|
||||
|
||||
|
@ -228,9 +228,11 @@ static const char *target_nodes_section = \
|
||||
static void
|
||||
spdk_iscsi_config_dump_target_nodes(FILE *fp)
|
||||
{
|
||||
int l = 0, m = 0;
|
||||
int l = 0;
|
||||
struct spdk_scsi_dev *dev = 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 */
|
||||
fprintf(fp, "%s", target_nodes_section);
|
||||
@ -247,13 +249,12 @@ spdk_iscsi_config_dump_target_nodes(FILE *fp)
|
||||
idx = target->num;
|
||||
fprintf(fp, TARGET_NODE_TMPL, idx, idx, target->name, spdk_scsi_dev_get_name(dev));
|
||||
|
||||
for (m = 0; m < target->maxmap; m++) {
|
||||
if (NULL == target->map[m].pg) continue;
|
||||
if (NULL == target->map[m].ig) continue;
|
||||
|
||||
fprintf(fp, TARGET_NODE_PGIG_MAPPING_TMPL,
|
||||
target->map[m].pg->tag,
|
||||
target->map[m].ig->tag);
|
||||
TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
|
||||
TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
|
||||
fprintf(fp, TARGET_NODE_PGIG_MAPPING_TMPL,
|
||||
pg_map->pg->tag,
|
||||
ig_map->ig->tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (target->auth_chap_disabled)
|
||||
|
@ -214,13 +214,17 @@ spdk_iscsi_init_grp_allow_iscsi_name(struct spdk_iscsi_init_grp *igp,
|
||||
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
|
||||
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_portal_grp *pg;
|
||||
struct spdk_iscsi_init_grp *igp;
|
||||
int i;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
struct spdk_iscsi_ig_map *ig_map;
|
||||
int rc;
|
||||
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",
|
||||
pg->tag, iqn, addr);
|
||||
for (i = 0; i < target->maxmap; i++) {
|
||||
/* skip excluding self portal group tag */
|
||||
if (pg != target->map[i].pg)
|
||||
continue;
|
||||
igp = target->map[i].ig;
|
||||
rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &allowed);
|
||||
pg_map = spdk_iscsi_tgt_node_find_pg_map(target, pg);
|
||||
if (pg_map == NULL) {
|
||||
return false;
|
||||
}
|
||||
TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
|
||||
rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &allowed);
|
||||
if (rc == 0) {
|
||||
if (allowed == false) {
|
||||
goto denied;
|
||||
} else {
|
||||
if (spdk_iscsi_init_grp_allow_addr(igp, addr)) {
|
||||
if (spdk_iscsi_init_grp_allow_addr(ig_map->ig, addr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -259,28 +263,21 @@ denied:
|
||||
static bool
|
||||
spdk_iscsi_tgt_node_allow_iscsi_name(struct spdk_iscsi_tgt_node *target, const char *iqn)
|
||||
{
|
||||
struct spdk_iscsi_init_grp *igp;
|
||||
int i, j;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
struct spdk_iscsi_ig_map *ig_map;
|
||||
int rc;
|
||||
bool result = false;
|
||||
|
||||
if (target == NULL || iqn == NULL)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < target->maxmap; i++) {
|
||||
igp = target->map[i].ig;
|
||||
/* skip same ig_tag */
|
||||
for (j = 0; j < i; j++) {
|
||||
if (target->map[j].ig->tag == igp->tag) {
|
||||
goto skip_ig_tag;
|
||||
TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
|
||||
TAILQ_FOREACH(ig_map, &pg_map->ig_map_head, tailq) {
|
||||
rc = spdk_iscsi_init_grp_allow_iscsi_name(ig_map->ig, iqn, &result);
|
||||
if (rc == 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
rc = spdk_iscsi_init_grp_allow_iscsi_name(igp, iqn, &result);
|
||||
if (rc == 0) {
|
||||
return result;
|
||||
}
|
||||
skip_ig_tag:
|
||||
;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -293,14 +290,13 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
|
||||
{
|
||||
char buf[MAX_TMPBUF];
|
||||
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;
|
||||
char *host;
|
||||
int total;
|
||||
int len;
|
||||
int rc;
|
||||
int pg_tag;
|
||||
int i, j;
|
||||
|
||||
if (conn == NULL)
|
||||
return 0;
|
||||
@ -336,53 +332,41 @@ spdk_iscsi_send_tgts(struct spdk_iscsi_conn *conn, const char *iiqn,
|
||||
"TargetName=%s", target->name);
|
||||
total += len + 1;
|
||||
|
||||
for (i = 0; i < target->maxmap; i++) {
|
||||
pg_tag = target->map[i].pg->tag;
|
||||
/* skip same pg_tag */
|
||||
for (j = 0; j < i; j++) {
|
||||
if (target->map[j].pg->tag == pg_tag) {
|
||||
goto skip_pg_tag;
|
||||
/* write to data */
|
||||
TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
|
||||
pg = pg_map->pg;
|
||||
TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
|
||||
if (alloc_len - total < 1) {
|
||||
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
|
||||
SPDK_ERRLOG("data space small %d\n", alloc_len);
|
||||
return total;
|
||||
}
|
||||
}
|
||||
/* write to data */
|
||||
TAILQ_FOREACH(pg, &g_spdk_iscsi.pg_head, tailq) {
|
||||
if (pg->tag != pg_tag)
|
||||
continue;
|
||||
TAILQ_FOREACH(p, &pg->head, per_pg_tailq) {
|
||||
if (alloc_len - total < 1) {
|
||||
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
|
||||
SPDK_ERRLOG("data space small %d\n", alloc_len);
|
||||
return total;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
@ -446,6 +430,241 @@ spdk_iscsi_tgt_node_unregister(struct spdk_iscsi_tgt_node *target)
|
||||
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
|
||||
spdk_check_iscsi_name(const char *name)
|
||||
{
|
||||
@ -488,64 +707,6 @@ spdk_check_iscsi_name(const char *name)
|
||||
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_construct(int target_index,
|
||||
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];
|
||||
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_pg_map *pg_map;
|
||||
int num_unique_portal_groups;
|
||||
int i, j, rc;
|
||||
int i, rc;
|
||||
|
||||
if (auth_chap_disabled && auth_chap_required) {
|
||||
SPDK_ERRLOG("auth_chap_disabled and auth_chap_required are mutually exclusive\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((num_maps > MAX_TARGET_MAP) || (num_maps == 0)) {
|
||||
SPDK_ERRLOG("num_maps = %d out of range\n", num_maps);
|
||||
if (num_maps == 0) {
|
||||
SPDK_ERRLOG("num_maps = 0\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -635,37 +795,31 @@ spdk_iscsi_tgt_node_construct(int target_index,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num_unique_portal_groups = 0;
|
||||
TAILQ_INIT(&target->pg_map_head);
|
||||
for (i = 0; i < num_maps; i++) {
|
||||
map = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i],
|
||||
ig_tag_list[i]);
|
||||
rc = spdk_iscsi_tgt_node_add_map(target, pg_tag_list[i],
|
||||
ig_tag_list[i]);
|
||||
|
||||
if (map == NULL) {
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("could not add map to target\n");
|
||||
spdk_iscsi_tgt_node_destruct(target);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < num_unique_portal_groups; j++) {
|
||||
if (unique_portal_groups[j] == map->pg) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
num_unique_portal_groups = 0;
|
||||
TAILQ_FOREACH(pg_map, &target->pg_map_head, tailq) {
|
||||
|
||||
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_iscsi_tgt_node_destruct(target);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (j == num_unique_portal_groups) {
|
||||
pg = map->pg;
|
||||
snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x",
|
||||
name, pg->tag);
|
||||
spdk_scsi_dev_add_port(target->dev, pg->tag, port_name);
|
||||
unique_portal_groups[j] = pg;
|
||||
num_unique_portal_groups++;
|
||||
}
|
||||
pg = pg_map->pg;
|
||||
snprintf(port_name, sizeof(port_name), "%s,t,0x%4.4x",
|
||||
name, pg->tag);
|
||||
spdk_scsi_dev_add_port(target->dev, pg->tag, port_name);
|
||||
}
|
||||
|
||||
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_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) {
|
||||
loop:
|
||||
flag = 0;
|
||||
for (i = 0; i < target->maxmap; i++) {
|
||||
if (portal_group) {
|
||||
if (target->map[i].pg->tag == portal_group->tag) {
|
||||
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;
|
||||
}
|
||||
if (portal_group) {
|
||||
spdk_iscsi_tgt_node_delete_pg_map(target, portal_group);
|
||||
}
|
||||
if (initiator_group) {
|
||||
spdk_iscsi_tgt_node_delete_ig_maps(target, initiator_group);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
|
||||
}
|
||||
|
@ -40,14 +40,24 @@
|
||||
#include "spdk/scsi.h"
|
||||
|
||||
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 MAX_TARGET_MAP 256
|
||||
#define SPDK_TN_TAG_MAX 0x0000ffff
|
||||
|
||||
struct spdk_iscsi_tgt_node_map {
|
||||
struct spdk_iscsi_portal_grp *pg;
|
||||
struct spdk_iscsi_init_grp *ig;
|
||||
struct spdk_iscsi_ig_map {
|
||||
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 {
|
||||
@ -73,8 +83,8 @@ struct spdk_iscsi_tgt_node {
|
||||
uint32_t num_active_conns;
|
||||
int lcore;
|
||||
|
||||
int maxmap;
|
||||
struct spdk_iscsi_tgt_node_map map[MAX_TARGET_MAP];
|
||||
int num_pg_maps;
|
||||
TAILQ_HEAD(, spdk_iscsi_pg_map) pg_map_head;
|
||||
TAILQ_ENTRY(spdk_iscsi_tgt_node) tailq;
|
||||
};
|
||||
|
||||
|
@ -186,6 +186,7 @@ node_access_allowed(void)
|
||||
struct spdk_iscsi_portal portal;
|
||||
struct spdk_iscsi_initiator_name iname;
|
||||
struct spdk_iscsi_initiator_netmask imask;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
char *iqn, *addr;
|
||||
bool result;
|
||||
|
||||
@ -209,10 +210,10 @@ node_access_allowed(void)
|
||||
|
||||
/* target initialization */
|
||||
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
|
||||
tgtnode.maxmap = 1;
|
||||
tgtnode.name = "iqn.2017-10.spdk.io:0001";
|
||||
tgtnode.map[0].pg = &pg;
|
||||
tgtnode.map[0].ig = &ig;
|
||||
TAILQ_INIT(&tgtnode.pg_map_head);
|
||||
pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);
|
||||
|
||||
/* portal initialization */
|
||||
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);
|
||||
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
|
||||
@ -240,6 +244,7 @@ node_access_denied_by_empty_netmask(void)
|
||||
struct spdk_iscsi_conn conn;
|
||||
struct spdk_iscsi_portal portal;
|
||||
struct spdk_iscsi_initiator_name iname;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
char *iqn, *addr;
|
||||
bool result;
|
||||
|
||||
@ -261,10 +266,10 @@ node_access_denied_by_empty_netmask(void)
|
||||
|
||||
/* target initialization */
|
||||
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
|
||||
tgtnode.maxmap = 1;
|
||||
tgtnode.name = "iqn.2017-10.spdk.io:0001";
|
||||
tgtnode.map[0].pg = &pg;
|
||||
tgtnode.map[0].ig = &ig;
|
||||
TAILQ_INIT(&tgtnode.pg_map_head);
|
||||
pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig);
|
||||
|
||||
/* portal initialization */
|
||||
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);
|
||||
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"
|
||||
@ -300,18 +307,17 @@ node_access_multi_initiator_groups_cases(void)
|
||||
struct spdk_iscsi_init_grp ig1, ig2;
|
||||
struct spdk_iscsi_initiator_name iname1, iname2;
|
||||
struct spdk_iscsi_initiator_netmask imask1, imask2;
|
||||
struct spdk_iscsi_pg_map *pg_map;
|
||||
char *iqn, *addr;
|
||||
bool result;
|
||||
|
||||
/* target initialization */
|
||||
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
|
||||
tgtnode.maxmap = 2;
|
||||
tgtnode.name = IQN1;
|
||||
|
||||
tgtnode.map[0].pg = &pg;
|
||||
tgtnode.map[0].ig = &ig1;
|
||||
tgtnode.map[1].pg = &pg;
|
||||
tgtnode.map[1].ig = &ig2;
|
||||
TAILQ_INIT(&tgtnode.pg_map_head);
|
||||
pg_map = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig1);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map, &ig2);
|
||||
|
||||
/* portal group initialization */
|
||||
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);
|
||||
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
|
||||
allow_iscsi_name_multi_maps_case(void)
|
||||
{
|
||||
struct spdk_iscsi_tgt_node tgtnode;
|
||||
struct spdk_iscsi_portal_grp pg1, pg2;
|
||||
struct spdk_iscsi_init_grp ig;
|
||||
struct spdk_iscsi_initiator_name iname;
|
||||
struct spdk_iscsi_pg_map *pg_map1, *pg_map2;
|
||||
char *iqn;
|
||||
bool result;
|
||||
|
||||
/* target initialization */
|
||||
memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
|
||||
tgtnode.maxmap = 2;
|
||||
|
||||
tgtnode.map[0].ig = &ig;
|
||||
tgtnode.map[1].ig = &ig;
|
||||
TAILQ_INIT(&tgtnode.pg_map_head);
|
||||
pg_map1 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg1);
|
||||
pg_map2 = spdk_iscsi_tgt_node_add_pg_map(&tgtnode, &pg2);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map1, &ig);
|
||||
spdk_iscsi_pg_map_add_ig_map(pg_map2, &ig);
|
||||
|
||||
/* initiator group initialization */
|
||||
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);
|
||||
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
|
||||
main(int argc, char **argv)
|
||||
|
Loading…
x
Reference in New Issue
Block a user