Merge pull request #149 from plieven/for_upstream

init: fix segfaul in iscsi_parse_url
This commit is contained in:
Ronnie Sahlberg
2015-03-26 06:29:35 -07:00
13 changed files with 84 additions and 141 deletions

View File

@@ -174,29 +174,21 @@ void list_luns(struct client_state *clnt, const char *target, const char *portal
printf("Failed to create context\n");
exit(10);
}
if (clnt->username != NULL) {
if (iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password);
if (iscsi_set_targetname(iscsi, target)) {
fprintf(stderr, "Failed to set target name\n");
exit(10);
}
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_connect_sync(iscsi, portal) != 0) {
if (iscsi_full_connect_sync(iscsi, portal, -1) != 0) {
printf("iscsi_connect failed. %s\n", iscsi_get_error(iscsi));
exit(10);
}
if (iscsi_login_sync(iscsi) != 0) {
fprintf(stderr, "login failed :%s\n", iscsi_get_error(iscsi));
exit(10);
}
/* get initial reportluns data, all targets can report 16 bytes but some
* fail if we ask for too much.
*/
@@ -404,14 +396,9 @@ int main(int argc, char *argv[])
iscsi_set_session_type(iscsi, ISCSI_SESSION_DISCOVERY);
if (iscsi_url->user[0] != '\0') {
state.username = iscsi_url->user;
state.password = iscsi_url->passwd;
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
state.username = iscsi_url->user;
state.password = iscsi_url->passwd;
if (iscsi_connect_async(iscsi, iscsi_url->portal, discoveryconnect_cb, &state) != 0) {
fprintf(stderr, "iscsi_connect failed. %s\n", iscsi_get_error(iscsi));
exit(10);

View File

@@ -266,15 +266,8 @@ int main(int argc, char *argv[])
iscsi_get_error(client.src_iscsi));
exit(10);
}
iscsi_set_targetname(client.src_iscsi, iscsi_url->target);
iscsi_set_session_type(client.src_iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(client.src_iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0] != '\0') {
if (iscsi_set_initiator_username_pwd(client.src_iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
if (iscsi_full_connect_sync(client.src_iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.src_iscsi));
iscsi_destroy_url(iscsi_url);
@@ -325,15 +318,8 @@ int main(int argc, char *argv[])
iscsi_get_error(client.dst_iscsi));
exit(10);
}
iscsi_set_targetname(client.dst_iscsi, iscsi_url->target);
iscsi_set_session_type(client.dst_iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(client.dst_iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0] != '\0') {
if (iscsi_set_initiator_username_pwd(client.dst_iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
if (iscsi_full_connect_sync(client.dst_iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.dst_iscsi));
iscsi_destroy_url(iscsi_url);

View File

@@ -92,19 +92,9 @@ int open(const char *path, int flags, mode_t mode)
return -1;
}
iscsi_set_targetname(iscsi, iscsi_url->target);
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0] != '\0') {
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
LD_ISCSI_DPRINTF(0,"Failed to set initiator username and password");
iscsi_destroy_context(iscsi);
errno = ENOMEM;
return -1;
}
}
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
LD_ISCSI_DPRINTF(0,"Login Failed. %s\n", iscsi_get_error(iscsi));
iscsi_destroy_url(iscsi_url);

View File

@@ -91,6 +91,8 @@ struct iscsi_url {
char target[MAX_STRING_SIZE + 1];
char user[MAX_STRING_SIZE + 1];
char passwd[MAX_STRING_SIZE + 1];
char target_user[MAX_STRING_SIZE + 1];
char target_passwd[MAX_STRING_SIZE + 1];
int lun;
struct iscsi_context *iscsi;
};

View File

@@ -130,10 +130,14 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_,
return;
}
if (iscsi_testunitready_task(iscsi, ct->lun,
iscsi_testunitready_cb, ct) == NULL) {
iscsi_set_error(iscsi, "iscsi_testunitready_async failed.");
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
if (ct->lun != -1) {
if (iscsi_testunitready_task(iscsi, ct->lun,
iscsi_testunitready_cb, ct) == NULL) {
iscsi_set_error(iscsi, "iscsi_testunitready_async failed.");
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
}
} else {
ct->cb(iscsi, SCSI_STATUS_GOOD, NULL, ct->private_data);
}
}
@@ -282,12 +286,8 @@ try_again:
iscsi_set_header_digest(iscsi, old_iscsi->want_header_digest);
if (old_iscsi->user[0]) {
iscsi_set_initiator_username_pwd(iscsi, old_iscsi->user, old_iscsi->passwd);
}
if (old_iscsi->target_user[0]) {
iscsi_set_target_username_pwd(iscsi, old_iscsi->target_user, old_iscsi->target_passwd);
}
iscsi_set_initiator_username_pwd(iscsi, old_iscsi->user, old_iscsi->passwd);
iscsi_set_target_username_pwd(iscsi, old_iscsi->target_user, old_iscsi->target_passwd);
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);

View File

@@ -453,6 +453,8 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
char *portal;
char *user = NULL;
char *passwd = NULL;
char *target_user = NULL;
char *target_passwd = NULL;
char *target = NULL;
char *lun;
char *tmp;
@@ -474,12 +476,10 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
strncpy(str,url + 8, MAX_STRING_SIZE);
portal = str;
iscsi_set_target_username_pwd(iscsi,
getenv("LIBISCSI_CHAP_TARGET_USERNAME"),
getenv("LIBISCSI_CHAP_TARGET_PASSWORD"));
user = getenv("LIBISCSI_CHAP_USERNAME");
passwd = getenv("LIBISCSI_CHAP_PASSWORD");
user = getenv("LIBISCSI_CHAP_USERNAME");
passwd = getenv("LIBISCSI_CHAP_PASSWORD");
target_user = getenv("LIBISCSI_CHAP_TARGET_USERNAME");
target_passwd = getenv("LIBISCSI_CHAP_TARGET_PASSWORD");
tmp = strchr(portal, '?');
if (tmp) {
@@ -487,7 +487,6 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
while (tmp && *tmp) {
char *next = strchr(tmp, '&');
char *key, *value;
if (next != NULL) {
*next++ = 0;
}
@@ -497,15 +496,9 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
*value++ = 0;
}
if (!strcmp(key, "target_user")) {
if (value) {
strncpy(iscsi->target_user,
value, MAX_STRING_SIZE);
}
target_user = value;
} else if (!strcmp(key, "target_password")) {
if (value) {
strncpy(iscsi->target_passwd,
value, MAX_STRING_SIZE);
}
target_passwd = value;
}
tmp = next;
}
@@ -587,19 +580,16 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE);
if (!iscsi->target_user[0] || !iscsi->target_passwd[0]) {
iscsi->target_user[0] = 0;
iscsi->target_passwd[0] = 0;
}
if (user != NULL && passwd != NULL) {
if (user && passwd && user[0] && passwd[0]) {
strncpy(iscsi_url->user, user, MAX_STRING_SIZE);
strncpy(iscsi_url->passwd, passwd, MAX_STRING_SIZE);
} else {
/* if we do not have normal CHAP, that means we do not have
* bidirectional either.
*/
iscsi->target_user[0] = 0;
iscsi->target_passwd[0] = 0;
if (target_user && target_passwd && target_user[0] && target_passwd[0]) {
strncpy(iscsi_url->target_user, target_user, MAX_STRING_SIZE);
strncpy(iscsi_url->target_passwd, target_passwd, MAX_STRING_SIZE);
}
}
if (full) {
@@ -609,6 +599,14 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
iscsi_decode_url_string(&iscsi_url->target[0]);
/* NOTE: iscsi is allowed to be NULL. Especially qemu does call us with iscsi == NULL.
* If we receive iscsi != NULL we apply the parsed settings to the context. */
if (iscsi) {
iscsi_set_targetname(iscsi, iscsi_url->target);
iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd);
iscsi_set_target_username_pwd(iscsi, iscsi_url->target_user, iscsi_url->target_passwd);
}
return iscsi_url;
}
@@ -640,6 +638,11 @@ int
iscsi_set_initiator_username_pwd(struct iscsi_context *iscsi,
const char *user, const char *passwd)
{
if (!user || !passwd || !user[0] || !passwd[0]) {
iscsi->user[0] = 0;
iscsi->passwd[0] = 0;
return 0;
}
strncpy(iscsi->user,user,MAX_STRING_SIZE);
strncpy(iscsi->passwd,passwd,MAX_STRING_SIZE);
return 0;
@@ -650,7 +653,7 @@ int
iscsi_set_target_username_pwd(struct iscsi_context *iscsi,
const char *user, const char *passwd)
{
if (!user || !passwd) {
if (!user || !passwd || !user[0] || !passwd[0]) {
iscsi->target_user[0] = 0;
iscsi->target_passwd[0] = 0;
return 0;

View File

@@ -83,6 +83,7 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
}
iscsi->nops_in_flight++;
ISCSI_LOG(iscsi, 6, "NOP Out Send (nops_in_flight: %d)", iscsi->nops_in_flight);
return 0;
}
@@ -138,6 +139,8 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
iscsi->nops_in_flight = 0;
ISCSI_LOG(iscsi, 6, "NOP Out Reply received");
if (pdu->callback == NULL) {
return 0;
}

View File

@@ -455,17 +455,17 @@ iscsi_iovector_readv_writev(struct iscsi_context *iscsi, struct scsi_iovector *i
int niov=1; /* number of iovectors to pass */
uint32_t len2 = pos + count; /* adjust length of iov2 */
/* forward until iov2 points to the last iovec we pass later. it might
happen that we have a lot of iovectors but are limited by count */
while (len2 > iov2->iov_len) {
if (iovector->niov <= iovector->consumed+niov-1) {
niov++;
if (iovector->niov < iovector->consumed + niov) {
errno = EINVAL;
return -1;
}
niov++;
len2 -= iov2->iov_len;
iov2 = &iovector->iov[iovector->consumed+niov-1];
iov2 = &iovector->iov[iovector->consumed + niov - 1];
}
/* we might limit the length of the last iovec we pass to readv/writev
@@ -627,15 +627,24 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
if (iscsi->is_corked) {
/* connection is corked we are not allowed to send
* additional PDUs */
ISCSI_LOG(iscsi, 6, "iscsi_write_to_socket: socket is corked");
return 0;
}
if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->maxcmdsn) > 0
&& !(iscsi->outqueue->outdata.data[0] & ISCSI_PDU_IMMEDIATE)) {
/* stop sending for non-immediate PDUs. maxcmdsn is reached */
ISCSI_LOG(iscsi, 6,
"iscsi_write_to_socket: maxcmdsn reached (outqueue[0]->cmdsnd %08x > maxcmdsn %08x)",
iscsi->outqueue->cmdsn, iscsi->maxcmdsn);
return 0;
}
/* pop first element of the outqueue */
if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->expcmdsn) < 0) {
iscsi_set_error(iscsi, "iscsi_write_to_scoket: outqueue[0]->cmdsn < expcmdsn (%08x < %08x)",
iscsi->outqueue->cmdsn, iscsi->expcmdsn);
return -1;
}
iscsi->outqueue_current = iscsi->outqueue;
ISCSI_LIST_REMOVE(&iscsi->outqueue, iscsi->outqueue_current);
if (!(iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT)) {

View File

@@ -322,17 +322,9 @@ int main(int argc, char *argv[])
exit(10);
}
iscsi_set_targetname(iscsi, iscsi_url->target);
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0]) {
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi));
iscsi_destroy_url(iscsi_url);

View File

@@ -172,29 +172,20 @@ void list_luns(struct client_state *clnt, const char *target, const char *portal
printf("Failed to create context\n");
exit(10);
}
if (clnt->username != NULL) {
if (iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password);
if (iscsi_set_targetname(iscsi, target)) {
fprintf(stderr, "Failed to set target name\n");
exit(10);
}
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_connect_sync(iscsi, portal) != 0) {
if (iscsi_full_connect_sync(iscsi, portal, -1) != 0) {
printf("iscsi_connect failed. %s\n", iscsi_get_error(iscsi));
exit(10);
}
if (iscsi_login_sync(iscsi) != 0) {
fprintf(stderr, "login failed :%s\n", iscsi_get_error(iscsi));
exit(10);
}
/* get initial reportluns data, all targets can report 16 bytes but some
* fail if we ask for too much.
*/
@@ -430,14 +421,9 @@ int main(int argc, char *argv[])
iscsi_set_session_type(iscsi, ISCSI_SESSION_DISCOVERY);
if (iscsi_url->user[0]) {
state.username = iscsi_url->user;
state.password = iscsi_url->passwd;
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
state.username = iscsi_url->user;
state.password = iscsi_url->passwd;
if (iscsi_connect_async(iscsi, iscsi_url->portal, discoveryconnect_cb, &state) != 0) {
fprintf(stderr, "iscsi_connect failed. %s\n", iscsi_get_error(iscsi));
exit(10);

View File

@@ -45,6 +45,8 @@ struct client {
int random;
struct iscsi_context *iscsi;
struct scsi_iovec perf_iov;
int lun;
int blocksize;
uint64_t num_blocks;
@@ -133,6 +135,7 @@ void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *p
fprintf(stderr, "failed to send read16 command\n");
client->err_cnt++;
}
scsi_task_set_iov_in(task2, &client->perf_iov, 1);
if (status == SCSI_STATUS_BUSY) {
client->busy_cnt++;
}
@@ -184,12 +187,12 @@ void fill_read_queue(struct client *client)
num_blocks * client->blocksize,
client->blocksize, 0, 0, 0, 0, 0,
cb, client);
if (task == NULL) {
fprintf(stderr, "failed to send read16 command\n");
iscsi_destroy_context(client->iscsi);
exit(10);
}
scsi_task_set_iov_in(task, &client->perf_iov, 1);
client->pos += num_blocks;
}
}
@@ -270,27 +273,17 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failed to create context\n");
exit(10);
}
iscsi_url = iscsi_parse_full_url(client.iscsi, url);
iscsi_url = iscsi_parse_full_url(client.iscsi, url);
if (iscsi_url == NULL) {
fprintf(stderr, "Failed to parse URL: %s\n",
iscsi_get_error(client.iscsi));
exit(10);
}
iscsi_set_targetname(client.iscsi, iscsi_url->target);
iscsi_set_session_type(client.iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(client.iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0] != '\0') {
if (iscsi_set_initiator_username_pwd(client.iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
iscsi_destroy_url(iscsi_url);
iscsi_destroy_context(client.iscsi);
exit(10);
}
}
if (iscsi_full_connect_sync(client.iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.iscsi));
iscsi_destroy_url(iscsi_url);
@@ -321,6 +314,13 @@ int main(int argc, char *argv[])
scsi_free_scsi_task(task);
client.perf_iov.iov_base = malloc(blocks_per_io * client.blocksize);
if (!client.perf_iov.iov_base) {
fprintf(stderr, "Out of Memory\n");
exit(10);
}
client.perf_iov.iov_len = blocks_per_io * client.blocksize;
printf("capacity is %" PRIu64 " blocks or %" PRIu64 " byte (%" PRIu64 " MB)\n", client.num_blocks, client.num_blocks * client.blocksize,
(client.num_blocks * client.blocksize) >> 20);
@@ -370,6 +370,8 @@ int main(int argc, char *argv[])
}
iscsi_destroy_context(client.iscsi);
free(client.perf_iov.iov_base);
return client.err_cnt ? 1 : 0;
}

View File

@@ -145,17 +145,9 @@ int main(int argc, char *argv[])
exit(10);
}
iscsi_set_targetname(iscsi, iscsi_url->target);
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0]) {
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
exit(10);
}
}
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi));
iscsi_destroy_url(iscsi_url);

View File

@@ -158,18 +158,9 @@ int main(int argc, char *argv[])
goto finished;
}
iscsi_set_targetname(iscsi, iscsi_url->target);
iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
if (iscsi_url->user[0]) {
if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) {
fprintf(stderr, "Failed to set initiator username and password\n");
ret = 10;
goto finished;
}
}
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi));
ret = 10;