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: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/385180 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
5c13f5ae6d
commit
3b3c6002c9
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
|
||||
lun = spdk_scsi_lun_construct(bdev, hotremove_cb, hotremove_ctx);
|
||||
if (lun == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
spdk_scsi_dev_add_lun(dev, lun, lun_id_list[i]);
|
||||
}
|
||||
|
||||
return dev;
|
||||
|
||||
error:
|
||||
spdk_scsi_dev_destruct(dev);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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
|
||||
|
@ -531,6 +531,70 @@ dev_find_port_by_id_success(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dev_add_lun_bdev_not_found(void)
|
||||
{
|
||||
int rc;
|
||||
struct spdk_scsi_dev dev = {0};
|
||||
|
||||
rc = spdk_scsi_dev_add_lun(&dev, "malloc2", -1, NULL, NULL);
|
||||
|
||||
CU_ASSERT_NOT_EQUAL(rc, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_add_lun_no_free_lun_id(void)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
struct spdk_scsi_dev dev = {0};
|
||||
struct spdk_scsi_lun lun;
|
||||
|
||||
for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) {
|
||||
dev.lun[i] = &lun;
|
||||
}
|
||||
|
||||
rc = spdk_scsi_dev_add_lun(&dev, "malloc0", -1, NULL, NULL);
|
||||
|
||||
CU_ASSERT_NOT_EQUAL(rc, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_add_lun_success1(void)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
struct spdk_scsi_dev dev;
|
||||
|
||||
for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) {
|
||||
dev.lun[i] = NULL;
|
||||
}
|
||||
|
||||
rc = spdk_scsi_dev_add_lun(&dev, "malloc0", -1, NULL, NULL);
|
||||
|
||||
CU_ASSERT_EQUAL(rc, 0);
|
||||
|
||||
spdk_scsi_dev_destruct(&dev);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_add_lun_success2(void)
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
struct spdk_scsi_dev dev;
|
||||
|
||||
for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; i++) {
|
||||
dev.lun[i] = NULL;
|
||||
}
|
||||
|
||||
rc = spdk_scsi_dev_add_lun(&dev, "malloc0", 0, NULL, NULL);
|
||||
|
||||
CU_ASSERT_EQUAL(rc, 0);
|
||||
|
||||
spdk_scsi_dev_destruct(&dev);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -585,6 +649,14 @@ main(int argc, char **argv)
|
||||
dev_find_port_by_id_id_not_found_failure) == NULL
|
||||
|| CU_add_test(suite, "dev find port by id - success",
|
||||
dev_find_port_by_id_success) == NULL
|
||||
|| CU_add_test(suite, "dev add lun - bdev not found",
|
||||
dev_add_lun_bdev_not_found) == NULL
|
||||
|| CU_add_test(suite, "dev add lun - no free lun id",
|
||||
dev_add_lun_no_free_lun_id) == NULL
|
||||
|| CU_add_test(suite, "dev add lun - success 1",
|
||||
dev_add_lun_success1) == NULL
|
||||
|| CU_add_test(suite, "dev add lun - success 2",
|
||||
dev_add_lun_success2) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
x
Reference in New Issue
Block a user