From 389f6a8ba5df38405a18271987758a6c279ad65e Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Wed, 31 Oct 2012 16:46:33 +0100 Subject: [PATCH 01/27] SCSI half mallocs in scsi_malloc --- lib/scsi-lowlevel.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index 3787072..3f8020e 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -47,7 +47,6 @@ scsi_free_scsi_task(struct scsi_task *task) while ((mem = task->mem)) { SLIST_REMOVE(&task->mem, mem); - free(mem->ptr); free(mem); } @@ -60,17 +59,12 @@ scsi_malloc(struct scsi_task *task, size_t size) { struct scsi_allocated_memory *mem; - mem = malloc(sizeof(struct scsi_allocated_memory)); + mem = malloc(sizeof(struct scsi_allocated_memory) + size); if (mem == NULL) { return NULL; } - memset(mem, 0, sizeof(struct scsi_allocated_memory)); - mem->ptr = malloc(size); - if (mem->ptr == NULL) { - free(mem); - return NULL; - } - memset(mem->ptr, 0, size); + memset(mem, 0, sizeof(struct scsi_allocated_memory) + size); + mem->ptr = (void *) ((uintptr_t)mem + sizeof(struct scsi_allocated_memory)); SLIST_ADD(&task->mem, mem); return mem->ptr; } From d327ab09c62f36e65c7e1c555a65d202a428967c Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 01:05:57 +0100 Subject: [PATCH 02/27] MEMORY add wrappers around all mallocs and frees and trace them This patch adds a wrapper around all memory allocations and frees. The idea is to get warned immediately if the application leaks memory. Additionally the wrapper functions make it easy to add different memory allocators or memory pools in the future. --- include/iscsi-private.h | 12 ++- include/iscsi.h | 1 + include/scsi-lowlevel.h | 76 +++++++-------- lib/connect.c | 22 +++-- lib/discovery.c | 29 +++--- lib/init.c | 53 +++++++++-- lib/login.c | 64 ++++++------- lib/pdu.c | 21 ++--- lib/scsi-command.c | 81 ++++++++-------- lib/scsi-lowlevel.c | 201 +++++++++++++++++----------------------- lib/socket.c | 27 +++--- 11 files changed, 300 insertions(+), 287 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 5c9b15a..3280f1d 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -48,8 +48,8 @@ struct iscsi_in_pdu { long long data_pos; unsigned char *data; }; -void iscsi_free_iscsi_in_pdu(struct iscsi_in_pdu *in); -void iscsi_free_iscsi_inqueue(struct iscsi_in_pdu *inqueue); +void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in); +void iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inqueue); enum iscsi_initial_r2t { ISCSI_INITIAL_R2T_NO = 0, @@ -128,6 +128,8 @@ struct iscsi_context { int no_auto_reconnect; int reconnect_deferred; int debug; + int mallocs; + int frees; }; #define ISCSI_PDU_IMMEDIATE 0x40 @@ -208,7 +210,7 @@ struct iscsi_pdu { struct iscsi_scsi_cbdata *scsi_cbdata; }; -void iscsi_free_scsi_cbdata(struct iscsi_scsi_cbdata *scsi_cbdata); +void iscsi_free_scsi_cbdata(struct iscsi_context *iscsi, struct iscsi_scsi_cbdata *scsi_cbdata); struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, @@ -277,6 +279,10 @@ void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, unsigned char *iscsi_get_user_in_buffer(struct iscsi_context *iscsi, struct iscsi_in_pdu *in, uint32_t pos, ssize_t *count); unsigned char *scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos, ssize_t *count); +inline void* iscsi_malloc(struct iscsi_context *iscsi, size_t size); +inline void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size); +inline void iscsi_free(struct iscsi_context *iscsi, void* ptr); +inline char* iscsi_strdup(struct iscsi_context *iscsi, const char* str); unsigned long crc32c(char *buf, int len); diff --git a/include/iscsi.h b/include/iscsi.h index 0ab4b84..af7e1ba 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -77,6 +77,7 @@ struct iscsi_url { char user[MAX_STRING_SIZE+1]; char passwd[MAX_STRING_SIZE+1]; int lun; + struct iscsi_context *iscsi; }; /* diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h index 9d25b47..0f7face 100644 --- a/include/scsi-lowlevel.h +++ b/include/scsi-lowlevel.h @@ -123,7 +123,7 @@ enum scsi_xfer_dir { /* * READTOC */ -EXTERN struct scsi_task *scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_readtoc(struct iscsi_context *iscsi, int msf, int format, int track_session, uint16_t alloc_len); enum scsi_readtoc_fmt { SCSI_READ_TOC = 0, @@ -312,10 +312,10 @@ enum scsi_residual { struct scsi_task { int status; - int cdb_size; int xfer_dir; int expxferlen; + struct iscsi_context * iscsi; unsigned char cdb[SCSI_CDB_MAX_SIZE]; union { struct scsi_read6_params read6; @@ -371,8 +371,7 @@ EXTERN void *scsi_get_task_private_ptr(struct scsi_task *task); /* * TESTUNITREADY */ -EXTERN struct scsi_task *scsi_cdb_testunitready(void); - +EXTERN struct scsi_task *scsi_cdb_testunitready(struct iscsi_context *iscsi); /* * REPORTLUNS @@ -386,16 +385,16 @@ struct scsi_reportluns_list { uint16_t luns[0]; }; -EXTERN struct scsi_task *scsi_reportluns_cdb(int report_type, int alloc_len); +EXTERN struct scsi_task *scsi_reportluns_cdb(struct iscsi_context *iscsi, int report_type, int alloc_len); /* * RESERVE6 */ -EXTERN struct scsi_task *scsi_cdb_reserve6(void); +EXTERN struct scsi_task *scsi_cdb_reserve6(struct iscsi_context *iscsi); /* * RELEASE6 */ -EXTERN struct scsi_task *scsi_cdb_release6(void); +EXTERN struct scsi_task *scsi_cdb_release6(struct iscsi_context *iscsi); /* * READCAPACITY10 @@ -404,7 +403,7 @@ struct scsi_readcapacity10 { uint32_t lba; uint32_t block_size; }; -EXTERN struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi); +EXTERN struct scsi_task *scsi_cdb_readcapacity10(struct iscsi_context *iscsi, int lba, int pmi); /* @@ -564,7 +563,7 @@ struct scsi_inquiry_logical_block_provisioning { enum scsi_inquiry_provisioning_type provisioning_type; }; -EXTERN struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len); +EXTERN struct scsi_task *scsi_cdb_inquiry(struct iscsi_context *iscsi, int evpd, int page_code, int alloc_len); struct scsi_inquiry_unit_serial_number { enum scsi_inquiry_peripheral_qualifier qualifier; @@ -734,7 +733,8 @@ struct scsi_mode_sense { struct scsi_mode_page *pages; }; -EXTERN struct scsi_task *scsi_cdb_modesense6(int dbd, +EXTERN struct scsi_task *scsi_cdb_modesense6(struct iscsi_context *iscsi, + int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, @@ -799,37 +799,37 @@ struct scsi_report_supported_op_codes { EXTERN int scsi_datain_getfullsize(struct scsi_task *task); EXTERN void *scsi_datain_unmarshall(struct scsi_task *task); -EXTERN struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize); -EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int start); -EXTERN struct scsi_task *scsi_cdb_preventallow(int prevent); -EXTERN struct scsi_task *scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_read12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_read16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_startstopunit(struct iscsi_context *iscsi, int immed, int pcm, int pc, int no_flush, int loej, int start); +EXTERN struct scsi_task *scsi_cdb_preventallow(struct iscsi_context *iscsi, int prevent); +EXTERN struct scsi_task *scsi_cdb_orwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_compareandwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_verify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_verify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_verify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_synchronizecache10(int lba, int num_blocks, +EXTERN struct scsi_task *scsi_cdb_synchronizecache10(struct iscsi_context *iscsi, int lba, int num_blocks, int syncnv, int immed); -EXTERN struct scsi_task *scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, +EXTERN struct scsi_task *scsi_cdb_synchronizecache16(struct iscsi_context *iscsi, uint64_t lba, uint32_t num_blocks, int syncnv, int immed); -EXTERN struct scsi_task *scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen); -EXTERN struct scsi_task *scsi_cdb_readcapacity16(void); -EXTERN struct scsi_task *scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len); -EXTERN struct scsi_task *scsi_cdb_unmap(int anchor, int group, uint16_t xferlen); -EXTERN struct scsi_task *scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks); -EXTERN struct scsi_task *scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks); -EXTERN struct scsi_task *scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group); -EXTERN struct scsi_task *scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group); -EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(int report_timeouts, uint32_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_serviceactionin16(struct iscsi_context *iscsi, enum scsi_service_action_in sa, uint32_t xferlen); +EXTERN struct scsi_task *scsi_cdb_readcapacity16(struct iscsi_context *iscsi); +EXTERN struct scsi_task *scsi_cdb_get_lba_status(struct iscsi_context *iscsi, uint64_t starting_lba, uint32_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_unmap(struct iscsi_context *iscsi, int anchor, int group, uint16_t xferlen); +EXTERN struct scsi_task *scsi_cdb_writesame10(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks); +EXTERN struct scsi_task *scsi_cdb_writesame16(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks); +EXTERN struct scsi_task *scsi_cdb_prefetch10(struct iscsi_context *iscsi, uint32_t lba, int num_blocks, int immed, int group); +EXTERN struct scsi_task *scsi_cdb_prefetch16(struct iscsi_context *iscsi, uint64_t lba, int num_blocks, int immed, int group); +EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(struct iscsi_context *iscsi, int report_timeouts, uint32_t alloc_len); void *scsi_malloc(struct scsi_task *task, size_t size); diff --git a/lib/connect.c b/lib/connect.c index 4fce89c..be51d89 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -61,7 +61,7 @@ iscsi_testunitready_cb(struct iscsi_context *iscsi, int status, "failed."); ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); - free(ct); + iscsi_free(iscsi, ct); } scsi_free_scsi_task(task); return; @@ -80,7 +80,7 @@ iscsi_testunitready_cb(struct iscsi_context *iscsi, int status, ct->cb(iscsi, status?SCSI_STATUS_ERROR:SCSI_STATUS_GOOD, NULL, ct->private_data); scsi_free_scsi_task(task); - free(ct); + iscsi_free(iscsi, ct); } static void @@ -92,7 +92,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) { iscsi_disconnect(iscsi); if (iscsi_connect_async(iscsi, iscsi->target_address, iscsi_connect_cb, iscsi->connect_data) != 0) { - free(ct); + iscsi_free(iscsi, ct); return; } return; @@ -100,7 +100,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, if (status != 0) { ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); - free(ct); + iscsi_free(iscsi, ct); return; } @@ -121,14 +121,14 @@ iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data _U_ iscsi_set_error(iscsi, "Failed to connect to iSCSI socket. " "%s", iscsi_get_error(iscsi)); ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); - free(ct); + iscsi_free(iscsi, ct); return; } if (iscsi_login_async(iscsi, iscsi_login_cb, ct) != 0) { iscsi_set_error(iscsi, "iscsi_login_async failed."); ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); - free(ct); + iscsi_free(iscsi, ct); } } @@ -142,7 +142,7 @@ iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal, iscsi->lun = lun; strncpy(iscsi->portal,portal,MAX_STRING_SIZE); - ct = malloc(sizeof(struct connect_task)); + ct = iscsi_malloc(iscsi, sizeof(struct connect_task)); if (ct == NULL) { iscsi_set_error(iscsi, "Out-of-memory. Failed to allocate " "connect_task structure."); @@ -318,18 +318,22 @@ try_again: } if (old_iscsi->incoming != NULL) { - iscsi_free_iscsi_in_pdu(old_iscsi->incoming); + iscsi_free_iscsi_in_pdu(old_iscsi, old_iscsi->incoming); } if (old_iscsi->inqueue != NULL) { - iscsi_free_iscsi_inqueue(old_iscsi->inqueue); + iscsi_free_iscsi_inqueue(old_iscsi, old_iscsi->inqueue); } close(iscsi->fd); iscsi->fd = old_iscsi->fd; + int _mallocs = old_iscsi->mallocs; + int _frees = old_iscsi->frees; memcpy(old_iscsi, iscsi, sizeof(struct iscsi_context)); free(iscsi); old_iscsi->is_reconnecting = 0; + old_iscsi->mallocs+=_mallocs; + old_iscsi->frees+=_frees; return 0; } diff --git a/lib/discovery.c b/lib/discovery.c index f474ae7..1ddf8ef 100644 --- a/lib/discovery.c +++ b/lib/discovery.c @@ -79,19 +79,19 @@ iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb, } static void -iscsi_free_discovery_addresses(struct iscsi_discovery_address *addresses) +iscsi_free_discovery_addresses(struct iscsi_context *iscsi, struct iscsi_discovery_address *addresses) { while (addresses != NULL) { struct iscsi_discovery_address *next = addresses->next; - free(discard_const(addresses->target_name)); + iscsi_free(iscsi, discard_const(addresses->target_name)); addresses->target_name = NULL; - free(discard_const(addresses->target_address)); + iscsi_free(iscsi, discard_const(addresses->target_address)); addresses->target_address = NULL; addresses->next = NULL; - free(addresses); + iscsi_free(iscsi, addresses); addresses = next; } } @@ -127,7 +127,7 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, "discovery data %d>%d", len, size); pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data); - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return -1; } @@ -135,40 +135,39 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if (!strncmp((char *)ptr, "TargetName=", 11)) { struct iscsi_discovery_address *target; - target = malloc(sizeof(struct iscsi_discovery_address)); + target = iscsi_zmalloc(iscsi, sizeof(struct iscsi_discovery_address)); if (target == NULL) { iscsi_set_error(iscsi, "Failed to allocate " "data for new discovered " "target"); pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data); - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return -1; } - memset(target, 0, sizeof(struct iscsi_discovery_address)); - target->target_name = strdup((char *)ptr+11); + target->target_name = iscsi_strdup(iscsi,(char *)ptr+11); if (target->target_name == NULL) { iscsi_set_error(iscsi, "Failed to allocate " "data for new discovered " "target name"); pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data); - free(target); + iscsi_free(iscsi, target); target = NULL; - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return -1; } target->next = targets; targets = target; } else if (!strncmp((char *)ptr, "TargetAddress=", 14)) { - targets->target_address = strdup((char *)ptr+14); + targets->target_address = iscsi_strdup(iscsi, (char *)ptr+14); if (targets->target_address == NULL) { iscsi_set_error(iscsi, "Failed to allocate " "data for new discovered " "target address"); pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data); - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return -1; } } else { @@ -176,7 +175,7 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, "discovery string : %s", ptr); pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data); - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return -1; } @@ -185,7 +184,7 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, } pdu->callback(iscsi, SCSI_STATUS_GOOD, targets, pdu->private_data); - iscsi_free_discovery_addresses(targets); + iscsi_free_discovery_addresses(iscsi, targets); return 0; } diff --git a/lib/init.c b/lib/init.c index 533b654..a53d665 100644 --- a/lib/init.c +++ b/lib/init.c @@ -33,23 +33,50 @@ #include "iscsi-private.h" #include "slist.h" +inline void* iscsi_malloc(struct iscsi_context *iscsi, size_t size) { + void * ptr = malloc(size); + if (ptr != NULL) iscsi->mallocs++; + return ptr; +} + +inline void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size) { + void * ptr = malloc(size); + if (ptr != NULL) { + memset(ptr,0x00,size); + iscsi->mallocs++; + } + return ptr; +} + +inline void iscsi_free(struct iscsi_context *iscsi, void* ptr) { + if (ptr == NULL) return; + free(ptr); + iscsi->frees++; +} + +inline char* iscsi_strdup(struct iscsi_context *iscsi, const char* str) { + char *str2 = strdup(str); + if (str2 != NULL) iscsi->mallocs++; + return str2; +} + struct iscsi_context * iscsi_create_context(const char *initiator_name) { struct iscsi_context *iscsi; + if (!initiator_name[0]) { + return NULL; + } + iscsi = malloc(sizeof(struct iscsi_context)); if (iscsi == NULL) { return NULL; } - + memset(iscsi, 0, sizeof(struct iscsi_context)); strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE); - if (!iscsi->initiator_name[0]) { - free(iscsi); - return NULL; - } iscsi->fd = -1; @@ -226,14 +253,20 @@ iscsi_destroy_context(struct iscsi_context *iscsi) } if (iscsi->incoming != NULL) { - iscsi_free_iscsi_in_pdu(iscsi->incoming); + iscsi_free_iscsi_in_pdu(iscsi, iscsi->incoming); } if (iscsi->inqueue != NULL) { - iscsi_free_iscsi_inqueue(iscsi->inqueue); + iscsi_free_iscsi_inqueue(iscsi, iscsi->inqueue); } iscsi->connect_data = NULL; + if (iscsi->mallocs != iscsi->frees) { + DPRINTF(iscsi,1,"%d memory blocks lost at iscsi_destroy_context() after %d mallocs and %d frees",iscsi->mallocs-iscsi->frees,iscsi->mallocs,iscsi->frees); + } else { + DPRINTF(iscsi,5,"memory is clean at iscsi_destroy_context() after %d mallocs and %d frees",iscsi->mallocs,iscsi->frees); + } + free(iscsi); return 0; @@ -391,12 +424,12 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) if (tmp) *tmp=0; } - iscsi_url = malloc(sizeof(struct iscsi_url)); + iscsi_url = iscsi_zmalloc(iscsi, sizeof(struct iscsi_url)); if (iscsi_url == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure"); return NULL; } - memset(iscsi_url, 0, sizeof(struct iscsi_url)); + iscsi_url->iscsi= iscsi; strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE); @@ -428,7 +461,7 @@ iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url) void iscsi_destroy_url(struct iscsi_url *iscsi_url) { - free(iscsi_url); + iscsi_free(iscsi_url->iscsi, iscsi_url); } diff --git a/lib/login.c b/lib/login.c index 5da4d21..04368d2 100644 --- a/lib/login.c +++ b/lib/login.c @@ -43,23 +43,23 @@ iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { #else if (snprintf(str, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -74,24 +74,24 @@ iscsi_login_add_alias(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { #else if (snprintf(str, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -112,24 +112,24 @@ iscsi_login_add_targetname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return -1; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "TargetName=%s", iscsi->target_name) == -1) { #else if (snprintf(str, 1024, "TargetName=%s", iscsi->target_name) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -232,7 +232,7 @@ iscsi_login_add_initialr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? #else @@ -240,17 +240,17 @@ iscsi_login_add_initialr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) #endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -265,7 +265,7 @@ iscsi_login_add_immediatedata(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? #else @@ -273,17 +273,17 @@ iscsi_login_add_immediatedata(struct iscsi_context *iscsi, struct iscsi_pdu *pdu #endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -298,24 +298,24 @@ iscsi_login_add_maxburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *pd return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { #else if (snprintf(str, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -329,24 +329,24 @@ iscsi_login_add_firstburstlength(struct iscsi_context *iscsi, struct iscsi_pdu * return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { #else if (snprintf(str, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } @@ -360,24 +360,24 @@ iscsi_login_add_maxrecvdatasegmentlength(struct iscsi_context *iscsi, struct isc return 0; } - str = malloc(1024); + str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) if (_snprintf_s(str, 1024, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { #else if (snprintf(str, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - free(str); + iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - free(str); + iscsi_free(iscsi, str); return -1; } - free(str); + iscsi_free(iscsi, str); return 0; } diff --git a/lib/pdu.c b/lib/pdu.c index f9cbf80..7109511 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -36,22 +36,20 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode { struct iscsi_pdu *pdu; - pdu = malloc(sizeof(struct iscsi_pdu)); + pdu = iscsi_zmalloc(iscsi, sizeof(struct iscsi_pdu)); if (pdu == NULL) { iscsi_set_error(iscsi, "failed to allocate pdu"); return NULL; } - memset(pdu, 0, sizeof(struct iscsi_pdu)); pdu->outdata.size = ISCSI_HEADER_SIZE; - pdu->outdata.data = malloc(pdu->outdata.size); + pdu->outdata.data = iscsi_zmalloc(iscsi, pdu->outdata.size); if (pdu->outdata.data == NULL) { iscsi_set_error(iscsi, "failed to allocate pdu header"); - free(pdu); + iscsi_free(iscsi, pdu); return NULL; } - memset(pdu->outdata.data, 0, pdu->outdata.size); /* opcode */ pdu->outdata.data[0] = opcode; @@ -89,18 +87,18 @@ iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return; } - free(pdu->outdata.data); + iscsi_free(iscsi, pdu->outdata.data); pdu->outdata.data = NULL; - free(pdu->indata.data); + iscsi_free(iscsi, pdu->indata.data); pdu->indata.data = NULL; if (pdu->scsi_cbdata) { - iscsi_free_scsi_cbdata(pdu->scsi_cbdata); + iscsi_free_scsi_cbdata(iscsi, pdu->scsi_cbdata); pdu->scsi_cbdata = NULL; } - free(pdu); + iscsi_free(iscsi, pdu); } @@ -122,7 +120,8 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, if (pdualignment) { aligned = (aligned+3)&0xfffffffc; } - buf = malloc(aligned); + + buf = iscsi_malloc(iscsi, aligned); if (buf == NULL) { iscsi_set_error(iscsi, "failed to allocate buffer for %d " "bytes", len); @@ -138,7 +137,7 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, memset(buf+len, 0, aligned-len); } - free(data->data); + iscsi_free(iscsi, data->data); data->data = buf; data->size = len; diff --git a/lib/scsi-command.c b/lib/scsi-command.c index 0fe5291..49f96a0 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -37,7 +37,7 @@ struct iscsi_scsi_cbdata { }; void -iscsi_free_scsi_cbdata(struct iscsi_scsi_cbdata *scsi_cbdata) +iscsi_free_scsi_cbdata(struct iscsi_context *iscsi, struct iscsi_scsi_cbdata *scsi_cbdata) { if (scsi_cbdata == NULL) { return; @@ -45,7 +45,7 @@ iscsi_free_scsi_cbdata(struct iscsi_scsi_cbdata *scsi_cbdata) if (scsi_cbdata->task != NULL) { scsi_cbdata->task = NULL; } - free(scsi_cbdata); + iscsi_free(iscsi, scsi_cbdata); } static void @@ -186,13 +186,12 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, return -1; } - scsi_cbdata = malloc(sizeof(struct iscsi_scsi_cbdata)); + scsi_cbdata = iscsi_zmalloc(iscsi, sizeof(struct iscsi_scsi_cbdata)); if (scsi_cbdata == NULL) { iscsi_set_error(iscsi, "Out-of-memory: failed to allocate " "scsi cbdata."); return -1; } - memset(scsi_cbdata, 0, sizeof(struct iscsi_scsi_cbdata)); scsi_cbdata->task = task; scsi_cbdata->callback = cb; scsi_cbdata->private_data = private_data; @@ -204,7 +203,7 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi pdu."); - iscsi_free_scsi_cbdata(scsi_cbdata); + iscsi_free_scsi_cbdata(iscsi, scsi_cbdata); return -1; } pdu->scsi_cbdata = scsi_cbdata; @@ -384,7 +383,7 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, break; case SCSI_STATUS_CHECK_CONDITION: task->datain.size = in->data_pos; - task->datain.data = malloc(task->datain.size); + task->datain.data = iscsi_malloc(iscsi, task->datain.size); if (task->datain.data == NULL) { iscsi_set_error(iscsi, "failed to allocate blob for " "sense data"); @@ -533,7 +532,7 @@ iscsi_testunitready_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_testunitready(); + task = scsi_cdb_testunitready(iscsi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "testunitready cdb."); @@ -561,7 +560,7 @@ iscsi_reportluns_task(struct iscsi_context *iscsi, int report_type, return NULL; } - task = scsi_reportluns_cdb(report_type, alloc_len); + task = scsi_reportluns_cdb(iscsi, report_type, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "reportluns cdb."); @@ -584,7 +583,7 @@ iscsi_inquiry_task(struct iscsi_context *iscsi, int lun, int evpd, { struct scsi_task *task; - task = scsi_cdb_inquiry(evpd, page_code, maxsize); + task = scsi_cdb_inquiry(iscsi, evpd, page_code, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "inquiry cdb."); @@ -605,7 +604,7 @@ iscsi_readcapacity10_task(struct iscsi_context *iscsi, int lun, int lba, { struct scsi_task *task; - task = scsi_cdb_readcapacity10(lba, pmi); + task = scsi_cdb_readcapacity10(iscsi, lba, pmi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "readcapacity10 cdb."); @@ -626,7 +625,7 @@ iscsi_readcapacity16_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_readcapacity16(); + task = scsi_cdb_readcapacity16(iscsi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "readcapacity16 cdb."); @@ -648,7 +647,7 @@ iscsi_get_lba_status_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_get_lba_status(starting_lba, alloc_len); + task = scsi_cdb_get_lba_status(iscsi, starting_lba, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "get-lba-status cdb."); @@ -676,7 +675,7 @@ iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read6(lba, datalen, blocksize); + task = scsi_cdb_read6(iscsi, lba, datalen, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "read6 cdb."); @@ -705,7 +704,7 @@ iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read10(lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read10(iscsi, lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -735,7 +734,7 @@ iscsi_read12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read12(lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read12(iscsi, lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -765,7 +764,7 @@ iscsi_read16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_read16(lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read16(iscsi, lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -796,7 +795,7 @@ iscsi_write10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_write10(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write10(iscsi, lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -831,7 +830,7 @@ iscsi_write12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_write12(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write12(iscsi, lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -866,7 +865,7 @@ iscsi_write16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_write16(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write16(iscsi, lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -901,7 +900,7 @@ iscsi_orwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_orwrite(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_orwrite(iscsi, lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -936,7 +935,7 @@ iscsi_compareandwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_compareandwrite(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_compareandwrite(iscsi, lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -971,7 +970,7 @@ iscsi_writeverify10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_writeverify10(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify10(iscsi, lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1006,7 +1005,7 @@ iscsi_writeverify12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_writeverify12(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify12(iscsi, lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1041,7 +1040,7 @@ iscsi_writeverify16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_writeverify16(lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify16(iscsi, lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1075,7 +1074,7 @@ iscsi_verify10_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify10(lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify10(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify10 cdb."); @@ -1108,7 +1107,7 @@ iscsi_verify12_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify12(lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify12(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify12 cdb."); @@ -1141,7 +1140,7 @@ iscsi_verify16_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify16(lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify16(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify16 cdb."); @@ -1168,7 +1167,7 @@ iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc, { struct scsi_task *task; - task = scsi_cdb_modesense6(dbd, pc, page_code, sub_page_code, + task = scsi_cdb_modesense6(iscsi, dbd, pc, page_code, sub_page_code, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1192,7 +1191,7 @@ iscsi_startstopunit_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_startstopunit(immed, pcm, pc, no_flush, + task = scsi_cdb_startstopunit(iscsi, immed, pcm, pc, no_flush, loej, start); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1215,7 +1214,7 @@ iscsi_preventallow_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_preventallow(prevent); + task = scsi_cdb_preventallow(iscsi, prevent); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "PreventAllowMediumRemoval cdb."); @@ -1237,7 +1236,7 @@ iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun, int lba, { struct scsi_task *task; - task = scsi_cdb_synchronizecache10(lba, num_blocks, syncnv, + task = scsi_cdb_synchronizecache10(iscsi, lba, num_blocks, syncnv, immed); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1260,7 +1259,7 @@ iscsi_synchronizecache16_task(struct iscsi_context *iscsi, int lun, uint64_t lba { struct scsi_task *task; - task = scsi_cdb_synchronizecache16(lba, num_blocks, syncnv, + task = scsi_cdb_synchronizecache16(iscsi, lba, num_blocks, syncnv, immed); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1283,7 +1282,7 @@ iscsi_prefetch10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, { struct scsi_task *task; - task = scsi_cdb_prefetch10(lba, num_blocks, immed, group); + task = scsi_cdb_prefetch10(iscsi, lba, num_blocks, immed, group); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "prefetch10 cdb."); @@ -1305,7 +1304,7 @@ iscsi_prefetch16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, { struct scsi_task *task; - task = scsi_cdb_prefetch16(lba, num_blocks, immed, group); + task = scsi_cdb_prefetch16(iscsi, lba, num_blocks, immed, group); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "prefetch16 cdb."); @@ -1331,7 +1330,7 @@ iscsi_writesame10_task(struct iscsi_context *iscsi, int lun, struct scsi_task *task; struct iscsi_data outdata; - task = scsi_cdb_writesame10(wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); + task = scsi_cdb_writesame10(iscsi, wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "writesame10 cdb."); @@ -1373,7 +1372,7 @@ iscsi_writesame16_task(struct iscsi_context *iscsi, int lun, struct scsi_task *task; struct iscsi_data outdata; - task = scsi_cdb_writesame16(wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); + task = scsi_cdb_writesame16(iscsi, wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "writesame16 cdb."); @@ -1417,7 +1416,7 @@ iscsi_unmap_task(struct iscsi_context *iscsi, int lun, int anchor, int group, xferlen = 8 + list_len * 16; - task = scsi_cdb_unmap(anchor, group, xferlen); + task = scsi_cdb_unmap(iscsi, anchor, group, xferlen); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "unmap cdb."); @@ -1484,7 +1483,7 @@ iscsi_readtoc_task(struct iscsi_context *iscsi, int lun, int msf, { struct scsi_task *task; - task = scsi_cdb_readtoc(msf, format, track_session, maxsize); + task = scsi_cdb_readtoc(iscsi, msf, format, track_session, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "read TOC cdb."); @@ -1505,7 +1504,7 @@ iscsi_reserve6_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_reserve6(); + task = scsi_cdb_reserve6(iscsi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "reserve6 cdb."); @@ -1526,7 +1525,7 @@ iscsi_release6_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_release6(); + task = scsi_cdb_release6(iscsi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "release6 cdb."); @@ -1548,7 +1547,7 @@ iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, { struct scsi_task *task; - task = scsi_cdb_report_supported_opcodes(return_timeouts, maxsize); + task = scsi_cdb_report_supported_opcodes(iscsi, return_timeouts, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "Maintenance In/Read Supported Op Codes cdb."); diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index 3f8020e..73e9d1d 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -46,24 +46,32 @@ scsi_free_scsi_task(struct scsi_task *task) struct scsi_allocated_memory *mem; while ((mem = task->mem)) { - SLIST_REMOVE(&task->mem, mem); - free(mem); + SLIST_REMOVE(&task->mem, mem); + iscsi_free(task->iscsi, mem); } - free(task->datain.data); - free(task); + iscsi_free(task->iscsi,task->datain.data); + iscsi_free(task->iscsi,task); +} + +struct scsi_task * +scsi_create_scsi_task(struct iscsi_context *iscsi) +{ + struct scsi_task * task; + task = iscsi_zmalloc(iscsi, sizeof(struct scsi_task)); + if (task==NULL) return NULL; + task->iscsi=iscsi; + return task; } void * scsi_malloc(struct scsi_task *task, size_t size) { struct scsi_allocated_memory *mem; - - mem = malloc(sizeof(struct scsi_allocated_memory) + size); + mem = iscsi_zmalloc(task->iscsi,sizeof(struct scsi_allocated_memory) + size); if (mem == NULL) { return NULL; } - memset(mem, 0, sizeof(struct scsi_allocated_memory) + size); mem->ptr = (void *) ((uintptr_t)mem + sizeof(struct scsi_allocated_memory)); SLIST_ADD(&task->mem, mem); return mem->ptr; @@ -163,16 +171,15 @@ scsi_sense_ascq_str(int ascq) * TESTUNITREADY */ struct scsi_task * -scsi_cdb_testunitready(void) +scsi_cdb_testunitready(struct iscsi_context *iscsi) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_TESTUNITREADY; task->cdb_size = 6; @@ -187,16 +194,15 @@ scsi_cdb_testunitready(void) * REPORTLUNS */ struct scsi_task * -scsi_reportluns_cdb(int report_type, int alloc_len) +scsi_reportluns_cdb(struct iscsi_context *iscsi, int report_type, int alloc_len) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_REPORTLUNS; task->cdb[2] = report_type; *(uint32_t *)&task->cdb[6] = htonl(alloc_len); @@ -268,16 +274,15 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) * READCAPACITY10 */ struct scsi_task * -scsi_cdb_readcapacity10(int lba, int pmi) +scsi_cdb_readcapacity10(struct iscsi_context *iscsi, int lba, int pmi) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READCAPACITY10; *(uint32_t *)&task->cdb[2] = htonl(lba); @@ -302,7 +307,7 @@ scsi_cdb_readcapacity10(int lba, int pmi) * READTOC */ struct scsi_task * -scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len) +scsi_cdb_readtoc(struct iscsi_context *iscsi, int msf, int format, int track_session, uint16_t alloc_len) { struct scsi_task *task; @@ -312,12 +317,11 @@ scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len) return NULL; } - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READTOC; if (msf) { @@ -456,16 +460,15 @@ scsi_readtoc_datain_unmarshall(struct scsi_task *task) * RESERVE6 */ struct scsi_task * -scsi_cdb_reserve6(void) +scsi_cdb_reserve6(struct iscsi_context *iscsi) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_RESERVE6; task->cdb_size = 6; @@ -477,16 +480,15 @@ scsi_cdb_reserve6(void) * RELEASE10 */ struct scsi_task * -scsi_cdb_release6(void) +scsi_cdb_release6(struct iscsi_context *iscsi) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_RELEASE6; task->cdb_size = 6; @@ -637,16 +639,15 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task) * MAINTENANCE In / Read Supported Op Codes */ struct scsi_task * -scsi_cdb_report_supported_opcodes(int return_timeouts, uint32_t alloc_len) +scsi_cdb_report_supported_opcodes(struct iscsi_context *iscsi, int return_timeouts, uint32_t alloc_len) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_MAINTENANCE_IN; task->cdb[1] = SCSI_REPORT_SUPPORTED_OP_CODES; task->cdb[2] = SCSI_REPORT_SUPPORTING_OPS_ALL; @@ -711,16 +712,15 @@ scsi_readcapacity10_datain_unmarshall(struct scsi_task *task) * INQUIRY */ struct scsi_task * -scsi_cdb_inquiry(int evpd, int page_code, int alloc_len) +scsi_cdb_inquiry(struct iscsi_context *iscsi, int evpd, int page_code, int alloc_len) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_INQUIRY; if (evpd) { @@ -987,7 +987,7 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task) * READ6 */ struct scsi_task * -scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize) +scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize) { struct scsi_task *task; int num_blocks; @@ -1001,12 +1001,11 @@ scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize) return NULL; } - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ6; task->cdb_size = 6; @@ -1035,16 +1034,15 @@ scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize) * READ10 */ struct scsi_task * -scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1081,16 +1079,15 @@ scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, in * READ12 */ struct scsi_task * -scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1127,16 +1124,15 @@ scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, in * READ16 */ struct scsi_task * -scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1174,16 +1170,15 @@ scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, in * WRITE10 */ struct scsi_task * -scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE10; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1220,16 +1215,15 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, i * WRITE12 */ struct scsi_task * -scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE12; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1266,16 +1260,15 @@ scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, i * WRITE16 */ struct scsi_task * -scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE16; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1313,16 +1306,15 @@ scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, i * ORWRITE */ struct scsi_task * -scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_orwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_ORWRITE; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1360,16 +1352,15 @@ scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, i * COMPAREANDWRITE */ struct scsi_task * -scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_compareandwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_COMPARE_AND_WRITE; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1406,16 +1397,15 @@ scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrpr * VERIFY10 */ struct scsi_task * -scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY10; if (vprotect) { @@ -1452,16 +1442,15 @@ scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int byt * VERIFY12 */ struct scsi_task * -scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY12; if (vprotect) { @@ -1498,16 +1487,15 @@ scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int byt * VERIFY16 */ struct scsi_task * -scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY16; if (vprotect) { @@ -1545,16 +1533,15 @@ scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int byt * UNMAP */ struct scsi_task * -scsi_cdb_unmap(int anchor, int group, uint16_t xferlen) +scsi_cdb_unmap(struct iscsi_context *iscsi, int anchor, int group, uint16_t xferlen) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_UNMAP; if (anchor) { @@ -1579,16 +1566,15 @@ scsi_cdb_unmap(int anchor, int group, uint16_t xferlen) * WRITE_SAME10 */ struct scsi_task * -scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks) +scsi_cdb_writesame10(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_SAME10; if (wrprotect) { @@ -1623,16 +1609,15 @@ scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdat * WRITE_SAME16 */ struct scsi_task * -scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks) +scsi_cdb_writesame16(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_SAME16; if (wrprotect) { @@ -1668,18 +1653,17 @@ scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdat * MODESENSE6 */ struct scsi_task * -scsi_cdb_modesense6(int dbd, enum scsi_modesense_page_control pc, +scsi_cdb_modesense6(struct iscsi_context *iscsi, int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, unsigned char alloc_len) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_MODESENSE6; if (dbd) { @@ -1859,16 +1843,15 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) * STARTSTOPUNIT */ struct scsi_task * -scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int start) +scsi_cdb_startstopunit(struct iscsi_context *iscsi, int immed, int pcm, int pc, int no_flush, int loej, int start) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_STARTSTOPUNIT; if (immed) { @@ -1905,16 +1888,15 @@ scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int s * PREVENTALLOWMEDIUMREMOVAL */ struct scsi_task * -scsi_cdb_preventallow(int prevent) +scsi_cdb_preventallow(struct iscsi_context *iscsi, int prevent) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREVENTALLOW; task->cdb[4] = prevent & 0x03; @@ -1932,16 +1914,15 @@ scsi_cdb_preventallow(int prevent) * SYNCHRONIZECACHE10 */ struct scsi_task * -scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed) +scsi_cdb_synchronizecache10(struct iscsi_context *iscsi, int lba, int num_blocks, int syncnv, int immed) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SYNCHRONIZECACHE10; if (syncnv) { @@ -1964,16 +1945,15 @@ scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed) * SYNCHRONIZECACHE16 */ struct scsi_task * -scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, int syncnv, int immed) +scsi_cdb_synchronizecache16(struct iscsi_context *iscsi, uint64_t lba, uint32_t num_blocks, int syncnv, int immed) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SYNCHRONIZECACHE16; if (syncnv) { @@ -1997,16 +1977,15 @@ scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, int syncnv, int i * PREFETCH10 */ struct scsi_task * -scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group) +scsi_cdb_prefetch10(struct iscsi_context *iscsi, uint32_t lba, int num_blocks, int immed, int group) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREFETCH10; if (immed) { @@ -2027,16 +2006,15 @@ scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group) * PREFETCH16 */ struct scsi_task * -scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group) +scsi_cdb_prefetch16(struct iscsi_context *iscsi, uint64_t lba, int num_blocks, int immed, int group) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREFETCH16; if (immed) { @@ -2059,16 +2037,15 @@ scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group) * SERVICEACTIONIN16 */ struct scsi_task * -scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen) +scsi_cdb_serviceactionin16(struct iscsi_context *iscsi, enum scsi_service_action_in sa, uint32_t xferlen) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SERVICE_ACTION_IN; task->cdb[1] = sa; @@ -2092,25 +2069,24 @@ scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen) * READCAPACITY16 */ struct scsi_task * -scsi_cdb_readcapacity16(void) +scsi_cdb_readcapacity16(struct iscsi_context *iscsi) { - return scsi_cdb_serviceactionin16(SCSI_READCAPACITY16, 32); + return scsi_cdb_serviceactionin16(iscsi, SCSI_READCAPACITY16, 32); } /* * GET_LBA_STATUS */ struct scsi_task * -scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len) +scsi_cdb_get_lba_status(struct iscsi_context *iscsi, uint64_t starting_lba, uint32_t alloc_len) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SERVICE_ACTION_IN; task->cdb[1] = SCSI_GET_LBA_STATUS; @@ -2136,16 +2112,15 @@ scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len) * WRITEVERIFY10 */ struct scsi_task * -scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -2179,16 +2154,15 @@ scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprot * WRITEVERIFY12 */ struct scsi_task * -scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY12; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -2222,16 +2196,15 @@ scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprot * WRITEVERIFY16 */ struct scsi_task * -scsi_cdb_writeverify16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = malloc(sizeof(struct scsi_task)); + task = scsi_create_scsi_task(iscsi); if (task == NULL) { return NULL; } - memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY16; task->cdb[1] |= ((wrprotect & 0x07) << 5); diff --git a/lib/socket.c b/lib/socket.c index 4c4da61..247cea5 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -122,7 +122,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, return -1; } - addr = strdup(portal); + addr = iscsi_strdup(iscsi, portal); if (addr == NULL) { iscsi_set_error(iscsi, "Out-of-memory: " "Failed to strdup portal address."); @@ -151,7 +151,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, host ++; str = strchr(host, ']'); if (str == NULL) { - free(addr); + iscsi_free(iscsi, addr); iscsi_set_error(iscsi, "Invalid target:%s " "Missing ']' in IPv6 address", portal); return -1; @@ -161,12 +161,12 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, /* is it a hostname ? */ if (getaddrinfo(host, NULL, NULL, &ai) != 0) { - free(addr); + iscsi_free(iscsi, addr); iscsi_set_error(iscsi, "Invalid target:%s " "Can not resolv into IPv4/v6.", portal); return -1; } - free(addr); + iscsi_free(iscsi, addr); switch (ai->ai_family) { case AF_INET: @@ -296,12 +296,11 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) ssize_t data_size, count; if (iscsi->incoming == NULL) { - iscsi->incoming = malloc(sizeof(struct iscsi_in_pdu)); + iscsi->incoming = iscsi_zmalloc(iscsi, sizeof(struct iscsi_in_pdu)); if (iscsi->incoming == NULL) { iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu"); return -1; } - memset(iscsi->incoming, 0, sizeof(struct iscsi_in_pdu)); } in = iscsi->incoming; @@ -346,7 +345,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) /* if not, allocate one */ if (buf == NULL) { if (in->data == NULL) { - in->data = malloc(data_size); + in->data = iscsi_malloc(iscsi, data_size); if (in->data == NULL) { iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size); return -1; @@ -385,7 +384,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) return -1; } SLIST_REMOVE(&iscsi->inqueue, current); - iscsi_free_iscsi_in_pdu(current); + iscsi_free_iscsi_in_pdu(iscsi, current); } @@ -442,7 +441,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) return 0; } -int inline +inline int iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi) { if (iscsi->is_loggedin) { @@ -553,18 +552,18 @@ iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) } void -iscsi_free_iscsi_in_pdu(struct iscsi_in_pdu *in) +iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { - free(in->data); - free(in); + iscsi_free(iscsi, in->data); + iscsi_free(iscsi, in); } void -iscsi_free_iscsi_inqueue(struct iscsi_in_pdu *inqueue) +iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inqueue) { while (inqueue != NULL) { struct iscsi_in_pdu *next = inqueue->next; - iscsi_free_iscsi_in_pdu(inqueue); + iscsi_free_iscsi_in_pdu(iscsi, inqueue); inqueue = next; } } From 871c56ce7a7ea99439e92a69f8f67fdebcfcb807 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 02:05:16 +0100 Subject: [PATCH 03/27] MEMORY add compatibility for qemu-kvm qemu-kvm iscsi block driver calls iscsi_parse_full_url without a valid iscsi_context. The driver also creates its own scsi_task objects. --- lib/connect.c | 10 +++++----- lib/init.c | 11 +++++++++-- lib/scsi-lowlevel.c | 26 +++++++++++++++++++------- lib/socket.c | 2 ++ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/connect.c b/lib/connect.c index be51d89..ce7d6a8 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -140,7 +140,8 @@ iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal, struct connect_task *ct; iscsi->lun = lun; - strncpy(iscsi->portal,portal,MAX_STRING_SIZE); + if (iscsi->portal != portal) + strncpy(iscsi->portal,portal,MAX_STRING_SIZE); ct = iscsi_malloc(iscsi, sizeof(struct connect_task)); if (ct == NULL) { @@ -326,14 +327,13 @@ try_again: close(iscsi->fd); iscsi->fd = old_iscsi->fd; - int _mallocs = old_iscsi->mallocs; - int _frees = old_iscsi->frees; + iscsi->mallocs+=old_iscsi->mallocs; + iscsi->frees+=old_iscsi->frees; + memcpy(old_iscsi, iscsi, sizeof(struct iscsi_context)); free(iscsi); old_iscsi->is_reconnecting = 0; - old_iscsi->mallocs+=_mallocs; - old_iscsi->frees+=_frees; return 0; } diff --git a/lib/init.c b/lib/init.c index a53d665..774cdd5 100644 --- a/lib/init.c +++ b/lib/init.c @@ -424,11 +424,15 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) if (tmp) *tmp=0; } - iscsi_url = iscsi_zmalloc(iscsi, sizeof(struct iscsi_url)); + if (iscsi != NULL) + iscsi_url = iscsi_malloc(iscsi, sizeof(struct iscsi_url)); + else + iscsi_url = malloc(sizeof(struct iscsi_url)); if (iscsi_url == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure"); return NULL; } + memset(iscsi_url, 0, sizeof(struct iscsi_url)); iscsi_url->iscsi= iscsi; strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE); @@ -461,7 +465,10 @@ iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url) void iscsi_destroy_url(struct iscsi_url *iscsi_url) { - iscsi_free(iscsi_url->iscsi, iscsi_url); + if (iscsi_url->iscsi != NULL) + iscsi_free(iscsi_url->iscsi, iscsi_url); + else + free(iscsi_url); } diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index 73e9d1d..d99f5d9 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -45,13 +45,21 @@ scsi_free_scsi_task(struct scsi_task *task) { struct scsi_allocated_memory *mem; - while ((mem = task->mem)) { - SLIST_REMOVE(&task->mem, mem); - iscsi_free(task->iscsi, mem); + if (task->iscsi != NULL) { + while ((mem = task->mem)) { + SLIST_REMOVE(&task->mem, mem); + iscsi_free(task->iscsi, mem); + } + iscsi_free(task->iscsi,task->datain.data); + iscsi_free(task->iscsi,task); + } else { + while ((mem = task->mem)) { + SLIST_REMOVE(&task->mem, mem); + free(mem); + } + free(task->datain.data); + free(task); } - - iscsi_free(task->iscsi,task->datain.data); - iscsi_free(task->iscsi,task); } struct scsi_task * @@ -68,10 +76,14 @@ void * scsi_malloc(struct scsi_task *task, size_t size) { struct scsi_allocated_memory *mem; - mem = iscsi_zmalloc(task->iscsi,sizeof(struct scsi_allocated_memory) + size); + if (task->iscsi != NULL) + mem = iscsi_malloc(task->iscsi,sizeof(struct scsi_allocated_memory) + size); + else + mem = malloc(sizeof(struct scsi_allocated_memory) + size); if (mem == NULL) { return NULL; } + memset(mem, 0, sizeof(struct scsi_allocated_memory) + size); mem->ptr = (void *) ((uintptr_t)mem + sizeof(struct scsi_allocated_memory)); SLIST_ADD(&task->mem, mem); return mem->ptr; diff --git a/lib/socket.c b/lib/socket.c index a7f455a..087d573 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -568,7 +568,9 @@ void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { iscsi_free(iscsi, in->data); + in->data=NULL; iscsi_free(iscsi, in); + in=NULL; } void From a6caad107ca0342746f6d8e72fa78485486f5a58 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 02:12:46 +0100 Subject: [PATCH 04/27] INIT zero out sensitive data before its freed The iscsi_url and iscsi_context might contain clear text login credentials for an iscsi target. As Linux zeroes on allocate this data might remain in memory for a long time. --- lib/connect.c | 1 + lib/init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/connect.c b/lib/connect.c index ce7d6a8..32b3316 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -331,6 +331,7 @@ try_again: iscsi->frees+=old_iscsi->frees; memcpy(old_iscsi, iscsi, sizeof(struct iscsi_context)); + memset(iscsi, 0, sizeof(struct iscsi_context)); free(iscsi); old_iscsi->is_reconnecting = 0; diff --git a/lib/init.c b/lib/init.c index 774cdd5..c23d25d 100644 --- a/lib/init.c +++ b/lib/init.c @@ -267,6 +267,7 @@ iscsi_destroy_context(struct iscsi_context *iscsi) DPRINTF(iscsi,5,"memory is clean at iscsi_destroy_context() after %d mallocs and %d frees",iscsi->mallocs,iscsi->frees); } + memset(iscsi, 0, sizeof(struct iscsi_context)); free(iscsi); return 0; @@ -465,7 +466,9 @@ iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url) void iscsi_destroy_url(struct iscsi_url *iscsi_url) { - if (iscsi_url->iscsi != NULL) + struct iscsi_context *iscsi = iscsi_url->iscsi; + memset(iscsi_url, 0, sizeof(struct iscsi_url)); + if (iscsi != NULL) iscsi_free(iscsi_url->iscsi, iscsi_url); else free(iscsi_url); From 3268ae4c888e2dfac517ce5aac2aeb8004d1f370 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 02:26:30 +0100 Subject: [PATCH 05/27] INIT fix iscsi_destroy_url --- include/iscsi.h | 2 ++ lib/init.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/iscsi.h b/include/iscsi.h index af7e1ba..9753d22 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,6 +33,7 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) +#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. @@ -533,6 +534,7 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi, struct iscsi_data { int size; + int alloc_size; unsigned char *data; }; diff --git a/lib/init.c b/lib/init.c index c23d25d..840e163 100644 --- a/lib/init.c +++ b/lib/init.c @@ -469,7 +469,7 @@ iscsi_destroy_url(struct iscsi_url *iscsi_url) struct iscsi_context *iscsi = iscsi_url->iscsi; memset(iscsi_url, 0, sizeof(struct iscsi_url)); if (iscsi != NULL) - iscsi_free(iscsi_url->iscsi, iscsi_url); + iscsi_free(iscsi, iscsi_url); else free(iscsi_url); } From d9fbe37f4b96ace03bace8fa3f3283a5a57e7383 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 02:28:23 +0100 Subject: [PATCH 06/27] HEADERS fix early commit of new header data --- include/iscsi.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/iscsi.h b/include/iscsi.h index 9753d22..af7e1ba 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,7 +33,6 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) -#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. @@ -534,7 +533,6 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi, struct iscsi_data { int size; - int alloc_size; unsigned char *data; }; From c4dc3802627207ad9af999d16b6c90129ce0c05a Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 02:49:56 +0100 Subject: [PATCH 07/27] PDU reduce number of mallocs/memcpys in iscsi_add_data() This patch adds logarithmic malloc behaviour to iscsi_add_data(). Currently for each new call there is a new buffer allocated and all old data is copied to the new buffer. Change this by allocating at least PAGE_SIZE bytes and increase the allocation by powers of 2 each time it does no longer fit. --- include/iscsi.h | 2 ++ lib/pdu.c | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/iscsi.h b/include/iscsi.h index af7e1ba..9753d22 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,6 +33,7 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) +#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. @@ -533,6 +534,7 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi, struct iscsi_data { int size; + int alloc_size; unsigned char *data; }; diff --git a/lib/pdu.c b/lib/pdu.c index 7109511..86dc2b1 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -107,7 +107,6 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, unsigned char *dptr, int dsize, int pdualignment) { int len, aligned; - unsigned char *buf; if (dsize == 0) { iscsi_set_error(iscsi, "Trying to append zero size data to " @@ -121,25 +120,33 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, aligned = (aligned+3)&0xfffffffc; } - buf = iscsi_malloc(iscsi, aligned); - if (buf == NULL) { + int new_alloc_size=data->alloc_size; + if (new_alloc_size < PAGE_SIZE) new_alloc_size=PAGE_SIZE; + + while (aligned > new_alloc_size) new_alloc_size<<=1; + + if (data->data != NULL && data->alloc_size == 0) data->alloc_size=data->size; + + if (data->alloc_size == 0) + data->data = iscsi_malloc(iscsi, new_alloc_size); + else + if (data->alloc_size != new_alloc_size) + data->data = realloc(data->data, new_alloc_size); + + if (data->data == NULL) { iscsi_set_error(iscsi, "failed to allocate buffer for %d " "bytes", len); return -1; } + + data->alloc_size = new_alloc_size; + memcpy(data->data + data->size, dptr, dsize); - if (data->size > 0) { - memcpy(buf, data->data, data->size); - } - memcpy(buf + data->size, dptr, dsize); if (len != aligned) { /* zero out any padding at the end */ - memset(buf+len, 0, aligned-len); + memset(data->data+len, 0, aligned-len); } - iscsi_free(iscsi, data->data); - - data->data = buf; data->size = len; return 0; From fbfa6bca61105ebf47f8320b4bbe3d097467a6ae Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 10:58:35 +0100 Subject: [PATCH 08/27] ISCSI-READCAPACITY16 fix missing free of scsi_task --- src/iscsi-readcapacity16.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/iscsi-readcapacity16.c b/src/iscsi-readcapacity16.c index bbbc38f..89e5637 100644 --- a/src/iscsi-readcapacity16.c +++ b/src/iscsi-readcapacity16.c @@ -176,6 +176,7 @@ int main(int argc, const char *argv[]) printf("%" PRIu64 "\n", rc16->block_length * (rc16->returned_lba + 1)); } + scsi_free_scsi_task(task); iscsi_destroy_url(iscsi_url); iscsi_logout_sync(iscsi); From 0bf8b3880854d4d180f77d1a6f55297fb7573ffb Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 11:09:20 +0100 Subject: [PATCH 09/27] LD_ISCSI fix segfault on reconnect iscsi_reconnect calls dup2 which is intercepted in ld_iscsi. Fix this by calling the real dup2 in this case. --- src/ld_iscsi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index b6c4aa8..cdf86e8 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -387,6 +387,10 @@ int (*real_dup2)(int oldfd, int newfd); int dup2(int oldfd, int newfd) { + if (iscsi_fd_list[newfd].is_iscsi) { + return real_dup2(oldfd, newfd); + } + close(newfd); if (iscsi_fd_list[oldfd].is_iscsi == 1) { From d2894e46343576602799b5c801b759c776a9d808 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 17:36:29 +0100 Subject: [PATCH 10/27] LD_ISCSI add lseek --- src/ld_iscsi.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index cdf86e8..975e800 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -275,6 +275,37 @@ int __xstat(int ver, const char *path, struct stat *buf) return __lxstat(ver, path, buf); } +off_t (*real_lseek)(int fd, off_t offset, int whence); + +off_t lseek(int fd, off_t offset, int whence) { + if (iscsi_fd_list[fd].is_iscsi == 1) { + off_t new_offset; + off_t size = iscsi_fd_list[fd].num_blocks*iscsi_fd_list[fd].block_size; + switch (whence) { + case SEEK_SET: + new_offset = offset; + break; + case SEEK_CUR: + new_offset = iscsi_fd_list[fd].offset+offset; + break; + case SEEK_END: + new_offset = size + offset; + break; + default: + errno = EINVAL; + return -1; + } + if (new_offset < 0 || new_offset > size) { + errno = EINVAL; + return -1; + } + iscsi_fd_list[fd].offset=new_offset; + return iscsi_fd_list[fd].offset; + } + + return real_lseek(fd, offset, whence); +} + ssize_t (*real_read)(int fd, void *buf, size_t count); ssize_t read(int fd, void *buf, size_t count) @@ -503,6 +534,12 @@ static void __attribute__((constructor)) _init(void) exit(10); } + real_lseek = dlsym(RTLD_NEXT, "lseek"); + if (real_lseek == NULL) { + LD_ISCSI_DPRINTF(0,"Failed to dlsym(lseek)"); + exit(10); + } + real_read = dlsym(RTLD_NEXT, "read"); if (real_read == NULL) { LD_ISCSI_DPRINTF(0,"Failed to dlsym(read)"); From 2e413a3c9fb403204b0a935c4445c5f53adb23e8 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 17:48:31 +0100 Subject: [PATCH 11/27] LD_ISCSI add pread --- src/ld_iscsi.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 975e800..47e7214 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -413,6 +413,26 @@ ssize_t read(int fd, void *buf, size_t count) return real_read(fd, buf, count); } +ssize_t (*real_pread)(int fd, void *buf, size_t count, off_t offset); +ssize_t pread(int fd, void *buf, size_t count, off_t offset) { + if ((iscsi_fd_list[fd].is_iscsi == 1 && iscsi_fd_list[fd].in_flight == 0)) { + off_t old_offset; + if ((old_offset = lseek(fd, 0, SEEK_CUR)) < 0) { + errno = EIO; + return -1; + } + if (lseek(fd, offset, SEEK_SET) < 0) { + return -1; + } + if (read(fd, buf, count) < 0) { + lseek(fd, old_offset, SEEK_SET); + return -1; + } + lseek(fd, old_offset, SEEK_SET); + return count; + } + return real_pread(fd, buf, count, offset); +} int (*real_dup2)(int oldfd, int newfd); @@ -546,6 +566,12 @@ static void __attribute__((constructor)) _init(void) exit(10); } + real_pread = dlsym(RTLD_NEXT, "pread"); + if (real_pread == NULL) { + LD_ISCSI_DPRINTF(0,"Failed to dlsym(pread)"); + exit(10); + } + real_dup2 = dlsym(RTLD_NEXT, "dup2"); if (real_dup2 == NULL) { LD_ISCSI_DPRINTF(0,"Failed to dlsym(dup2)"); From 0639c7e9abff10ff400ebdef0ebe485275fe9459 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 18:08:12 +0100 Subject: [PATCH 12/27] LD_ISCSI add write the write command is limited in the sense that file offset and count bytes must be multiple of the targets blocksize. for most copy/dd etc. operations this is sufficient to work. --- src/ld_iscsi.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 47e7214..7d2d5d6 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -434,6 +434,61 @@ ssize_t pread(int fd, void *buf, size_t count, off_t offset) { return real_pread(fd, buf, count, offset); } +ssize_t (*real_write)(int fd, const void *buf, size_t count); + +ssize_t write(int fd, const void *buf, size_t count) +{ + if ((iscsi_fd_list[fd].is_iscsi == 1) && (iscsi_fd_list[fd].in_flight == 0)) { + uint64_t offset; + uint64_t num_blocks, lba; + struct scsi_task *task; + + if (iscsi_fd_list[fd].dup2fd >= 0) { + return write(iscsi_fd_list[fd].dup2fd, buf, count); + } + if (iscsi_fd_list[fd].offset%iscsi_fd_list[fd].block_size) { + errno = EINVAL; + return -1; + } + if (count%iscsi_fd_list[fd].block_size) { + errno = EINVAL; + return -1; + } + + offset = iscsi_fd_list[fd].offset; + num_blocks = count/iscsi_fd_list[fd].block_size; + lba = offset / iscsi_fd_list[fd].block_size; + + /* Don't try to read beyond the last LBA */ + if (lba >= iscsi_fd_list[fd].num_blocks) { + return 0; + } + /* Trim num_blocks requested to last lba */ + if ((lba + num_blocks) > iscsi_fd_list[fd].num_blocks) { + num_blocks = iscsi_fd_list[fd].num_blocks - lba; + count = num_blocks * iscsi_fd_list[fd].block_size; + } + + iscsi_fd_list[fd].in_flight = 1; + LD_ISCSI_DPRINTF(4,"write16_sync: lun %d, lba %lu, num_blocks: %lu, block_size: %d, offset: %lu count: %lu",iscsi_fd_list[fd].lun,lba,num_blocks,iscsi_fd_list[fd].block_size,offset,count); + task = iscsi_write16_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, lba, (unsigned char *) buf, count, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); + iscsi_fd_list[fd].in_flight = 0; + if (task == NULL || task->status != SCSI_STATUS_GOOD) { + LD_ISCSI_DPRINTF(0,"failed to send write16 command"); + errno = EIO; + return -1; + } + + iscsi_fd_list[fd].offset += count; + scsi_free_scsi_task(task); + + return count; + } + + return real_write(fd, buf, count); +} + + int (*real_dup2)(int oldfd, int newfd); int dup2(int oldfd, int newfd) @@ -572,6 +627,12 @@ static void __attribute__((constructor)) _init(void) exit(10); } + real_write = dlsym(RTLD_NEXT, "write"); + if (real_write == NULL) { + LD_ISCSI_DPRINTF(0,"Failed to dlsym(write)"); + exit(10); + } + real_dup2 = dlsym(RTLD_NEXT, "dup2"); if (real_dup2 == NULL) { LD_ISCSI_DPRINTF(0,"Failed to dlsym(dup2)"); From e1bb8e1ed13ee196cbb4420e17d799b00fe31cc6 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 18:12:39 +0100 Subject: [PATCH 13/27] LD_ISCSI add pwite --- src/ld_iscsi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 7d2d5d6..7a740f2 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -488,6 +488,26 @@ ssize_t write(int fd, const void *buf, size_t count) return real_write(fd, buf, count); } +ssize_t (*real_pwrite)(int fd, const void *buf, size_t count, off_t offset); +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) { + if ((iscsi_fd_list[fd].is_iscsi == 1 && iscsi_fd_list[fd].in_flight == 0)) { + off_t old_offset; + if ((old_offset = lseek(fd, 0, SEEK_CUR)) < 0) { + errno = EIO; + return -1; + } + if (lseek(fd, offset, SEEK_SET) < 0) { + return -1; + } + if (write(fd, buf, count) < 0) { + lseek(fd, old_offset, SEEK_SET); + return -1; + } + lseek(fd, old_offset, SEEK_SET); + return count; + } + return real_pwrite(fd, buf, count, offset); +} int (*real_dup2)(int oldfd, int newfd); From b5183d5e3057a0f9c5afeb98a9b8d677cedd1a73 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Sat, 3 Nov 2012 18:15:05 +0100 Subject: [PATCH 14/27] LD_ISCSI add pwrite and dlsym it at init --- src/ld_iscsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index 7a740f2..f9271a6 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -653,6 +653,12 @@ static void __attribute__((constructor)) _init(void) exit(10); } + real_pwrite = dlsym(RTLD_NEXT, "pwrite"); + if (real_pwrite == NULL) { + LD_ISCSI_DPRINTF(0,"Failed to dlsym(pwrite)"); + exit(10); + } + real_dup2 = dlsym(RTLD_NEXT, "dup2"); if (real_dup2 == NULL) { LD_ISCSI_DPRINTF(0,"Failed to dlsym(dup2)"); From 65cd38e8ffc3ef9767a991b487238265407d54d2 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 5 Nov 2012 15:13:50 +0100 Subject: [PATCH 15/27] PDU further optimize iscsi_add_data() This patch further improves add data and esepcially preassigns the right amount of memory where the amount is preknown --- include/iscsi-private.h | 10 ++++++++++ include/iscsi.h | 1 - lib/login.c | 4 ++-- lib/pdu.c | 33 ++++++++++++++++++++++++++------- lib/scsi-command.c | 17 +++++++++++++---- 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index ddf7807..528b9a1 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -215,11 +215,21 @@ void iscsi_free_scsi_cbdata(struct iscsi_context *iscsi, struct iscsi_scsi_cbdat struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode); +struct iscsi_pdu *iscsi_allocate_pdu_size(struct iscsi_context *iscsi, + enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, + size_t payload_size); struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags); +struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags_size(struct iscsi_context *iscsi, + enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, + uint32_t itt, + uint32_t flags, + size_t payload_size); void iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); void iscsi_pdu_set_pduflags(struct iscsi_pdu *pdu, unsigned char flags); void iscsi_pdu_set_immediate(struct iscsi_pdu *pdu); diff --git a/include/iscsi.h b/include/iscsi.h index 9753d22..6ac7f0e 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,7 +33,6 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) -#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. diff --git a/lib/login.c b/lib/login.c index 04368d2..5728007 100644 --- a/lib/login.c +++ b/lib/login.c @@ -735,10 +735,10 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, return -1; } - pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, + pdu = iscsi_allocate_pdu_with_itt_flags_size(iscsi, ISCSI_PDU_LOGIN_REQUEST, ISCSI_PDU_LOGIN_RESPONSE, - iscsi->itt, 0); + iscsi->itt, 0, 1024); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate " "login pdu."); diff --git a/lib/pdu.c b/lib/pdu.c index 86dc2b1..f2e11ba 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -31,8 +31,8 @@ #include "slist.h" struct iscsi_pdu * -iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, - enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags) +iscsi_allocate_pdu_with_itt_flags_size(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags, size_t payload_size) { struct iscsi_pdu *pdu; @@ -43,7 +43,10 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode } pdu->outdata.size = ISCSI_HEADER_SIZE; - pdu->outdata.data = iscsi_zmalloc(iscsi, pdu->outdata.size); + pdu->outdata.alloc_size = 64; + while (pdu->outdata.alloc_size < ISCSI_HEADER_SIZE+payload_size) pdu->outdata.alloc_size<<=1; + pdu->outdata.data = iscsi_malloc(iscsi, pdu->outdata.alloc_size); + memset(pdu->outdata.data, 0, ISCSI_HEADER_SIZE); if (pdu->outdata.data == NULL) { iscsi_set_error(iscsi, "failed to allocate pdu header"); @@ -70,6 +73,13 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode return pdu; } +struct iscsi_pdu * +iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags) +{ + return iscsi_allocate_pdu_with_itt_flags_size(iscsi, opcode, response_opcode, itt, flags, 0); +} + struct iscsi_pdu * iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode) @@ -77,6 +87,13 @@ iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, return iscsi_allocate_pdu_with_itt_flags(iscsi, opcode, response_opcode, iscsi->itt++, 0); } +struct iscsi_pdu * +iscsi_allocate_pdu_size(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, size_t payload_size) +{ + return iscsi_allocate_pdu_with_itt_flags_size(iscsi, opcode, response_opcode, iscsi->itt++, 0, payload_size); +} + void @@ -120,18 +137,20 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, aligned = (aligned+3)&0xfffffffc; } - int new_alloc_size=data->alloc_size; - if (new_alloc_size < PAGE_SIZE) new_alloc_size=PAGE_SIZE; + int new_alloc_size = data->alloc_size; + if (new_alloc_size < 64) new_alloc_size=64; while (aligned > new_alloc_size) new_alloc_size<<=1; if (data->data != NULL && data->alloc_size == 0) data->alloc_size=data->size; - if (data->alloc_size == 0) + if (data->alloc_size == 0) { data->data = iscsi_malloc(iscsi, new_alloc_size); + } else - if (data->alloc_size != new_alloc_size) + if (data->alloc_size != new_alloc_size) { data->data = realloc(data->data, new_alloc_size); + } if (data->data == NULL) { iscsi_set_error(iscsi, "failed to allocate buffer for %d " diff --git a/lib/scsi-command.c b/lib/scsi-command.c index f3f4cef..57c50d3 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -85,10 +85,11 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu, len = iscsi->target_max_recv_data_segment_length; } - pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT, + pdu = iscsi_allocate_pdu_with_itt_flags_size(iscsi, ISCSI_PDU_DATA_OUT, ISCSI_PDU_NO_PDU, cmd_pdu->itt, - ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK); + ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK, + len); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi data out pdu."); @@ -198,8 +199,16 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, scsi_set_task_private_ptr(task, scsi_cbdata); - pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_SCSI_REQUEST, - ISCSI_PDU_SCSI_RESPONSE); + u_int32_t payload_size = 0; + if (iscsi->use_immediate_data == ISCSI_IMMEDIATE_DATA_YES) { + payload_size=data.size; + if (payload_size > iscsi->first_burst_length) { + payload_size = iscsi->first_burst_length; + } + } + + pdu = iscsi_allocate_pdu_size(iscsi, ISCSI_PDU_SCSI_REQUEST, + ISCSI_PDU_SCSI_RESPONSE, payload_size); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi pdu."); From e6553c2ef892807eb1bd76a0664f52f16313c15a Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 5 Nov 2012 15:20:15 +0100 Subject: [PATCH 16/27] MEMORY account reallocs --- include/iscsi-private.h | 2 ++ lib/init.c | 12 ++++++++++-- lib/pdu.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 528b9a1..8d209b9 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -129,6 +129,7 @@ struct iscsi_context { int reconnect_deferred; int debug; int mallocs; + int reallocs; int frees; }; @@ -291,6 +292,7 @@ unsigned char *scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos inline void* iscsi_malloc(struct iscsi_context *iscsi, size_t size); inline void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size); +inline void* iscsi_realloc(struct iscsi_context *iscsi, void* ptr, size_t size); inline void iscsi_free(struct iscsi_context *iscsi, void* ptr); inline char* iscsi_strdup(struct iscsi_context *iscsi, const char* str); diff --git a/lib/init.c b/lib/init.c index ecb3925..cf51500 100644 --- a/lib/init.c +++ b/lib/init.c @@ -48,6 +48,14 @@ inline void* iscsi_zmalloc(struct iscsi_context *iscsi, size_t size) { return ptr; } +inline void* iscsi_realloc(struct iscsi_context *iscsi, void* ptr, size_t size) { + void * _ptr = realloc(ptr, size); + if (_ptr != NULL) { + iscsi->reallocs++; + } + return _ptr; +} + inline void iscsi_free(struct iscsi_context *iscsi, void* ptr) { if (ptr == NULL) return; free(ptr); @@ -262,9 +270,9 @@ iscsi_destroy_context(struct iscsi_context *iscsi) iscsi->connect_data = NULL; if (iscsi->mallocs != iscsi->frees) { - DPRINTF(iscsi,1,"%d memory blocks lost at iscsi_destroy_context() after %d mallocs and %d frees",iscsi->mallocs-iscsi->frees,iscsi->mallocs,iscsi->frees); + DPRINTF(iscsi,1,"%d memory blocks lost at iscsi_destroy_context() after %d malloc(s), %d realloc(s) and %d free(s)",iscsi->mallocs-iscsi->frees,iscsi->mallocs,iscsi->reallocs,iscsi->frees); } else { - DPRINTF(iscsi,5,"memory is clean at iscsi_destroy_context() after %d mallocs and %d frees",iscsi->mallocs,iscsi->frees); + DPRINTF(iscsi,5,"memory is clean at iscsi_destroy_context() after %d mallocs, %d realloc(s) and %d frees",iscsi->mallocs,iscsi->reallocs,iscsi->frees); } memset(iscsi, 0, sizeof(struct iscsi_context)); diff --git a/lib/pdu.c b/lib/pdu.c index f2e11ba..c1e578f 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -149,7 +149,7 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, } else if (data->alloc_size != new_alloc_size) { - data->data = realloc(data->data, new_alloc_size); + data->data = iscsi_realloc(iscsi, data->data, new_alloc_size); } if (data->data == NULL) { From 57ec16023ec3e3a80b2553755f0c49d56c29b771 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 5 Nov 2012 15:33:12 +0100 Subject: [PATCH 17/27] LOGIN change dynamic string allocations to statics --- lib/login.c | 162 +++++++++++++++++++++------------------------------- 1 file changed, 66 insertions(+), 96 deletions(-) diff --git a/lib/login.c b/lib/login.c index 5728007..29f97c4 100644 --- a/lib/login.c +++ b/lib/login.c @@ -35,7 +35,7 @@ static int iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send InitiatorName during opneg or the first leg of secneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG @@ -43,30 +43,26 @@ iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "InitiatorName=%s", iscsi->initiator_name) == -1) { #else - if (snprintf(str, 1024, "InitiatorName=%s", iscsi->initiator_name) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "InitiatorName=%s", iscsi->initiator_name) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_alias(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send InitiatorAlias during opneg or the first leg of secneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG @@ -74,31 +70,27 @@ iscsi_login_add_alias(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "InitiatorAlias=%s", iscsi->alias) == -1) { #else - if (snprintf(str, 1024, "InitiatorAlias=%s", iscsi->alias) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "InitiatorAlias=%s", iscsi->alias) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_targetname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send TargetName during opneg or the first leg of secneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG @@ -112,31 +104,27 @@ iscsi_login_add_targetname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return -1; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "TargetName=%s", iscsi->target_name) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "TargetName=%s", iscsi->target_name) == -1) { #else - if (snprintf(str, 1024, "TargetName=%s", iscsi->target_name) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "TargetName=%s", iscsi->target_name) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_sessiontype(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send TargetName during opneg or the first leg of secneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG @@ -146,10 +134,10 @@ iscsi_login_add_sessiontype(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) switch (iscsi->session_type) { case ISCSI_SESSION_DISCOVERY: - str = (char *)"SessionType=Discovery"; + strncpy(str,"SessionType=Discovery",MAX_STRING_SIZE); break; case ISCSI_SESSION_NORMAL: - str = (char *)"SessionType=Normal"; + strncpy(str,"SessionType=Normal",MAX_STRING_SIZE); break; default: iscsi_set_error(iscsi, "Can not handle sessions %d yet.", @@ -168,7 +156,7 @@ iscsi_login_add_sessiontype(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_headerdigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send HeaderDigest during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { @@ -177,16 +165,16 @@ iscsi_login_add_headerdigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) switch (iscsi->want_header_digest) { case ISCSI_HEADER_DIGEST_NONE: - str = (char *)"HeaderDigest=None"; + strncpy(str,"HeaderDigest=None",MAX_STRING_SIZE); break; case ISCSI_HEADER_DIGEST_NONE_CRC32C: - str = (char *)"HeaderDigest=None,CRC32C"; + strncpy(str,"HeaderDigest=None,CRC32C",MAX_STRING_SIZE); break; case ISCSI_HEADER_DIGEST_CRC32C_NONE: - str = (char *)"HeaderDigest=CRC32C,None"; + strncpy(str,"HeaderDigest=CRC32C,None",MAX_STRING_SIZE); break; case ISCSI_HEADER_DIGEST_CRC32C: - str = (char *)"HeaderDigest=CRC32C"; + strncpy(str,"HeaderDigest=CRC32C",MAX_STRING_SIZE); break; default: iscsi_set_error(iscsi, "invalid header digest value"); @@ -205,14 +193,14 @@ iscsi_login_add_headerdigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_datadigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send DataDigest during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"DataDigest=None"; + strncpy(str,"DataDigest=None",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -225,32 +213,28 @@ iscsi_login_add_datadigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_initialr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send InitialR2T during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? #else - if (snprintf(str, 1024, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? + if (snprintf(str, MAX_STRING_SIZE, "InitialR2T=%s", iscsi->want_initial_r2t == ISCSI_INITIAL_R2T_NO ? #endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } @@ -258,32 +242,28 @@ iscsi_login_add_initialr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_immediatedata(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send ImmediateData during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? #else - if (snprintf(str, 1024, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? + if (snprintf(str, MAX_STRING_SIZE, "ImmediateData=%s", iscsi->want_immediate_data == ISCSI_IMMEDIATE_DATA_NO ? #endif "No" : "Yes") == -1) { iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } @@ -291,107 +271,95 @@ iscsi_login_add_immediatedata(struct iscsi_context *iscsi, struct iscsi_pdu *pdu static int iscsi_login_add_maxburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send MaxBurstLength during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { #else - if (snprintf(str, 1024, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "MaxBurstLength=%d", iscsi->max_burst_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_firstburstlength(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send FirstBurstLength during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { #else - if (snprintf(str, 1024, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "FirstBurstLength=%d", iscsi->first_burst_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_maxrecvdatasegmentlength(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send MaxRecvDataSegmentLength during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = iscsi_malloc(iscsi, 1024); #if defined(WIN32) - if (_snprintf_s(str, 1024, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { + if (_snprintf_s(str, MAX_STRING_SIZE, MAX_STRING_SIZE, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { #else - if (snprintf(str, 1024, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { + if (snprintf(str, MAX_STRING_SIZE, "MaxRecvDataSegmentLength=%d", iscsi->initiator_max_recv_data_segment_length) == -1) { #endif iscsi_set_error(iscsi, "Out-of-memory: aprintf failed."); - iscsi_free(iscsi, str); return -1; } if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); - iscsi_free(iscsi, str); return -1; } - iscsi_free(iscsi, str); return 0; } static int iscsi_login_add_datapduinorder(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send DataPduInOrder during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"DataPDUInOrder=Yes"; + strncpy(str,"DataPDUInOrder=Yes",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -404,14 +372,14 @@ iscsi_login_add_datapduinorder(struct iscsi_context *iscsi, struct iscsi_pdu *pd static int iscsi_login_add_defaulttime2wait(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send DefaultTime2Wait during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"DefaultTime2Wait=2"; + strncpy(str,"DefaultTime2Wait=2",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -424,14 +392,14 @@ iscsi_login_add_defaulttime2wait(struct iscsi_context *iscsi, struct iscsi_pdu * static int iscsi_login_add_defaulttime2retain(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send DefaultTime2Retain during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"DefaultTime2Retain=0"; + strncpy(str,"DefaultTime2Retain=0",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -444,14 +412,14 @@ iscsi_login_add_defaulttime2retain(struct iscsi_context *iscsi, struct iscsi_pdu static int iscsi_login_add_ifmarker(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send IFMarker during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"IFMarker=No"; + strncpy(str,"IFMarker=No",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -464,14 +432,14 @@ iscsi_login_add_ifmarker(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_ofmarker(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send OFMarker during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"OFMarker=No"; + strncpy(str,"OFMarker=No",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -484,14 +452,14 @@ iscsi_login_add_ofmarker(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_maxconnections(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send MaxConnections during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"MaxConnections=1"; + strncpy(str,"MaxConnections=1",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -504,14 +472,14 @@ iscsi_login_add_maxconnections(struct iscsi_context *iscsi, struct iscsi_pdu *pd static int iscsi_login_add_maxoutstandingr2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send MaxOutstandingR2T during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"MaxOutstandingR2T=1"; + strncpy(str,"MaxOutstandingR2T=1",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -524,14 +492,14 @@ iscsi_login_add_maxoutstandingr2t(struct iscsi_context *iscsi, struct iscsi_pdu static int iscsi_login_add_errorrecoverylevel(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send ErrorRecoveryLevel during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"ErrorRecoveryLevel=0"; + strncpy(str,"ErrorRecoveryLevel=0",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -544,14 +512,14 @@ iscsi_login_add_errorrecoverylevel(struct iscsi_context *iscsi, struct iscsi_pdu static int iscsi_login_add_datasequenceinorder(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; /* We only send DataSequenceInOrder during opneg */ if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_OPNEG) { return 0; } - str = (char *)"DataSequenceInOrder=Yes"; + strncpy(str,"DataSequenceInOrder=Yes",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -564,14 +532,14 @@ iscsi_login_add_datasequenceinorder(struct iscsi_context *iscsi, struct iscsi_pd static int iscsi_login_add_authmethod(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG || iscsi->secneg_phase != ISCSI_LOGIN_SECNEG_PHASE_OFFER_CHAP) { return 0; } - str = (char *)"AuthMethod=CHAP,None"; + strncpy(str,"AuthMethod=CHAP,None",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -584,14 +552,14 @@ iscsi_login_add_authmethod(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int iscsi_login_add_authalgorithm(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG || iscsi->secneg_phase != ISCSI_LOGIN_SECNEG_PHASE_SELECT_ALGORITHM) { return 0; } - str = (char *)"CHAP_A=5"; + strncpy(str,"CHAP_A=5",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -604,14 +572,14 @@ iscsi_login_add_authalgorithm(struct iscsi_context *iscsi, struct iscsi_pdu *pdu static int iscsi_login_add_chap_username(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG || iscsi->secneg_phase != ISCSI_LOGIN_SECNEG_PHASE_SEND_RESPONSE) { return 0; } - str = (char *)"CHAP_N="; + strncpy(str,"CHAP_N=",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); @@ -652,7 +620,8 @@ i2h(int i) static int iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; + char str[MAX_STRING_SIZE+1]; + char * strp; unsigned char c, cc[2]; unsigned char digest[16]; struct MD5Context ctx; @@ -671,15 +640,16 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu c = iscsi->chap_i; MD5Update(&ctx, &c, 1); MD5Update(&ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd)); - str = iscsi->chap_c; - while (*str != 0) { - c = (h2i(str[0]) << 4) | h2i(str[1]); - str += 2; + + strp = iscsi->chap_c; + while (*strp != 0) { + c = (h2i(strp[0]) << 4) | h2i(strp[1]); + strp += 2; MD5Update(&ctx, &c, 1); } MD5Final(digest, &ctx); - str = (char *)"CHAP_R=0x"; + strncpy(str,"CHAP_R=0x",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)) != 0) { iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed."); From 1ba60282bf6ffea3e0fab7b36bd87e02d9300e17 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 5 Nov 2012 21:23:30 +0100 Subject: [PATCH 18/27] LD_ISCSI invalidate get_lba_status cache on write --- src/ld_iscsi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ld_iscsi.c b/src/ld_iscsi.c index f9271a6..144769b 100644 --- a/src/ld_iscsi.c +++ b/src/ld_iscsi.c @@ -455,6 +455,8 @@ ssize_t write(int fd, const void *buf, size_t count) return -1; } + iscsi_fd_list[fd].lbasd_cache_valid = 0; + offset = iscsi_fd_list[fd].offset; num_blocks = count/iscsi_fd_list[fd].block_size; lba = offset / iscsi_fd_list[fd].block_size; From 0d8819e68f7d05bf2b1937c79fb656f8067b0ade Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 6 Nov 2012 08:53:38 +0100 Subject: [PATCH 19/27] INIT allow iscsi_context = NULL in iscsi_set_error() qemu-kvm calls iscsi_parse_url_full() with iscsi = NULL. In case there is an invalid URL specified qemu-kvm segfaults when it tries to set iscsi->error_string. I tried to patch this in qemu-kvm, but the initiator_name is dirived from the target name so this seemed to be the easier approach. --- lib/init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/init.c b/lib/init.c index cf51500..2fdc3c2 100644 --- a/lib/init.c +++ b/lib/init.c @@ -293,8 +293,13 @@ iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, ...) } va_end(ap); - strncpy(iscsi->error_string,errstr,MAX_STRING_SIZE); - DPRINTF(iscsi,1,"%s",iscsi->error_string); + if (iscsi != NULL) { + strncpy(iscsi->error_string,errstr,MAX_STRING_SIZE); + DPRINTF(iscsi,1,"%s",iscsi->error_string); + } + else { + fprintf(stderr,"libiscsi: %s\n", errstr); + } } void From 6cad82532a2718161eb2cb1a822150c0bb155bec Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 6 Nov 2012 14:53:55 +0100 Subject: [PATCH 20/27] SOCKET add option to bind to connection to interface(s) --- include/iscsi-private.h | 2 ++ include/iscsi.h | 7 +++++++ lib/init.c | 4 ++++ lib/libiscsi.def | 1 + lib/libiscsi.syms | 1 + lib/socket.c | 42 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 8d209b9..c16d672 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -68,6 +68,7 @@ struct iscsi_context { char connected_portal[MAX_STRING_SIZE+1]; char portal[MAX_STRING_SIZE+1]; char alias[MAX_STRING_SIZE+1]; + char bind_interfaces[MAX_STRING_SIZE+1]; char user[MAX_STRING_SIZE+1]; char passwd[MAX_STRING_SIZE+1]; @@ -102,6 +103,7 @@ struct iscsi_context { int login_attempts; int is_loggedin; int is_reconnecting; + int bind_interface_cnt; int chap_a; int chap_i; diff --git a/include/iscsi.h b/include/iscsi.h index 6ac7f0e..fde65c8 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1028,6 +1028,13 @@ iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value); EXTERN void iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value); +/* + * This function is to set the interface that outbound connections for this socket are bound to. + * You max specify more than one interface here separated by comma. + */ +EXTERN void +iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces); + #ifdef __cplusplus } #endif diff --git a/lib/init.c b/lib/init.c index 2fdc3c2..2540779 100644 --- a/lib/init.c +++ b/lib/init.c @@ -134,6 +134,10 @@ iscsi_create_context(const char *initiator_name) iscsi_set_tcp_syncnt(iscsi,atoi(getenv("LIBISCSI_TCP_SYNCNT"))); } + if (getenv("LIBISCSI_BIND_INTERFACES") != NULL) { + iscsi_set_bind_interfaces(iscsi,getenv("LIBISCSI_BIND_INTERFACES")); + } + return iscsi; } diff --git a/lib/libiscsi.def b/lib/libiscsi.def index c3a915c..95f4552 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -79,6 +79,7 @@ iscsi_set_tcp_keepidle iscsi_set_tcp_keepcnt iscsi_set_tcp_keepintvl iscsi_set_tcp_syncnt +iscsi_set_bind_interface iscsi_startstopunit_sync iscsi_startstopunit_task iscsi_synchronizecache10_sync diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index ddf3e1a..4eaeb67 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -77,6 +77,7 @@ iscsi_set_tcp_keepidle iscsi_set_tcp_keepcnt iscsi_set_tcp_keepintvl iscsi_set_tcp_syncnt +iscsi_set_bind_interface iscsi_startstopunit_sync iscsi_startstopunit_task iscsi_synchronizecache10_sync diff --git a/lib/socket.c b/lib/socket.c index 0566dc9..84b427e 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -216,6 +216,30 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, set_tcp_syncnt(iscsi); } +#if __linux + if (iscsi->bind_interfaces[0]) { + char *pchr = iscsi->bind_interfaces, *pchr2; + int iface_n = rand()%iscsi->bind_interface_cnt; + int iface_c = 0; + do { + pchr2 = strchr(pchr,','); + if (iface_c == iface_n) { + if (pchr2) pchr2[0]=0x00; + break; + } + if (pchr2) {pchr=pchr2+1;} + } while (pchr2); + + int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr)); + if (res < 0) { + DPRINTF(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno)); + } else { + DPRINTF(iscsi,3,"successfully bound to interface '%s'",pchr); + } + if (pchr2) pchr2[0]=','; + } +#endif + if (connect(iscsi->fd, ai->ai_addr, socksize) != 0 && errno != EINPROGRESS) { iscsi_set_error(iscsi, "Connect failed with errno : " @@ -647,3 +671,21 @@ int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, in return 0; } + +void iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces) +{ +#if __linux + strncpy(iscsi->bind_interfaces,interfaces,MAX_STRING_SIZE); + iscsi->bind_interface_cnt=0; + char * pchr = interfaces; + char * pchr2 = NULL; + do { + pchr2 = strchr(pchr,','); + if (pchr2) {pchr=pchr2+1;} + iscsi->bind_interface_cnt++; + } while (pchr2); + DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interface_cnt,interfaces); +#else + DPRINTF(iscsi,1,"binding to an interface is not supported on your OS"); +#endif +} From f00cd048105f64102e28653f01c08aa0148e653f Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 6 Nov 2012 15:01:34 +0100 Subject: [PATCH 21/27] INIT call srand() once at iscsi_create_context() currently the rng is not seeded at all which makes the isid not really random at all. --- lib/init.c | 2 ++ lib/socket.c | 1 + 2 files changed, 3 insertions(+) diff --git a/lib/init.c b/lib/init.c index 2540779..143cf9b 100644 --- a/lib/init.c +++ b/lib/init.c @@ -88,6 +88,8 @@ iscsi_create_context(const char *initiator_name) iscsi->fd = -1; + srand(time(NULL) ^ getpid() ^ (u_int32_t) iscsi); + /* initialize to a "random" isid */ iscsi_set_isid_random(iscsi, rand(), 0); diff --git a/lib/socket.c b/lib/socket.c index 84b427e..7d1f014 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -228,6 +228,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, break; } if (pchr2) {pchr=pchr2+1;} + iface_c++; } while (pchr2); int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr)); From 3e57a612db965337bf7947d2108badfe7dbef0b4 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 6 Nov 2012 15:47:30 +0100 Subject: [PATCH 22/27] SOCKET add more skill to interface binding If a process opens more than once connection the interfaces are assigned round-robin from the available ones. However, different processes will uses a random interface of as starting point. This patch will also make the redirect case handled correctly. --- include/iscsi-private.h | 4 +++- lib/connect.c | 4 ++++ lib/socket.c | 15 +++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index c16d672..5655d9e 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -103,7 +103,7 @@ struct iscsi_context { int login_attempts; int is_loggedin; int is_reconnecting; - int bind_interface_cnt; + int bind_interfaces_cnt; int chap_a; int chap_i; @@ -304,6 +304,8 @@ struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu); void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state); +void iscsi_decrement_iface_rr(); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index 32b3316..76000be 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -91,6 +91,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) { iscsi_disconnect(iscsi); + if (iscsi->bind_interfaces[0]) iscsi_decrement_iface_rr(); if (iscsi_connect_async(iscsi, iscsi->target_address, iscsi_connect_cb, iscsi->connect_data) != 0) { iscsi_free(iscsi, ct); return; @@ -238,6 +239,9 @@ try_again: strncpy(iscsi->portal,old_iscsi->portal,MAX_STRING_SIZE); + strncpy(iscsi->bind_interfaces,old_iscsi->bind_interfaces,MAX_STRING_SIZE); + iscsi->bind_interfaces_cnt = old_iscsi->bind_interfaces_cnt; + iscsi->debug = old_iscsi->debug; iscsi->tcp_user_timeout = old_iscsi->tcp_user_timeout; diff --git a/lib/socket.c b/lib/socket.c index 7d1f014..a611d8e 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -46,6 +46,12 @@ #include "iscsi-private.h" #include "slist.h" +static uint32_t iface_rr = 0; + +void iscsi_decrement_iface_rr() { + iface_rr--; +} + static void set_nonblocking(int fd) { #if defined(WIN32) @@ -219,7 +225,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, #if __linux if (iscsi->bind_interfaces[0]) { char *pchr = iscsi->bind_interfaces, *pchr2; - int iface_n = rand()%iscsi->bind_interface_cnt; + int iface_n = iface_rr++%iscsi->bind_interfaces_cnt; int iface_c = 0; do { pchr2 = strchr(pchr,','); @@ -677,15 +683,16 @@ void iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces) { #if __linux strncpy(iscsi->bind_interfaces,interfaces,MAX_STRING_SIZE); - iscsi->bind_interface_cnt=0; + iscsi->bind_interfaces_cnt=0; char * pchr = interfaces; char * pchr2 = NULL; do { pchr2 = strchr(pchr,','); if (pchr2) {pchr=pchr2+1;} - iscsi->bind_interface_cnt++; + iscsi->bind_interfaces_cnt++; } while (pchr2); - DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interface_cnt,interfaces); + DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interfaces_cnt,interfaces); + if (!iface_rr) iface_rr=rand()%iscsi->bind_interfaces_cnt+1; #else DPRINTF(iscsi,1,"binding to an interface is not supported on your OS"); #endif From ec46d6fa43e33d3cc943fc28d09045a006eb4bac Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 6 Nov 2012 16:07:43 +0100 Subject: [PATCH 23/27] DEBUG add function to set debug fd DPRINTF was blindly sending all debug output to fd 2 (stderr). The new function iscsi_set_debug_fd() will set the debug fd. In general debugging is completely disabled by default. --- include/iscsi-private.h | 3 ++- include/iscsi.h | 14 ++++++++++---- lib/init.c | 12 ++++++++++++ lib/libiscsi.def | 1 + lib/libiscsi.syms | 1 + 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 5655d9e..1250dec 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -130,6 +130,7 @@ struct iscsi_context { int no_auto_reconnect; int reconnect_deferred; int debug; + int debug_fd; int mallocs; int reallocs; int frees; @@ -304,7 +305,7 @@ struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu); void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state); -void iscsi_decrement_iface_rr(); +void iscsi_decrement_iface_rr(void); #ifdef __cplusplus } diff --git a/include/iscsi.h b/include/iscsi.h index fde65c8..d8c67f2 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -971,12 +971,12 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); #define DPRINTF(iscsi,level,fmt,args...) \ do { \ if ((iscsi)->debug >= level) { \ - fprintf(stderr,"libiscsi: "); \ - fprintf(stderr, (fmt), ##args); \ + dprintf((iscsi)->debug_fd,"libiscsi: "); \ + dprintf((iscsi)->debug_fd, (fmt), ##args); \ if (iscsi->target_name[0]) { \ - fprintf(stderr," [%s]",iscsi->target_name); \ + dprintf((iscsi)->debug_fd," [%s]",iscsi->target_name); \ } \ - fprintf(stderr,"\n"); \ + dprintf((iscsi)->debug_fd,"\n"); \ } \ } while (0); @@ -993,6 +993,12 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); EXTERN void iscsi_set_debug(struct iscsi_context *iscsi, int level); +/* + * This function is to set fd where debugging info is sent to. default is stderr (2) + */ +EXTERN void +iscsi_set_debug_fd(struct iscsi_context *iscsi, int fd); + /* * This function is to set the TCP_USER_TIMEOUT option. It has to be called after iscsi * context creation. The value given in ms is then applied each time a new socket is created. diff --git a/lib/init.c b/lib/init.c index 143cf9b..1464916 100644 --- a/lib/init.c +++ b/lib/init.c @@ -87,6 +87,7 @@ iscsi_create_context(const char *initiator_name) strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE); iscsi->fd = -1; + iscsi->debug_fd = 2; srand(time(NULL) ^ getpid() ^ (u_int32_t) iscsi); @@ -112,6 +113,10 @@ iscsi_create_context(const char *initiator_name) iscsi->tcp_keepintvl=30; iscsi->tcp_keepidle=30; + if (getenv("LIBISCSI_DEBUG_FD") != NULL) { + iscsi_set_debug_fd(iscsi,atoi(getenv("LIBISCSI_DEBUG_FD"))); + } + if (getenv("LIBISCSI_DEBUG") != NULL) { iscsi_set_debug(iscsi,atoi(getenv("LIBISCSI_DEBUG"))); } @@ -315,6 +320,13 @@ iscsi_set_debug(struct iscsi_context *iscsi, int level) DPRINTF(iscsi,2,"set debug level to %d",level); } +void +iscsi_set_debug_fd(struct iscsi_context *iscsi, int fd) +{ + iscsi->debug_fd = fd; + DPRINTF(iscsi,2,"set debug fd to %d",fd); +} + const char * iscsi_get_error(struct iscsi_context *iscsi) { diff --git a/lib/libiscsi.def b/lib/libiscsi.def index 95f4552..3f38d87 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -65,6 +65,7 @@ iscsi_scsi_task_cancel iscsi_service iscsi_set_alias iscsi_set_debug +iscsi_set_debug_fd iscsi_set_header_digest iscsi_set_initiator_username_pwd iscsi_set_isid_en diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index 4eaeb67..5129d9c 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -63,6 +63,7 @@ iscsi_scsi_task_cancel iscsi_service iscsi_set_alias iscsi_set_debug +iscsi_set_debug_fd iscsi_set_header_digest iscsi_set_initiator_username_pwd iscsi_set_isid_en From a97b51bbe5a61101bb9bc0a2f940c6e5a7e8cac1 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Wed, 7 Nov 2012 06:45:54 +0100 Subject: [PATCH 24/27] Revert "DEBUG add function to set debug fd" We will have a completely different debugging framework soon. This reverts commit ec46d6fa43e33d3cc943fc28d09045a006eb4bac. --- include/iscsi-private.h | 3 +-- include/iscsi.h | 14 ++++---------- lib/init.c | 12 ------------ lib/libiscsi.def | 1 - lib/libiscsi.syms | 1 - 5 files changed, 5 insertions(+), 26 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 1250dec..5655d9e 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -130,7 +130,6 @@ struct iscsi_context { int no_auto_reconnect; int reconnect_deferred; int debug; - int debug_fd; int mallocs; int reallocs; int frees; @@ -305,7 +304,7 @@ struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu); void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state); -void iscsi_decrement_iface_rr(void); +void iscsi_decrement_iface_rr(); #ifdef __cplusplus } diff --git a/include/iscsi.h b/include/iscsi.h index d8c67f2..fde65c8 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -971,12 +971,12 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); #define DPRINTF(iscsi,level,fmt,args...) \ do { \ if ((iscsi)->debug >= level) { \ - dprintf((iscsi)->debug_fd,"libiscsi: "); \ - dprintf((iscsi)->debug_fd, (fmt), ##args); \ + fprintf(stderr,"libiscsi: "); \ + fprintf(stderr, (fmt), ##args); \ if (iscsi->target_name[0]) { \ - dprintf((iscsi)->debug_fd," [%s]",iscsi->target_name); \ + fprintf(stderr," [%s]",iscsi->target_name); \ } \ - dprintf((iscsi)->debug_fd,"\n"); \ + fprintf(stderr,"\n"); \ } \ } while (0); @@ -993,12 +993,6 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); EXTERN void iscsi_set_debug(struct iscsi_context *iscsi, int level); -/* - * This function is to set fd where debugging info is sent to. default is stderr (2) - */ -EXTERN void -iscsi_set_debug_fd(struct iscsi_context *iscsi, int fd); - /* * This function is to set the TCP_USER_TIMEOUT option. It has to be called after iscsi * context creation. The value given in ms is then applied each time a new socket is created. diff --git a/lib/init.c b/lib/init.c index 1464916..143cf9b 100644 --- a/lib/init.c +++ b/lib/init.c @@ -87,7 +87,6 @@ iscsi_create_context(const char *initiator_name) strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE); iscsi->fd = -1; - iscsi->debug_fd = 2; srand(time(NULL) ^ getpid() ^ (u_int32_t) iscsi); @@ -113,10 +112,6 @@ iscsi_create_context(const char *initiator_name) iscsi->tcp_keepintvl=30; iscsi->tcp_keepidle=30; - if (getenv("LIBISCSI_DEBUG_FD") != NULL) { - iscsi_set_debug_fd(iscsi,atoi(getenv("LIBISCSI_DEBUG_FD"))); - } - if (getenv("LIBISCSI_DEBUG") != NULL) { iscsi_set_debug(iscsi,atoi(getenv("LIBISCSI_DEBUG"))); } @@ -320,13 +315,6 @@ iscsi_set_debug(struct iscsi_context *iscsi, int level) DPRINTF(iscsi,2,"set debug level to %d",level); } -void -iscsi_set_debug_fd(struct iscsi_context *iscsi, int fd) -{ - iscsi->debug_fd = fd; - DPRINTF(iscsi,2,"set debug fd to %d",fd); -} - const char * iscsi_get_error(struct iscsi_context *iscsi) { diff --git a/lib/libiscsi.def b/lib/libiscsi.def index 3f38d87..95f4552 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -65,7 +65,6 @@ iscsi_scsi_task_cancel iscsi_service iscsi_set_alias iscsi_set_debug -iscsi_set_debug_fd iscsi_set_header_digest iscsi_set_initiator_username_pwd iscsi_set_isid_en diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index 5129d9c..4eaeb67 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -63,7 +63,6 @@ iscsi_scsi_task_cancel iscsi_service iscsi_set_alias iscsi_set_debug -iscsi_set_debug_fd iscsi_set_header_digest iscsi_set_initiator_username_pwd iscsi_set_isid_en From 144026a7bdcd4ab2aef79e06fd21ba2119095c55 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Thu, 8 Nov 2012 16:56:44 +0100 Subject: [PATCH 25/27] RECONNECT allow a consecutive reconnect only every 5 seconds In case there is an error condition e.g. out of memory. We are heavily disconnecting and reconnecting without any limit. This patch adds a 5 seconds period that has to go by between 2 reconnects. --- include/iscsi-private.h | 5 ++++- lib/connect.c | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 5655d9e..99bec11 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -18,6 +18,7 @@ #define __iscsi_private_h__ #include +#include #if defined(WIN32) #include @@ -133,6 +134,8 @@ struct iscsi_context { int mallocs; int reallocs; int frees; + + time_t last_reconnect; }; #define ISCSI_PDU_IMMEDIATE 0x40 @@ -304,7 +307,7 @@ struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu); void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state); -void iscsi_decrement_iface_rr(); +void iscsi_decrement_iface_rr(void); #ifdef __cplusplus } diff --git a/lib/connect.c b/lib/connect.c index 76000be..e88a4d6 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -220,6 +220,10 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) int retry = 0; + if (old_iscsi->last_reconnect) { + while (time(NULL) - old_iscsi->last_reconnect < 5) sleep(1); + } + try_again: iscsi = iscsi_create_context(old_iscsi->initiator_name); @@ -339,6 +343,7 @@ try_again: free(iscsi); old_iscsi->is_reconnecting = 0; + old_iscsi->last_reconnect = time(NULL); return 0; } From 5e1d0112705d980c23e834a1ae4362cf0679e152 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 12 Nov 2012 15:43:29 +0100 Subject: [PATCH 26/27] SCSI-LOWLEVEL revert changes to scsi-lowlevel The memory tracking code reports memory allocated by iscsi_allocate_pdu_with_itt_flags_size() as lost. This memory is allocated by the iscsi part of libiscsi, but later freed by the lowlevel scsi part. We will fix this later by introducing an iscsi_task object. --- include/iscsi.h | 4 +- include/scsi-lowlevel.h | 90 ++++++------ lib/libiscsi.def | 2 +- lib/libiscsi.syms | 2 +- lib/scsi-command.c | 144 ++++++++++++------- lib/scsi-lowlevel.c | 296 ++++++++++++++++------------------------ lib/task_mgmt.c | 2 +- 7 files changed, 264 insertions(+), 276 deletions(-) diff --git a/include/iscsi.h b/include/iscsi.h index fde65c8..461a758 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -955,8 +955,8 @@ EXTERN int scsi_task_add_data_in_buffer(struct scsi_task *task, int len, unsigne * To cancel the task also a the target you need to call the task management functions. */ EXTERN int -iscsi_scsi_task_cancel(struct iscsi_context *iscsi, - struct scsi_task *task); +iscsi_scsi_cancel_task(struct iscsi_context *iscsi, + struct scsi_task *task); /* * This function is used when you want to cancel all scsi tasks. diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h index 0f7face..38787c1 100644 --- a/include/scsi-lowlevel.h +++ b/include/scsi-lowlevel.h @@ -17,6 +17,12 @@ #ifndef __scsi_lowlevel_h__ #define __scsi_lowlevel_h__ +#if defined(WIN32) +#define EXTERN __declspec( dllexport ) +#else +#define EXTERN +#endif + #ifdef __cplusplus extern "C" { #endif @@ -123,7 +129,7 @@ enum scsi_xfer_dir { /* * READTOC */ -EXTERN struct scsi_task *scsi_cdb_readtoc(struct iscsi_context *iscsi, int msf, int format, int track_session, uint16_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len); enum scsi_readtoc_fmt { SCSI_READ_TOC = 0, @@ -299,11 +305,6 @@ struct scsi_data { unsigned char *data; }; -struct scsi_allocated_memory { - struct scsi_allocated_memory *next; - void *ptr; -}; - enum scsi_residual { SCSI_RESIDUAL_NO_RESIDUAL = 0, SCSI_RESIDUAL_UNDERFLOW, @@ -312,10 +313,10 @@ enum scsi_residual { struct scsi_task { int status; + int cdb_size; int xfer_dir; int expxferlen; - struct iscsi_context * iscsi; unsigned char cdb[SCSI_CDB_MAX_SIZE]; union { struct scsi_read6_params read6; @@ -361,7 +362,7 @@ struct scsi_task { /* This function will free a scsi task structure. You may NOT cancel a task until the callback has been invoked - and the command has completed on the iscsi layer. + and the command has completed on the transport layer. */ EXTERN void scsi_free_scsi_task(struct scsi_task *task); @@ -371,7 +372,8 @@ EXTERN void *scsi_get_task_private_ptr(struct scsi_task *task); /* * TESTUNITREADY */ -EXTERN struct scsi_task *scsi_cdb_testunitready(struct iscsi_context *iscsi); +EXTERN struct scsi_task *scsi_cdb_testunitready(void); + /* * REPORTLUNS @@ -385,16 +387,16 @@ struct scsi_reportluns_list { uint16_t luns[0]; }; -EXTERN struct scsi_task *scsi_reportluns_cdb(struct iscsi_context *iscsi, int report_type, int alloc_len); +EXTERN struct scsi_task *scsi_reportluns_cdb(int report_type, int alloc_len); /* * RESERVE6 */ -EXTERN struct scsi_task *scsi_cdb_reserve6(struct iscsi_context *iscsi); +EXTERN struct scsi_task *scsi_cdb_reserve6(void); /* * RELEASE6 */ -EXTERN struct scsi_task *scsi_cdb_release6(struct iscsi_context *iscsi); +EXTERN struct scsi_task *scsi_cdb_release6(void); /* * READCAPACITY10 @@ -403,7 +405,7 @@ struct scsi_readcapacity10 { uint32_t lba; uint32_t block_size; }; -EXTERN struct scsi_task *scsi_cdb_readcapacity10(struct iscsi_context *iscsi, int lba, int pmi); +EXTERN struct scsi_task *scsi_cdb_readcapacity10(int lba, int pmi); /* @@ -563,7 +565,7 @@ struct scsi_inquiry_logical_block_provisioning { enum scsi_inquiry_provisioning_type provisioning_type; }; -EXTERN struct scsi_task *scsi_cdb_inquiry(struct iscsi_context *iscsi, int evpd, int page_code, int alloc_len); +EXTERN struct scsi_task *scsi_cdb_inquiry(int evpd, int page_code, int alloc_len); struct scsi_inquiry_unit_serial_number { enum scsi_inquiry_peripheral_qualifier qualifier; @@ -733,8 +735,7 @@ struct scsi_mode_sense { struct scsi_mode_page *pages; }; -EXTERN struct scsi_task *scsi_cdb_modesense6(struct iscsi_context *iscsi, - int dbd, +EXTERN struct scsi_task *scsi_cdb_modesense6(int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, @@ -799,37 +800,37 @@ struct scsi_report_supported_op_codes { EXTERN int scsi_datain_getfullsize(struct scsi_task *task); EXTERN void *scsi_datain_unmarshall(struct scsi_task *task); -EXTERN struct scsi_task *scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize); -EXTERN struct scsi_task *scsi_cdb_read10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_read12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_read16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_write16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_startstopunit(struct iscsi_context *iscsi, int immed, int pcm, int pc, int no_flush, int loej, int start); -EXTERN struct scsi_task *scsi_cdb_preventallow(struct iscsi_context *iscsi, int prevent); -EXTERN struct scsi_task *scsi_cdb_orwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_compareandwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_writeverify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); -EXTERN struct scsi_task *scsi_cdb_verify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_verify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_verify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize); +EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int start); +EXTERN struct scsi_task *scsi_cdb_preventallow(int prevent); +EXTERN struct scsi_task *scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_writeverify16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number); +EXTERN struct scsi_task *scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); +EXTERN struct scsi_task *scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize); -EXTERN struct scsi_task *scsi_cdb_synchronizecache10(struct iscsi_context *iscsi, int lba, int num_blocks, +EXTERN struct scsi_task *scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed); -EXTERN struct scsi_task *scsi_cdb_synchronizecache16(struct iscsi_context *iscsi, uint64_t lba, uint32_t num_blocks, +EXTERN struct scsi_task *scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, int syncnv, int immed); -EXTERN struct scsi_task *scsi_cdb_serviceactionin16(struct iscsi_context *iscsi, enum scsi_service_action_in sa, uint32_t xferlen); -EXTERN struct scsi_task *scsi_cdb_readcapacity16(struct iscsi_context *iscsi); -EXTERN struct scsi_task *scsi_cdb_get_lba_status(struct iscsi_context *iscsi, uint64_t starting_lba, uint32_t alloc_len); -EXTERN struct scsi_task *scsi_cdb_unmap(struct iscsi_context *iscsi, int anchor, int group, uint16_t xferlen); -EXTERN struct scsi_task *scsi_cdb_writesame10(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks); -EXTERN struct scsi_task *scsi_cdb_writesame16(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks); -EXTERN struct scsi_task *scsi_cdb_prefetch10(struct iscsi_context *iscsi, uint32_t lba, int num_blocks, int immed, int group); -EXTERN struct scsi_task *scsi_cdb_prefetch16(struct iscsi_context *iscsi, uint64_t lba, int num_blocks, int immed, int group); -EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(struct iscsi_context *iscsi, int report_timeouts, uint32_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen); +EXTERN struct scsi_task *scsi_cdb_readcapacity16(void); +EXTERN struct scsi_task *scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len); +EXTERN struct scsi_task *scsi_cdb_unmap(int anchor, int group, uint16_t xferlen); +EXTERN struct scsi_task *scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks); +EXTERN struct scsi_task *scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks); +EXTERN struct scsi_task *scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group); +EXTERN struct scsi_task *scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group); +EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(int report_timeouts, uint32_t alloc_len); void *scsi_malloc(struct scsi_task *task, size_t size); @@ -838,4 +839,3 @@ void *scsi_malloc(struct scsi_task *task, size_t size); #endif #endif /* __scsi_lowlevel_h__ */ - diff --git a/lib/libiscsi.def b/lib/libiscsi.def index 95f4552..d8f6f5a 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -61,7 +61,7 @@ iscsi_reportluns_task iscsi_scsi_cancel_all_tasks iscsi_scsi_command_async iscsi_scsi_command_sync -iscsi_scsi_task_cancel +iscsi_scsi_cancel_task iscsi_service iscsi_set_alias iscsi_set_debug diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index 4eaeb67..78a5cf8 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -59,7 +59,7 @@ iscsi_reportluns_task iscsi_scsi_cancel_all_tasks iscsi_scsi_command_async iscsi_scsi_command_sync -iscsi_scsi_task_cancel +iscsi_scsi_cancel_task iscsi_service iscsi_set_alias iscsi_set_debug diff --git a/lib/scsi-command.c b/lib/scsi-command.c index 57c50d3..fbbd016 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -85,11 +85,10 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu, len = iscsi->target_max_recv_data_segment_length; } - pdu = iscsi_allocate_pdu_with_itt_flags_size(iscsi, ISCSI_PDU_DATA_OUT, + pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT, ISCSI_PDU_NO_PDU, cmd_pdu->itt, - ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK, - len); + ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi data out pdu."); @@ -193,22 +192,15 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, "scsi cbdata."); return -1; } + scsi_cbdata->task = task; scsi_cbdata->callback = cb; scsi_cbdata->private_data = private_data; scsi_set_task_private_ptr(task, scsi_cbdata); - u_int32_t payload_size = 0; - if (iscsi->use_immediate_data == ISCSI_IMMEDIATE_DATA_YES) { - payload_size=data.size; - if (payload_size > iscsi->first_burst_length) { - payload_size = iscsi->first_burst_length; - } - } - - pdu = iscsi_allocate_pdu_size(iscsi, ISCSI_PDU_SCSI_REQUEST, - ISCSI_PDU_SCSI_RESPONSE, payload_size); + pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_SCSI_REQUEST, + ISCSI_PDU_SCSI_RESPONSE); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi pdu."); @@ -392,7 +384,7 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, break; case SCSI_STATUS_CHECK_CONDITION: task->datain.size = in->data_pos; - task->datain.data = iscsi_malloc(iscsi, task->datain.size); + task->datain.data = malloc(task->datain.size); if (task->datain.data == NULL) { iscsi_set_error(iscsi, "failed to allocate blob for " "sense data"); @@ -541,7 +533,7 @@ iscsi_testunitready_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_testunitready(iscsi); + task = scsi_cdb_testunitready(); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "testunitready cdb."); @@ -569,7 +561,7 @@ iscsi_reportluns_task(struct iscsi_context *iscsi, int report_type, return NULL; } - task = scsi_reportluns_cdb(iscsi, report_type, alloc_len); + task = scsi_reportluns_cdb(report_type, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "reportluns cdb."); @@ -592,7 +584,7 @@ iscsi_inquiry_task(struct iscsi_context *iscsi, int lun, int evpd, { struct scsi_task *task; - task = scsi_cdb_inquiry(iscsi, evpd, page_code, maxsize); + task = scsi_cdb_inquiry(evpd, page_code, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "inquiry cdb."); @@ -613,7 +605,7 @@ iscsi_readcapacity10_task(struct iscsi_context *iscsi, int lun, int lba, { struct scsi_task *task; - task = scsi_cdb_readcapacity10(iscsi, lba, pmi); + task = scsi_cdb_readcapacity10(lba, pmi); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "readcapacity10 cdb."); @@ -634,7 +626,7 @@ iscsi_readcapacity16_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_readcapacity16(iscsi); + task = scsi_cdb_readcapacity16(); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "readcapacity16 cdb."); @@ -656,7 +648,7 @@ iscsi_get_lba_status_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_get_lba_status(iscsi, starting_lba, alloc_len); + task = scsi_cdb_get_lba_status(starting_lba, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "get-lba-status cdb."); @@ -684,7 +676,7 @@ iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read6(iscsi, lba, datalen, blocksize); + task = scsi_cdb_read6(lba, datalen, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "read6 cdb."); @@ -713,7 +705,7 @@ iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read10(iscsi, lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read10(lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -743,7 +735,7 @@ iscsi_read12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_read12(iscsi, lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read12(lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -773,7 +765,7 @@ iscsi_read16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_read16(iscsi, lba, datalen, blocksize, rdprotect, + task = scsi_cdb_read16(lba, datalen, blocksize, rdprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -804,7 +796,7 @@ iscsi_write10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_write10(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write10(lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -839,7 +831,7 @@ iscsi_write12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_write12(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write12(lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -874,7 +866,7 @@ iscsi_write16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_write16(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_write16(lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -909,7 +901,7 @@ iscsi_orwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_orwrite(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_orwrite(lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -944,7 +936,7 @@ iscsi_compareandwrite_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_compareandwrite(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_compareandwrite(lba, datalen, blocksize, wrprotect, dpo, fua, fua_nv, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -979,7 +971,7 @@ iscsi_writeverify10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_writeverify10(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify10(lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1014,7 +1006,7 @@ iscsi_writeverify12_task(struct iscsi_context *iscsi, int lun, uint32_t lba, return NULL; } - task = scsi_cdb_writeverify12(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify12(lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1049,7 +1041,7 @@ iscsi_writeverify16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, return NULL; } - task = scsi_cdb_writeverify16(iscsi, lba, datalen, blocksize, wrprotect, + task = scsi_cdb_writeverify16(lba, datalen, blocksize, wrprotect, dpo, bytchk, group_number); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1083,7 +1075,7 @@ iscsi_verify10_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify10(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify10(lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify10 cdb."); @@ -1116,7 +1108,7 @@ iscsi_verify12_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify12(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify12(lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify12 cdb."); @@ -1149,7 +1141,7 @@ iscsi_verify16_task(struct iscsi_context *iscsi, int lun, unsigned char *data, return NULL; } - task = scsi_cdb_verify16(iscsi, lba, datalen, vprotect, dpo, bytchk, blocksize); + task = scsi_cdb_verify16(lba, datalen, vprotect, dpo, bytchk, blocksize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "verify16 cdb."); @@ -1176,7 +1168,7 @@ iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc, { struct scsi_task *task; - task = scsi_cdb_modesense6(iscsi, dbd, pc, page_code, sub_page_code, + task = scsi_cdb_modesense6(dbd, pc, page_code, sub_page_code, alloc_len); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1200,7 +1192,7 @@ iscsi_startstopunit_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_startstopunit(iscsi, immed, pcm, pc, no_flush, + task = scsi_cdb_startstopunit(immed, pcm, pc, no_flush, loej, start); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1223,7 +1215,7 @@ iscsi_preventallow_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_preventallow(iscsi, prevent); + task = scsi_cdb_preventallow(prevent); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "PreventAllowMediumRemoval cdb."); @@ -1245,7 +1237,7 @@ iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun, int lba, { struct scsi_task *task; - task = scsi_cdb_synchronizecache10(iscsi, lba, num_blocks, syncnv, + task = scsi_cdb_synchronizecache10(lba, num_blocks, syncnv, immed); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1268,7 +1260,7 @@ iscsi_synchronizecache16_task(struct iscsi_context *iscsi, int lun, uint64_t lba { struct scsi_task *task; - task = scsi_cdb_synchronizecache16(iscsi, lba, num_blocks, syncnv, + task = scsi_cdb_synchronizecache16(lba, num_blocks, syncnv, immed); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " @@ -1291,7 +1283,7 @@ iscsi_prefetch10_task(struct iscsi_context *iscsi, int lun, uint32_t lba, { struct scsi_task *task; - task = scsi_cdb_prefetch10(iscsi, lba, num_blocks, immed, group); + task = scsi_cdb_prefetch10(lba, num_blocks, immed, group); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "prefetch10 cdb."); @@ -1313,7 +1305,7 @@ iscsi_prefetch16_task(struct iscsi_context *iscsi, int lun, uint64_t lba, { struct scsi_task *task; - task = scsi_cdb_prefetch16(iscsi, lba, num_blocks, immed, group); + task = scsi_cdb_prefetch16(lba, num_blocks, immed, group); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "prefetch16 cdb."); @@ -1339,7 +1331,7 @@ iscsi_writesame10_task(struct iscsi_context *iscsi, int lun, struct scsi_task *task; struct iscsi_data outdata; - task = scsi_cdb_writesame10(iscsi, wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); + task = scsi_cdb_writesame10(wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "writesame10 cdb."); @@ -1381,7 +1373,7 @@ iscsi_writesame16_task(struct iscsi_context *iscsi, int lun, struct scsi_task *task; struct iscsi_data outdata; - task = scsi_cdb_writesame16(iscsi, wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); + task = scsi_cdb_writesame16(wrprotect, anchor, unmap, pbdata, lbdata, lba, group, num_blocks); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "writesame16 cdb."); @@ -1425,7 +1417,7 @@ iscsi_unmap_task(struct iscsi_context *iscsi, int lun, int anchor, int group, xferlen = 8 + list_len * 16; - task = scsi_cdb_unmap(iscsi, anchor, group, xferlen); + task = scsi_cdb_unmap(anchor, group, xferlen); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "unmap cdb."); @@ -1492,7 +1484,7 @@ iscsi_readtoc_task(struct iscsi_context *iscsi, int lun, int msf, { struct scsi_task *task; - task = scsi_cdb_readtoc(iscsi, msf, format, track_session, maxsize); + task = scsi_cdb_readtoc(msf, format, track_session, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "read TOC cdb."); @@ -1513,7 +1505,7 @@ iscsi_reserve6_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_reserve6(iscsi); + task = scsi_cdb_reserve6(); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "reserve6 cdb."); @@ -1534,7 +1526,7 @@ iscsi_release6_task(struct iscsi_context *iscsi, int lun, { struct scsi_task *task; - task = scsi_cdb_release6(iscsi); + task = scsi_cdb_release6(); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "release6 cdb."); @@ -1556,7 +1548,7 @@ iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, { struct scsi_task *task; - task = scsi_cdb_report_supported_opcodes(iscsi, return_timeouts, maxsize); + task = scsi_cdb_report_supported_opcodes(return_timeouts, maxsize); if (task == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to create " "Maintenance In/Read Supported Op Codes cdb."); @@ -1576,3 +1568,57 @@ iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu) { return pdu->scsi_cbdata->task; } + +int +iscsi_scsi_cancel_task(struct iscsi_context *iscsi, + struct scsi_task *task) +{ + struct iscsi_pdu *pdu; + + for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { + if (pdu->itt == task->itt) { + SLIST_REMOVE(&iscsi->waitpdu, pdu); + if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, + pdu->private_data); + } + iscsi_free_pdu(iscsi, pdu); + return 0; + } + } + for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) { + if (pdu->itt == task->itt) { + SLIST_REMOVE(&iscsi->outqueue, pdu); + if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, + pdu->private_data); + } + iscsi_free_pdu(iscsi, pdu); + return 0; + } + } + return -1; +} + +void +iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi) +{ + struct iscsi_pdu *pdu; + + for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { + SLIST_REMOVE(&iscsi->waitpdu, pdu); + if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, + pdu->private_data); + } + iscsi_free_pdu(iscsi, pdu); + } + for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) { + SLIST_REMOVE(&iscsi->outqueue, pdu); + if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, + pdu->private_data); + } + iscsi_free_pdu(iscsi, pdu); + } +} diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index d99f5d9..53e84d3 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -35,58 +35,39 @@ #include #include #include "slist.h" -#include "iscsi.h" #include "scsi-lowlevel.h" -#include "iscsi-private.h" +struct scsi_allocated_memory { + struct scsi_allocated_memory *next; + char buf[0]; +}; void scsi_free_scsi_task(struct scsi_task *task) { struct scsi_allocated_memory *mem; - if (task->iscsi != NULL) { - while ((mem = task->mem)) { - SLIST_REMOVE(&task->mem, mem); - iscsi_free(task->iscsi, mem); - } - iscsi_free(task->iscsi,task->datain.data); - iscsi_free(task->iscsi,task); - } else { - while ((mem = task->mem)) { - SLIST_REMOVE(&task->mem, mem); - free(mem); - } - free(task->datain.data); - free(task); + while ((mem = task->mem)) { + SLIST_REMOVE(&task->mem, mem); + free(mem); } -} -struct scsi_task * -scsi_create_scsi_task(struct iscsi_context *iscsi) -{ - struct scsi_task * task; - task = iscsi_zmalloc(iscsi, sizeof(struct scsi_task)); - if (task==NULL) return NULL; - task->iscsi=iscsi; - return task; + free(task->datain.data); + free(task); } void * scsi_malloc(struct scsi_task *task, size_t size) { struct scsi_allocated_memory *mem; - if (task->iscsi != NULL) - mem = iscsi_malloc(task->iscsi,sizeof(struct scsi_allocated_memory) + size); - else - mem = malloc(sizeof(struct scsi_allocated_memory) + size); + + mem = malloc(sizeof(struct scsi_allocated_memory) + size); if (mem == NULL) { return NULL; } memset(mem, 0, sizeof(struct scsi_allocated_memory) + size); - mem->ptr = (void *) ((uintptr_t)mem + sizeof(struct scsi_allocated_memory)); SLIST_ADD(&task->mem, mem); - return mem->ptr; + return &mem->buf[0]; } struct value_string { @@ -183,15 +164,16 @@ scsi_sense_ascq_str(int ascq) * TESTUNITREADY */ struct scsi_task * -scsi_cdb_testunitready(struct iscsi_context *iscsi) +scsi_cdb_testunitready(void) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_TESTUNITREADY; task->cdb_size = 6; @@ -206,15 +188,16 @@ scsi_cdb_testunitready(struct iscsi_context *iscsi) * REPORTLUNS */ struct scsi_task * -scsi_reportluns_cdb(struct iscsi_context *iscsi, int report_type, int alloc_len) +scsi_reportluns_cdb(int report_type, int alloc_len) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_REPORTLUNS; task->cdb[2] = report_type; *(uint32_t *)&task->cdb[6] = htonl(alloc_len); @@ -286,15 +269,16 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) * READCAPACITY10 */ struct scsi_task * -scsi_cdb_readcapacity10(struct iscsi_context *iscsi, int lba, int pmi) +scsi_cdb_readcapacity10(int lba, int pmi) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READCAPACITY10; *(uint32_t *)&task->cdb[2] = htonl(lba); @@ -319,7 +303,7 @@ scsi_cdb_readcapacity10(struct iscsi_context *iscsi, int lba, int pmi) * READTOC */ struct scsi_task * -scsi_cdb_readtoc(struct iscsi_context *iscsi, int msf, int format, int track_session, uint16_t alloc_len) +scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len) { struct scsi_task *task; @@ -329,11 +313,12 @@ scsi_cdb_readtoc(struct iscsi_context *iscsi, int msf, int format, int track_ses return NULL; } - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READTOC; if (msf) { @@ -472,15 +457,16 @@ scsi_readtoc_datain_unmarshall(struct scsi_task *task) * RESERVE6 */ struct scsi_task * -scsi_cdb_reserve6(struct iscsi_context *iscsi) +scsi_cdb_reserve6(void) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_RESERVE6; task->cdb_size = 6; @@ -492,15 +478,16 @@ scsi_cdb_reserve6(struct iscsi_context *iscsi) * RELEASE10 */ struct scsi_task * -scsi_cdb_release6(struct iscsi_context *iscsi) +scsi_cdb_release6(void) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_RELEASE6; task->cdb_size = 6; @@ -651,15 +638,16 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task) * MAINTENANCE In / Read Supported Op Codes */ struct scsi_task * -scsi_cdb_report_supported_opcodes(struct iscsi_context *iscsi, int return_timeouts, uint32_t alloc_len) +scsi_cdb_report_supported_opcodes(int return_timeouts, uint32_t alloc_len) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_MAINTENANCE_IN; task->cdb[1] = SCSI_REPORT_SUPPORTED_OP_CODES; task->cdb[2] = SCSI_REPORT_SUPPORTING_OPS_ALL; @@ -724,15 +712,16 @@ scsi_readcapacity10_datain_unmarshall(struct scsi_task *task) * INQUIRY */ struct scsi_task * -scsi_cdb_inquiry(struct iscsi_context *iscsi, int evpd, int page_code, int alloc_len) +scsi_cdb_inquiry(int evpd, int page_code, int alloc_len) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_INQUIRY; if (evpd) { @@ -999,7 +988,7 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task) * READ6 */ struct scsi_task * -scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize) +scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize) { struct scsi_task *task; int num_blocks; @@ -1013,11 +1002,12 @@ scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int return NULL; } - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ6; task->cdb_size = 6; @@ -1046,15 +1036,16 @@ scsi_cdb_read6(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int * READ10 */ struct scsi_task * -scsi_cdb_read10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1091,15 +1082,16 @@ scsi_cdb_read10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int * READ12 */ struct scsi_task * -scsi_cdb_read12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1136,15 +1128,16 @@ scsi_cdb_read12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int * READ16 */ struct scsi_task * -scsi_cdb_read16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[1] |= ((rdprotect & 0x07) << 5); @@ -1182,15 +1175,16 @@ scsi_cdb_read16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int * WRITE10 */ struct scsi_task * -scsi_cdb_write10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE10; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1227,15 +1221,16 @@ scsi_cdb_write10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, in * WRITE12 */ struct scsi_task * -scsi_cdb_write12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE12; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1272,15 +1267,16 @@ scsi_cdb_write12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, in * WRITE16 */ struct scsi_task * -scsi_cdb_write16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE16; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1318,15 +1314,16 @@ scsi_cdb_write16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, in * ORWRITE */ struct scsi_task * -scsi_cdb_orwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_ORWRITE; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1364,15 +1361,16 @@ scsi_cdb_orwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, in * COMPAREANDWRITE */ struct scsi_task * -scsi_cdb_compareandwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) +scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_COMPARE_AND_WRITE; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -1409,15 +1407,16 @@ scsi_cdb_compareandwrite(struct iscsi_context *iscsi, uint64_t lba, uint32_t xfe * VERIFY10 */ struct scsi_task * -scsi_cdb_verify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY10; if (vprotect) { @@ -1454,15 +1453,16 @@ scsi_cdb_verify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, i * VERIFY12 */ struct scsi_task * -scsi_cdb_verify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY12; if (vprotect) { @@ -1499,15 +1499,16 @@ scsi_cdb_verify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, i * VERIFY16 */ struct scsi_task * -scsi_cdb_verify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) +scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int bytchk, int blocksize) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_VERIFY16; if (vprotect) { @@ -1545,15 +1546,16 @@ scsi_cdb_verify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, i * UNMAP */ struct scsi_task * -scsi_cdb_unmap(struct iscsi_context *iscsi, int anchor, int group, uint16_t xferlen) +scsi_cdb_unmap(int anchor, int group, uint16_t xferlen) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_UNMAP; if (anchor) { @@ -1578,15 +1580,16 @@ scsi_cdb_unmap(struct iscsi_context *iscsi, int anchor, int group, uint16_t xfer * WRITE_SAME10 */ struct scsi_task * -scsi_cdb_writesame10(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks) +scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint32_t lba, int group, uint16_t num_blocks) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_SAME10; if (wrprotect) { @@ -1621,15 +1624,16 @@ scsi_cdb_writesame10(struct iscsi_context *iscsi, int wrprotect, int anchor, int * WRITE_SAME16 */ struct scsi_task * -scsi_cdb_writesame16(struct iscsi_context *iscsi, int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks) +scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdata, uint64_t lba, int group, uint32_t num_blocks) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_SAME16; if (wrprotect) { @@ -1665,17 +1669,18 @@ scsi_cdb_writesame16(struct iscsi_context *iscsi, int wrprotect, int anchor, int * MODESENSE6 */ struct scsi_task * -scsi_cdb_modesense6(struct iscsi_context *iscsi, int dbd, enum scsi_modesense_page_control pc, +scsi_cdb_modesense6(int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, unsigned char alloc_len) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_MODESENSE6; if (dbd) { @@ -1855,15 +1860,16 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) * STARTSTOPUNIT */ struct scsi_task * -scsi_cdb_startstopunit(struct iscsi_context *iscsi, int immed, int pcm, int pc, int no_flush, int loej, int start) +scsi_cdb_startstopunit(int immed, int pcm, int pc, int no_flush, int loej, int start) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_STARTSTOPUNIT; if (immed) { @@ -1900,15 +1906,16 @@ scsi_cdb_startstopunit(struct iscsi_context *iscsi, int immed, int pcm, int pc, * PREVENTALLOWMEDIUMREMOVAL */ struct scsi_task * -scsi_cdb_preventallow(struct iscsi_context *iscsi, int prevent) +scsi_cdb_preventallow(int prevent) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREVENTALLOW; task->cdb[4] = prevent & 0x03; @@ -1926,15 +1933,16 @@ scsi_cdb_preventallow(struct iscsi_context *iscsi, int prevent) * SYNCHRONIZECACHE10 */ struct scsi_task * -scsi_cdb_synchronizecache10(struct iscsi_context *iscsi, int lba, int num_blocks, int syncnv, int immed) +scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SYNCHRONIZECACHE10; if (syncnv) { @@ -1957,15 +1965,16 @@ scsi_cdb_synchronizecache10(struct iscsi_context *iscsi, int lba, int num_blocks * SYNCHRONIZECACHE16 */ struct scsi_task * -scsi_cdb_synchronizecache16(struct iscsi_context *iscsi, uint64_t lba, uint32_t num_blocks, int syncnv, int immed) +scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, int syncnv, int immed) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SYNCHRONIZECACHE16; if (syncnv) { @@ -1989,15 +1998,16 @@ scsi_cdb_synchronizecache16(struct iscsi_context *iscsi, uint64_t lba, uint32_t * PREFETCH10 */ struct scsi_task * -scsi_cdb_prefetch10(struct iscsi_context *iscsi, uint32_t lba, int num_blocks, int immed, int group) +scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREFETCH10; if (immed) { @@ -2018,15 +2028,16 @@ scsi_cdb_prefetch10(struct iscsi_context *iscsi, uint32_t lba, int num_blocks, i * PREFETCH16 */ struct scsi_task * -scsi_cdb_prefetch16(struct iscsi_context *iscsi, uint64_t lba, int num_blocks, int immed, int group) +scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_PREFETCH16; if (immed) { @@ -2049,15 +2060,16 @@ scsi_cdb_prefetch16(struct iscsi_context *iscsi, uint64_t lba, int num_blocks, i * SERVICEACTIONIN16 */ struct scsi_task * -scsi_cdb_serviceactionin16(struct iscsi_context *iscsi, enum scsi_service_action_in sa, uint32_t xferlen) +scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SERVICE_ACTION_IN; task->cdb[1] = sa; @@ -2081,24 +2093,25 @@ scsi_cdb_serviceactionin16(struct iscsi_context *iscsi, enum scsi_service_action * READCAPACITY16 */ struct scsi_task * -scsi_cdb_readcapacity16(struct iscsi_context *iscsi) +scsi_cdb_readcapacity16(void) { - return scsi_cdb_serviceactionin16(iscsi, SCSI_READCAPACITY16, 32); + return scsi_cdb_serviceactionin16(SCSI_READCAPACITY16, 32); } /* * GET_LBA_STATUS */ struct scsi_task * -scsi_cdb_get_lba_status(struct iscsi_context *iscsi, uint64_t starting_lba, uint32_t alloc_len) +scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_SERVICE_ACTION_IN; task->cdb[1] = SCSI_GET_LBA_STATUS; @@ -2124,15 +2137,16 @@ scsi_cdb_get_lba_status(struct iscsi_context *iscsi, uint64_t starting_lba, uint * WRITEVERIFY10 */ struct scsi_task * -scsi_cdb_writeverify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY10; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -2166,15 +2180,16 @@ scsi_cdb_writeverify10(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferl * WRITEVERIFY12 */ struct scsi_task * -scsi_cdb_writeverify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY12; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -2208,15 +2223,16 @@ scsi_cdb_writeverify12(struct iscsi_context *iscsi, uint32_t lba, uint32_t xferl * WRITEVERIFY16 */ struct scsi_task * -scsi_cdb_writeverify16(struct iscsi_context *iscsi, uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) +scsi_cdb_writeverify16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int bytchk, int group_number) { struct scsi_task *task; - task = scsi_create_scsi_task(iscsi); + task = malloc(sizeof(struct scsi_task)); if (task == NULL) { return NULL; } + memset(task, 0, sizeof(struct scsi_task)); task->cdb[0] = SCSI_OPCODE_WRITE_VERIFY16; task->cdb[1] |= ((wrprotect & 0x07) << 5); @@ -2539,77 +2555,3 @@ scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos, ssize_t *coun return &sdb->data[pos]; } - -int -iscsi_scsi_task_cancel(struct iscsi_context *iscsi, - struct scsi_task *task) -{ - struct iscsi_pdu *pdu; - - for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { - if (pdu->itt == task->itt) { - while(task->in_buffers != NULL) { - struct scsi_data_buffer *ptr = task->in_buffers; - SLIST_REMOVE(&task->in_buffers, ptr); - } - SLIST_REMOVE(&iscsi->waitpdu, pdu); - if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi_free_pdu(iscsi, pdu); - return 0; - } - } - for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) { - if (pdu->itt == task->itt) { - while(task->in_buffers != NULL) { - struct scsi_data_buffer *ptr = task->in_buffers; - SLIST_REMOVE(&task->in_buffers, ptr); - } - SLIST_REMOVE(&iscsi->outqueue, pdu); - if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi_free_pdu(iscsi, pdu); - return 0; - } - } - return -1; -} - -void -iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi) -{ - struct iscsi_pdu *pdu; - - for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { - struct scsi_task *task = iscsi_scsi_get_task_from_pdu(pdu); - - while(task->in_buffers != NULL) { - struct scsi_data_buffer *ptr = task->in_buffers; - SLIST_REMOVE(&task->in_buffers, ptr); - } - SLIST_REMOVE(&iscsi->waitpdu, pdu); - if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi_free_pdu(iscsi, pdu); - } - for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) { - struct scsi_task *task = iscsi_scsi_get_task_from_pdu(pdu); - - while(task->in_buffers != NULL) { - struct scsi_data_buffer *ptr = task->in_buffers; - SLIST_REMOVE(&task->in_buffers, ptr); - } - SLIST_REMOVE(&iscsi->outqueue, pdu); - if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi_free_pdu(iscsi, pdu); - } -} diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c index 286072d..5767aed 100644 --- a/lib/task_mgmt.c +++ b/lib/task_mgmt.c @@ -103,7 +103,7 @@ iscsi_task_mgmt_abort_task_async(struct iscsi_context *iscsi, struct scsi_task *task, iscsi_command_cb cb, void *private_data) { - iscsi_scsi_task_cancel(iscsi, task); + iscsi_scsi_cancel_task(iscsi, task); return iscsi_task_mgmt_async(iscsi, task->lun, ISCSI_TM_ABORT_TASK, From b1374b42edaac43b1a158966c0af073de8e5653e Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 12 Nov 2012 16:12:29 +0100 Subject: [PATCH 27/27] Rename scsi-command.c to iscsi-command.c --- Makefile.am | 2 +- include/iscsi-private.h | 2 +- lib/{scsi-command.c => iscsi-command.c} | 0 win32/vsbuild.bat | 6 +++--- 4 files changed, 5 insertions(+), 5 deletions(-) rename lib/{scsi-command.c => iscsi-command.c} (100%) diff --git a/Makefile.am b/Makefile.am index 9c07405..5ef88d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,7 @@ dist_noinst_DATA = lib/libiscsi.syms lib_LTLIBRARIES = lib/libiscsi.la lib_libiscsi_la_SOURCES = \ lib/connect.c lib/crc32c.c lib/discovery.c lib/init.c \ - lib/login.c lib/md5.c lib/nop.c lib/pdu.c lib/scsi-command.c \ + lib/login.c lib/md5.c lib/nop.c lib/pdu.c lib/iscsi-command.c \ lib/scsi-lowlevel.c lib/socket.c lib/sync.c lib/task_mgmt.c \ lib/logging.c diff --git a/include/iscsi-private.h b/include/iscsi-private.h index a8c7763..48b757a 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -132,7 +132,7 @@ struct iscsi_context { int reconnect_deferred; int log_level; - iscsi_log_fn log_fn; + iscsi_log_fn log_fn; int mallocs; int reallocs; diff --git a/lib/scsi-command.c b/lib/iscsi-command.c similarity index 100% rename from lib/scsi-command.c rename to lib/iscsi-command.c diff --git a/win32/vsbuild.bat b/win32/vsbuild.bat index c16b6ea..0e48de0 100644 --- a/win32/vsbuild.bat +++ b/win32/vsbuild.bat @@ -14,7 +14,7 @@ cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\logi cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\md5.c -Folib\md5.obj cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\nop.c -Folib\nop.obj cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\pdu.c -Folib\pdu.obj -cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\scsi-command.c -Folib\scsi-command.obj +cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\iscsi-command.c -Folib\iscsi-command.obj cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\scsi-lowlevel.c -Folib\scsi-lowlevel.obj cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\socket.c -Folib\socket.obj cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\sync.c -Folib\sync.obj @@ -27,9 +27,9 @@ cl /I. /Iinclude -Zi -Od -c -D_U_="" -DWIN32 -D_WIN32_WINNT=0x0600 -MDd win32\wi rem rem create a linklibrary/dll rem -lib /out:lib\libiscsi.lib /def:lib\libiscsi.def lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\scsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj lib\win32_compat.obj +lib /out:lib\libiscsi.lib /def:lib\libiscsi.def lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\iscsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj lib\win32_compat.obj -link /DLL /out:lib\libiscsi.dll /DEBUG /DEBUGTYPE:cv lib\libiscsi.exp lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\scsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj lib\win32_compat.obj ws2_32.lib kernel32.lib +link /DLL /out:lib\libiscsi.dll /DEBUG /DEBUGTYPE:cv lib\libiscsi.exp lib\connect.obj lib\crc32c.obj lib\discovery.obj lib\init.obj lib\login.obj lib\md5.obj lib\nop.obj lib\pdu.obj lib\iscsi-command.obj lib\scsi-lowlevel.obj lib\socket.obj lib\sync.obj lib\task_mgmt.obj lib\win32_compat.obj ws2_32.lib kernel32.lib