Commit 3b3c6002 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

iscsi: Add LUN to an existing target (not runtime)



Removing an LUN from an existing iSCSI target is possible by
removing the corresponding BDEV. However adding an LUN to an
existing iSCSI target is not possible yet.

Add a new function spdk_iscsi_tgt_node_add_lun() and related
functions first toward supporting this function.

JSON-RPC for this operation will be submitted an another patch.

Informing the newly added LUN to the initiator is not included
in this patch. Hence this operation is possible only for any
inactive target.

Change-Id: I3a28f4d75a17126e49c9d12ce64c3ad68f231840
Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/385180


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 5c13f5ae
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -192,7 +192,9 @@ struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name,
		void *hotremove_ctx);

void spdk_scsi_dev_delete_lun(struct spdk_scsi_dev *dev, struct spdk_scsi_lun *lun);

int spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id,
			  void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
			  void *hotremove_ctx);

struct spdk_scsi_port *spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name);
void spdk_scsi_port_free(struct spdk_scsi_port **pport);
+33 −0
Original line number Diff line number Diff line
@@ -1294,3 +1294,36 @@ void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group,
	}
	pthread_mutex_unlock(&g_spdk_iscsi.mutex);
}

int
spdk_iscsi_tgt_node_add_lun(struct spdk_iscsi_tgt_node *target,
			    const char *bdev_name, int lun_id)
{
	struct spdk_scsi_dev *dev;
	int rc;

	if (target->num_active_conns > 0) {
		SPDK_ERRLOG("Target has active connections (count=%d)\n",
			    target->num_active_conns);
		return -1;
	}

	if (lun_id < -1 || lun_id >= SPDK_SCSI_DEV_MAX_LUN) {
		SPDK_ERRLOG("Specified LUN ID (%d) is invalid\n", lun_id);
		return -1;
	}

	dev = target->dev;
	if (dev == NULL) {
		SPDK_ERRLOG("SCSI device is not found\n");
		return -1;
	}

	rc = spdk_scsi_dev_add_lun(dev, bdev_name, lun_id, NULL, NULL);
	if (rc != 0) {
		SPDK_ERRLOG("spdk_scsi_dev_add_lun failed\n");
		return -1;
	}

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -132,4 +132,6 @@ int spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn,
				     struct spdk_iscsi_tgt_node *target);
void spdk_iscsi_tgt_node_delete_map(struct spdk_iscsi_portal_grp *portal_group,
				    struct spdk_iscsi_init_grp *initiator_group);
int spdk_iscsi_tgt_node_add_lun(struct spdk_iscsi_tgt_node *target,
				const char *bdev_name, int lun_id);
#endif /* SPDK_ISCSI_TGT_NODE_H_ */
+51 −25
Original line number Diff line number Diff line
@@ -102,13 +102,53 @@ spdk_scsi_dev_destruct(struct spdk_scsi_dev *dev)
	}
}

static void
spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev,
		      struct spdk_scsi_lun *lun, int id)
static int
spdk_scsi_dev_find_lowest_free_lun_id(struct spdk_scsi_dev *dev)
{
	lun->id = id;
	int i;

	for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) {
		if (dev->lun[i] == NULL) {
			return i;
		}
	}

	return -1;
}

int
spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id,
		      void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
		      void *hotremove_ctx)
{
	struct spdk_bdev *bdev;
	struct spdk_scsi_lun *lun;

	bdev = spdk_bdev_get_by_name(bdev_name);
	if (bdev == NULL) {
		SPDK_ERRLOG("device %s: cannot find bdev '%s' (target %d)\n",
			    dev->name, bdev_name, lun_id);
		return -1;
	}

	/* Search the lowest free LUN ID if LUN ID is default */
	if (lun_id == -1) {
		lun_id = spdk_scsi_dev_find_lowest_free_lun_id(dev);
		if (lun_id == -1) {
			SPDK_ERRLOG("Free LUN ID is not found\n");
			return -1;
		}
	}

	lun = spdk_scsi_lun_construct(bdev, hotremove_cb, hotremove_ctx);
	if (lun == NULL) {
		return -1;
	}

	lun->id = lun_id;
	lun->dev = dev;
	dev->lun[id] = lun;
	dev->lun[lun_id] = lun;
	return 0;
}

void
@@ -145,10 +185,8 @@ spdk_scsi_dev_construct(const char *name, const char *bdev_name_list[],
			void *hotremove_ctx)
{
	struct spdk_scsi_dev *dev;
	struct spdk_bdev *bdev;
	struct spdk_scsi_lun *lun = NULL;
	bool found_lun_0;
	int i;
	int i, rc;

	if (num_luns == 0) {
		SPDK_ERRLOG("device %s: no LUNs specified\n", name);
@@ -187,27 +225,15 @@ spdk_scsi_dev_construct(const char *name, const char *bdev_name_list[],
	dev->protocol_id = protocol_id;

	for (i = 0; i < num_luns; i++) {
		bdev = spdk_bdev_get_by_name(bdev_name_list[i]);
		if (bdev == NULL) {
			SPDK_ERRLOG("device %s: cannot find bdev '%s' (target %d)\n",
				    name, bdev_name_list[i], i);
			goto error;
		}

		lun = spdk_scsi_lun_construct(bdev, hotremove_cb, hotremove_ctx);
		if (lun == NULL) {
			goto error;
		rc = spdk_scsi_dev_add_lun(dev, bdev_name_list[i], lun_id_list[i],
					   hotremove_cb, hotremove_ctx);
		if (rc < 0) {
			spdk_scsi_dev_destruct(dev);
			return NULL;
		}

		spdk_scsi_dev_add_lun(dev, lun, lun_id_list[i]);
	}

	return dev;

error:
	spdk_scsi_dev_destruct(dev);

	return NULL;
}

void
+65 −1
Original line number Diff line number Diff line
@@ -95,6 +95,69 @@ spdk_scsi_dev_get_lun(struct spdk_scsi_dev *dev, int lun_id)
	return dev->lun[lun_id];
}

int
spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id,
		      void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
		      void *hotremove_ctx)
{
	if (bdev_name == NULL) {
		return -1;
	} else {
		return 0;
	}
}

static void
add_lun_test_cases(void)
{
	struct spdk_iscsi_tgt_node tgtnode;
	int lun_id = 0;
	char *bdev_name = NULL;
	struct spdk_scsi_dev scsi_dev;
	int rc;

	memset(&tgtnode, 0, sizeof(struct spdk_iscsi_tgt_node));
	memset(&scsi_dev, 0, sizeof(struct spdk_scsi_dev));

	/* case 1 */
	tgtnode.num_active_conns = 1;

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc != 0);

	/* case 2 */
	tgtnode.num_active_conns = 0;
	lun_id = -2;

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc != 0);

	/* case 3 */
	lun_id = SPDK_SCSI_DEV_MAX_LUN;

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc != 0);

	/* case 4 */
	lun_id = -1;
	tgtnode.dev = NULL;

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc != 0);

	/* case 5 */
	tgtnode.dev = &scsi_dev;

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc != 0);

	/* case 6 */
	bdev_name = "LUN0";

	rc = spdk_iscsi_tgt_node_add_lun(&tgtnode, bdev_name, lun_id);
	CU_ASSERT(rc == 0);
}

static void
config_file_fail_cases(void)
{
@@ -755,7 +818,8 @@ main(int argc, char **argv)
	}

	if (
		CU_add_test(suite, "config file fail cases", config_file_fail_cases) == NULL
		CU_add_test(suite, "add lun test cases", add_lun_test_cases) == NULL
		|| CU_add_test(suite, "config file fail cases", config_file_fail_cases) == NULL
		|| CU_add_test(suite, "allow any allowed case", allow_any_allowed) == NULL
		|| CU_add_test(suite, "allow ipv6 allowed case", allow_ipv6_allowed) == NULL
		|| CU_add_test(suite, "allow ipv6 denied case", allow_ipv6_denied) == NULL
Loading