diff --git a/test-tool/iscsi-multipath.c b/test-tool/iscsi-multipath.c index d691ed3..3058ba8 100644 --- a/test-tool/iscsi-multipath.c +++ b/test-tool/iscsi-multipath.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef HAVE_SG_IO #include @@ -385,3 +386,59 @@ mpath_count_iscsi(int num_sds, return found; } + +/* + * use an existing multi-path connection, or clone iscsi sd1. + */ +int +mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2) +{ + struct scsi_device *sd2; + + if (mp_num_sds > 1) { + logging(LOG_VERBOSE, "using multipath dev for second session"); + *_sd2 = mp_sds[1]; + return 0; + } + + if (sd1->iscsi_ctx == NULL) { + logging(LOG_NORMAL, "can't clone non-iscsi device"); + return -EINVAL; + } + + logging(LOG_VERBOSE, "cloning sd1 for second session"); + sd2 = malloc(sizeof(*sd2)); + if (sd2 == NULL) { + return -ENOMEM; + } + + memset(sd2, 0, sizeof(*sd2)); + sd2->iscsi_url = sd1->iscsi_url; + sd2->iscsi_lun = sd1->iscsi_lun; + sd2->iscsi_ctx = iscsi_context_login(initiatorname2, sd2->iscsi_url, + &sd2->iscsi_lun); + if (sd2->iscsi_ctx == NULL) { + logging(LOG_VERBOSE, "Failed to login to target"); + free(sd2); + return -ENOMEM; + } + *_sd2 = sd2; + + return 0; +} + +void +mpath_sd2_put(struct scsi_device *sd2) +{ + if (mp_num_sds > 1) { + if (sd2 != mp_sds[1]) { + logging(LOG_NORMAL, "Invalid sd2!"); + } + return; + } + + /* sd2 was allocated by mp_get - cleanup */ + iscsi_logout_sync(sd2->iscsi_ctx); + iscsi_destroy_context(sd2->iscsi_ctx); + free(sd2); +} diff --git a/test-tool/iscsi-multipath.h b/test-tool/iscsi-multipath.h index 2fcd6ea..7fd6187 100644 --- a/test-tool/iscsi-multipath.h +++ b/test-tool/iscsi-multipath.h @@ -30,6 +30,10 @@ mpath_check_matching_ids(int num_sds, int mpath_count_iscsi(int num_sds, struct scsi_device **sds); +int +mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2); +void +mpath_sd2_put(struct scsi_device *sd2); #define MPATH_SKIP_IF_UNAVAILABLE(_sds, _num_sds) \ do { \