Merge pull request #36 from plieven/master
Merge of my patches as discussed
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ dist_noinst_DATA = lib/libiscsi.syms
|
|||||||
lib_LTLIBRARIES = lib/libiscsi.la
|
lib_LTLIBRARIES = lib/libiscsi.la
|
||||||
lib_libiscsi_la_SOURCES = \
|
lib_libiscsi_la_SOURCES = \
|
||||||
lib/connect.c lib/crc32c.c lib/discovery.c lib/init.c \
|
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/scsi-lowlevel.c lib/socket.c lib/sync.c lib/task_mgmt.c \
|
||||||
lib/logging.c
|
lib/logging.c
|
||||||
|
|
||||||
|
|||||||
+29
-3
@@ -18,6 +18,7 @@
|
|||||||
#define __iscsi_private_h__
|
#define __iscsi_private_h__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
#include <basetsd.h>
|
#include <basetsd.h>
|
||||||
@@ -48,8 +49,8 @@ struct iscsi_in_pdu {
|
|||||||
long long data_pos;
|
long long data_pos;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
};
|
};
|
||||||
void iscsi_free_iscsi_in_pdu(struct iscsi_in_pdu *in);
|
void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in);
|
||||||
void iscsi_free_iscsi_inqueue(struct iscsi_in_pdu *inqueue);
|
void iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inqueue);
|
||||||
|
|
||||||
enum iscsi_initial_r2t {
|
enum iscsi_initial_r2t {
|
||||||
ISCSI_INITIAL_R2T_NO = 0,
|
ISCSI_INITIAL_R2T_NO = 0,
|
||||||
@@ -68,6 +69,7 @@ struct iscsi_context {
|
|||||||
char connected_portal[MAX_STRING_SIZE+1];
|
char connected_portal[MAX_STRING_SIZE+1];
|
||||||
char portal[MAX_STRING_SIZE+1];
|
char portal[MAX_STRING_SIZE+1];
|
||||||
char alias[MAX_STRING_SIZE+1];
|
char alias[MAX_STRING_SIZE+1];
|
||||||
|
char bind_interfaces[MAX_STRING_SIZE+1];
|
||||||
|
|
||||||
char user[MAX_STRING_SIZE+1];
|
char user[MAX_STRING_SIZE+1];
|
||||||
char passwd[MAX_STRING_SIZE+1];
|
char passwd[MAX_STRING_SIZE+1];
|
||||||
@@ -102,6 +104,7 @@ struct iscsi_context {
|
|||||||
int login_attempts;
|
int login_attempts;
|
||||||
int is_loggedin;
|
int is_loggedin;
|
||||||
int is_reconnecting;
|
int is_reconnecting;
|
||||||
|
int bind_interfaces_cnt;
|
||||||
|
|
||||||
int chap_a;
|
int chap_a;
|
||||||
int chap_i;
|
int chap_i;
|
||||||
@@ -130,6 +133,12 @@ struct iscsi_context {
|
|||||||
|
|
||||||
int log_level;
|
int log_level;
|
||||||
iscsi_log_fn log_fn;
|
iscsi_log_fn log_fn;
|
||||||
|
|
||||||
|
int mallocs;
|
||||||
|
int reallocs;
|
||||||
|
int frees;
|
||||||
|
|
||||||
|
time_t last_reconnect;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ISCSI_PDU_IMMEDIATE 0x40
|
#define ISCSI_PDU_IMMEDIATE 0x40
|
||||||
@@ -210,16 +219,26 @@ struct iscsi_pdu {
|
|||||||
struct iscsi_scsi_cbdata *scsi_cbdata;
|
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,
|
struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi,
|
||||||
enum iscsi_opcode opcode,
|
enum iscsi_opcode opcode,
|
||||||
enum iscsi_opcode response_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,
|
struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi,
|
||||||
enum iscsi_opcode opcode,
|
enum iscsi_opcode opcode,
|
||||||
enum iscsi_opcode response_opcode,
|
enum iscsi_opcode response_opcode,
|
||||||
uint32_t itt,
|
uint32_t itt,
|
||||||
uint32_t flags);
|
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_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_pduflags(struct iscsi_pdu *pdu, unsigned char flags);
|
||||||
void iscsi_pdu_set_immediate(struct iscsi_pdu *pdu);
|
void iscsi_pdu_set_immediate(struct iscsi_pdu *pdu);
|
||||||
@@ -279,6 +298,11 @@ 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 *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);
|
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_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);
|
||||||
|
|
||||||
unsigned long crc32c(char *buf, int len);
|
unsigned long crc32c(char *buf, int len);
|
||||||
|
|
||||||
@@ -286,6 +310,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_set_noautoreconnect(struct iscsi_context *iscsi, int state);
|
||||||
|
|
||||||
|
void iscsi_decrement_iface_rr(void);
|
||||||
|
|
||||||
#define ISCSI_LOG(iscsi, level, format, args...) \
|
#define ISCSI_LOG(iscsi, level, format, args...) \
|
||||||
do { \
|
do { \
|
||||||
if (level <= iscsi->log_level && iscsi->log_fn) { \
|
if (level <= iscsi->log_level && iscsi->log_fn) { \
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ struct iscsi_url {
|
|||||||
char user[MAX_STRING_SIZE+1];
|
char user[MAX_STRING_SIZE+1];
|
||||||
char passwd[MAX_STRING_SIZE+1];
|
char passwd[MAX_STRING_SIZE+1];
|
||||||
int lun;
|
int lun;
|
||||||
|
struct iscsi_context *iscsi;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -532,6 +533,7 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi,
|
|||||||
|
|
||||||
struct iscsi_data {
|
struct iscsi_data {
|
||||||
int size;
|
int size;
|
||||||
|
size_t alloc_size;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1023,6 +1025,13 @@ iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value);
|
|||||||
EXTERN void
|
EXTERN void
|
||||||
iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -839,4 +839,3 @@ void *scsi_malloc(struct scsi_task *task, size_t size);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __scsi_lowlevel_h__ */
|
#endif /* __scsi_lowlevel_h__ */
|
||||||
|
|
||||||
|
|||||||
+25
-11
@@ -61,7 +61,7 @@ iscsi_testunitready_cb(struct iscsi_context *iscsi, int status,
|
|||||||
"failed.");
|
"failed.");
|
||||||
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL,
|
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
ct->private_data);
|
ct->private_data);
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
}
|
}
|
||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
return;
|
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->cb(iscsi, status?SCSI_STATUS_ERROR:SCSI_STATUS_GOOD, NULL,
|
||||||
ct->private_data);
|
ct->private_data);
|
||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -91,8 +91,9 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_,
|
|||||||
|
|
||||||
if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) {
|
if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) {
|
||||||
iscsi_disconnect(iscsi);
|
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) {
|
if (iscsi_connect_async(iscsi, iscsi->target_address, iscsi_connect_cb, iscsi->connect_data) != 0) {
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -100,7 +101,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_,
|
|||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,14 +122,14 @@ iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data _U_
|
|||||||
iscsi_set_error(iscsi, "Failed to connect to iSCSI socket. "
|
iscsi_set_error(iscsi, "Failed to connect to iSCSI socket. "
|
||||||
"%s", iscsi_get_error(iscsi));
|
"%s", iscsi_get_error(iscsi));
|
||||||
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iscsi_login_async(iscsi, iscsi_login_cb, ct) != 0) {
|
if (iscsi_login_async(iscsi, iscsi_login_cb, ct) != 0) {
|
||||||
iscsi_set_error(iscsi, "iscsi_login_async failed.");
|
iscsi_set_error(iscsi, "iscsi_login_async failed.");
|
||||||
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data);
|
||||||
free(ct);
|
iscsi_free(iscsi, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,9 +141,10 @@ iscsi_full_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
struct connect_task *ct;
|
struct connect_task *ct;
|
||||||
|
|
||||||
iscsi->lun = lun;
|
iscsi->lun = lun;
|
||||||
strncpy(iscsi->portal,portal,MAX_STRING_SIZE);
|
if (iscsi->portal != portal)
|
||||||
|
strncpy(iscsi->portal,portal,MAX_STRING_SIZE);
|
||||||
|
|
||||||
ct = malloc(sizeof(struct connect_task));
|
ct = iscsi_malloc(iscsi, sizeof(struct connect_task));
|
||||||
if (ct == NULL) {
|
if (ct == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory. Failed to allocate "
|
iscsi_set_error(iscsi, "Out-of-memory. Failed to allocate "
|
||||||
"connect_task structure.");
|
"connect_task structure.");
|
||||||
@@ -218,6 +220,10 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi)
|
|||||||
|
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
|
|
||||||
|
if (old_iscsi->last_reconnect) {
|
||||||
|
while (time(NULL) - old_iscsi->last_reconnect < 5) sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
try_again:
|
try_again:
|
||||||
|
|
||||||
iscsi = iscsi_create_context(old_iscsi->initiator_name);
|
iscsi = iscsi_create_context(old_iscsi->initiator_name);
|
||||||
@@ -235,7 +241,10 @@ try_again:
|
|||||||
|
|
||||||
iscsi->lun = old_iscsi->lun;
|
iscsi->lun = old_iscsi->lun;
|
||||||
|
|
||||||
strncpy(iscsi->portal,old_iscsi->portal, MAX_STRING_SIZE);
|
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->log_level = old_iscsi->log_level;
|
iscsi->log_level = old_iscsi->log_level;
|
||||||
iscsi->log_fn = old_iscsi->log_fn;
|
iscsi->log_fn = old_iscsi->log_fn;
|
||||||
@@ -318,18 +327,23 @@ try_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (old_iscsi->incoming != NULL) {
|
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) {
|
if (old_iscsi->inqueue != NULL) {
|
||||||
iscsi_free_iscsi_inqueue(old_iscsi->inqueue);
|
iscsi_free_iscsi_inqueue(old_iscsi, old_iscsi->inqueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(iscsi->fd);
|
close(iscsi->fd);
|
||||||
iscsi->fd = old_iscsi->fd;
|
iscsi->fd = old_iscsi->fd;
|
||||||
|
iscsi->mallocs+=old_iscsi->mallocs;
|
||||||
|
iscsi->frees+=old_iscsi->frees;
|
||||||
|
|
||||||
memcpy(old_iscsi, iscsi, sizeof(struct iscsi_context));
|
memcpy(old_iscsi, iscsi, sizeof(struct iscsi_context));
|
||||||
|
memset(iscsi, 0, sizeof(struct iscsi_context));
|
||||||
free(iscsi);
|
free(iscsi);
|
||||||
|
|
||||||
old_iscsi->is_reconnecting = 0;
|
old_iscsi->is_reconnecting = 0;
|
||||||
|
old_iscsi->last_reconnect = time(NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-15
@@ -79,19 +79,19 @@ iscsi_discovery_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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) {
|
while (addresses != NULL) {
|
||||||
struct iscsi_discovery_address *next = addresses->next;
|
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;
|
addresses->target_name = NULL;
|
||||||
|
|
||||||
free(discard_const(addresses->target_address));
|
iscsi_free(iscsi, discard_const(addresses->target_address));
|
||||||
addresses->target_address = NULL;
|
addresses->target_address = NULL;
|
||||||
|
|
||||||
addresses->next = NULL;
|
addresses->next = NULL;
|
||||||
free(addresses);
|
iscsi_free(iscsi, addresses);
|
||||||
addresses = next;
|
addresses = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
"discovery data %d>%d", len, size);
|
"discovery data %d>%d", len, size);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,40 +135,39 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (!strncmp((char *)ptr, "TargetName=", 11)) {
|
if (!strncmp((char *)ptr, "TargetName=", 11)) {
|
||||||
struct iscsi_discovery_address *target;
|
struct iscsi_discovery_address *target;
|
||||||
|
|
||||||
target = malloc(sizeof(struct iscsi_discovery_address));
|
target = iscsi_zmalloc(iscsi, sizeof(struct iscsi_discovery_address));
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target");
|
"target");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(target, 0, sizeof(struct iscsi_discovery_address));
|
target->target_name = iscsi_strdup(iscsi,(char *)ptr+11);
|
||||||
target->target_name = strdup((char *)ptr+11);
|
|
||||||
if (target->target_name == NULL) {
|
if (target->target_name == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target name");
|
"target name");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
free(target);
|
iscsi_free(iscsi, target);
|
||||||
target = NULL;
|
target = NULL;
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
target->next = targets;
|
target->next = targets;
|
||||||
targets = target;
|
targets = target;
|
||||||
} else if (!strncmp((char *)ptr, "TargetAddress=", 14)) {
|
} 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) {
|
if (targets->target_address == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target address");
|
"target address");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -176,7 +175,7 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
"discovery string : %s", ptr);
|
"discovery string : %s", ptr);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
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);
|
pdu->callback(iscsi, SCSI_STATUS_GOOD, targets, pdu->private_data);
|
||||||
iscsi_free_discovery_addresses(targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-8
@@ -33,11 +33,50 @@
|
|||||||
#include "iscsi-private.h"
|
#include "iscsi-private.h"
|
||||||
#include "slist.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_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);
|
||||||
|
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 *
|
struct iscsi_context *
|
||||||
iscsi_create_context(const char *initiator_name)
|
iscsi_create_context(const char *initiator_name)
|
||||||
{
|
{
|
||||||
struct iscsi_context *iscsi;
|
struct iscsi_context *iscsi;
|
||||||
|
|
||||||
|
if (!initiator_name[0]) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
iscsi = malloc(sizeof(struct iscsi_context));
|
iscsi = malloc(sizeof(struct iscsi_context));
|
||||||
if (iscsi == NULL) {
|
if (iscsi == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -46,13 +85,11 @@ iscsi_create_context(const char *initiator_name)
|
|||||||
memset(iscsi, 0, sizeof(struct iscsi_context));
|
memset(iscsi, 0, sizeof(struct iscsi_context));
|
||||||
|
|
||||||
strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE);
|
strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE);
|
||||||
if (!iscsi->initiator_name[0]) {
|
|
||||||
free(iscsi);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
iscsi->fd = -1;
|
iscsi->fd = -1;
|
||||||
|
|
||||||
|
srand(time(NULL) ^ getpid() ^ (u_int32_t) ((uintptr_t) iscsi));
|
||||||
|
|
||||||
/* initialize to a "random" isid */
|
/* initialize to a "random" isid */
|
||||||
iscsi_set_isid_random(iscsi, rand(), 0);
|
iscsi_set_isid_random(iscsi, rand(), 0);
|
||||||
|
|
||||||
@@ -100,6 +137,10 @@ iscsi_create_context(const char *initiator_name)
|
|||||||
iscsi_set_tcp_syncnt(iscsi,atoi(getenv("LIBISCSI_TCP_SYNCNT")));
|
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;
|
return iscsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,14 +268,21 @@ iscsi_destroy_context(struct iscsi_context *iscsi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iscsi->incoming != NULL) {
|
if (iscsi->incoming != NULL) {
|
||||||
iscsi_free_iscsi_in_pdu(iscsi->incoming);
|
iscsi_free_iscsi_in_pdu(iscsi, iscsi->incoming);
|
||||||
}
|
}
|
||||||
if (iscsi->inqueue != NULL) {
|
if (iscsi->inqueue != NULL) {
|
||||||
iscsi_free_iscsi_inqueue(iscsi->inqueue);
|
iscsi_free_iscsi_inqueue(iscsi, iscsi->inqueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
iscsi->connect_data = NULL;
|
iscsi->connect_data = NULL;
|
||||||
|
|
||||||
|
if (iscsi->mallocs != iscsi->frees) {
|
||||||
|
ISCSI_LOG(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 {
|
||||||
|
ISCSI_LOG(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));
|
||||||
free(iscsi);
|
free(iscsi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -394,12 +442,17 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full)
|
|||||||
if (tmp) *tmp=0;
|
if (tmp) *tmp=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
iscsi_url = malloc(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) {
|
if (iscsi_url == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure");
|
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(iscsi_url, 0, sizeof(struct iscsi_url));
|
memset(iscsi_url, 0, sizeof(struct iscsi_url));
|
||||||
|
iscsi_url->iscsi= iscsi;
|
||||||
|
|
||||||
strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE);
|
strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE);
|
||||||
|
|
||||||
@@ -431,7 +484,12 @@ iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url)
|
|||||||
void
|
void
|
||||||
iscsi_destroy_url(struct iscsi_url *iscsi_url)
|
iscsi_destroy_url(struct iscsi_url *iscsi_url)
|
||||||
{
|
{
|
||||||
free(iscsi_url);
|
struct iscsi_context *iscsi = iscsi_url->iscsi;
|
||||||
|
memset(iscsi_url, 0, sizeof(struct iscsi_url));
|
||||||
|
if (iscsi != NULL)
|
||||||
|
iscsi_free(iscsi, iscsi_url);
|
||||||
|
else
|
||||||
|
free(iscsi_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct iscsi_scsi_cbdata {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
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) {
|
if (scsi_cbdata == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -45,7 +45,7 @@ iscsi_free_scsi_cbdata(struct iscsi_scsi_cbdata *scsi_cbdata)
|
|||||||
if (scsi_cbdata->task != NULL) {
|
if (scsi_cbdata->task != NULL) {
|
||||||
scsi_cbdata->task = NULL;
|
scsi_cbdata->task = NULL;
|
||||||
}
|
}
|
||||||
free(scsi_cbdata);
|
iscsi_free(iscsi, scsi_cbdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -186,13 +186,13 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_cbdata = malloc(sizeof(struct iscsi_scsi_cbdata));
|
scsi_cbdata = iscsi_zmalloc(iscsi, sizeof(struct iscsi_scsi_cbdata));
|
||||||
if (scsi_cbdata == NULL) {
|
if (scsi_cbdata == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to allocate "
|
iscsi_set_error(iscsi, "Out-of-memory: failed to allocate "
|
||||||
"scsi cbdata.");
|
"scsi cbdata.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(scsi_cbdata, 0, sizeof(struct iscsi_scsi_cbdata));
|
|
||||||
scsi_cbdata->task = task;
|
scsi_cbdata->task = task;
|
||||||
scsi_cbdata->callback = cb;
|
scsi_cbdata->callback = cb;
|
||||||
scsi_cbdata->private_data = private_data;
|
scsi_cbdata->private_data = private_data;
|
||||||
@@ -204,7 +204,7 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
||||||
"scsi pdu.");
|
"scsi pdu.");
|
||||||
iscsi_free_scsi_cbdata(scsi_cbdata);
|
iscsi_free_scsi_cbdata(iscsi, scsi_cbdata);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pdu->scsi_cbdata = scsi_cbdata;
|
pdu->scsi_cbdata = scsi_cbdata;
|
||||||
@@ -81,6 +81,7 @@ iscsi_set_tcp_keepidle
|
|||||||
iscsi_set_tcp_keepcnt
|
iscsi_set_tcp_keepcnt
|
||||||
iscsi_set_tcp_keepintvl
|
iscsi_set_tcp_keepintvl
|
||||||
iscsi_set_tcp_syncnt
|
iscsi_set_tcp_syncnt
|
||||||
|
iscsi_set_bind_interface
|
||||||
iscsi_startstopunit_sync
|
iscsi_startstopunit_sync
|
||||||
iscsi_startstopunit_task
|
iscsi_startstopunit_task
|
||||||
iscsi_synchronizecache10_sync
|
iscsi_synchronizecache10_sync
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ iscsi_set_tcp_keepidle
|
|||||||
iscsi_set_tcp_keepcnt
|
iscsi_set_tcp_keepcnt
|
||||||
iscsi_set_tcp_keepintvl
|
iscsi_set_tcp_keepintvl
|
||||||
iscsi_set_tcp_syncnt
|
iscsi_set_tcp_syncnt
|
||||||
|
iscsi_set_bind_interface
|
||||||
iscsi_startstopunit_sync
|
iscsi_startstopunit_sync
|
||||||
iscsi_startstopunit_task
|
iscsi_startstopunit_task
|
||||||
iscsi_synchronizecache10_sync
|
iscsi_synchronizecache10_sync
|
||||||
|
|||||||
+2
-2
@@ -705,10 +705,10 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
return -1;
|
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_REQUEST,
|
||||||
ISCSI_PDU_LOGIN_RESPONSE,
|
ISCSI_PDU_LOGIN_RESPONSE,
|
||||||
iscsi->itt, 0);
|
iscsi->itt, 0, 1024);
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
||||||
"login pdu.");
|
"login pdu.");
|
||||||
|
|||||||
@@ -31,27 +31,28 @@
|
|||||||
#include "slist.h"
|
#include "slist.h"
|
||||||
|
|
||||||
struct iscsi_pdu *
|
struct iscsi_pdu *
|
||||||
iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
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)
|
enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags, size_t payload_size)
|
||||||
{
|
{
|
||||||
struct iscsi_pdu *pdu;
|
struct iscsi_pdu *pdu;
|
||||||
|
|
||||||
pdu = malloc(sizeof(struct iscsi_pdu));
|
pdu = iscsi_zmalloc(iscsi, sizeof(struct iscsi_pdu));
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
iscsi_set_error(iscsi, "failed to allocate pdu");
|
iscsi_set_error(iscsi, "failed to allocate pdu");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(pdu, 0, sizeof(struct iscsi_pdu));
|
|
||||||
|
|
||||||
pdu->outdata.size = ISCSI_HEADER_SIZE;
|
pdu->outdata.size = ISCSI_HEADER_SIZE;
|
||||||
pdu->outdata.data = malloc(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) {
|
if (pdu->outdata.data == NULL) {
|
||||||
iscsi_set_error(iscsi, "failed to allocate pdu header");
|
iscsi_set_error(iscsi, "failed to allocate pdu header");
|
||||||
free(pdu);
|
iscsi_free(iscsi, pdu);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(pdu->outdata.data, 0, pdu->outdata.size);
|
|
||||||
|
|
||||||
/* opcode */
|
/* opcode */
|
||||||
pdu->outdata.data[0] = opcode;
|
pdu->outdata.data[0] = opcode;
|
||||||
@@ -72,6 +73,13 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode
|
|||||||
return pdu;
|
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 *
|
struct iscsi_pdu *
|
||||||
iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode,
|
||||||
enum iscsi_opcode response_opcode)
|
enum iscsi_opcode response_opcode)
|
||||||
@@ -79,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);
|
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
|
void
|
||||||
@@ -89,18 +104,18 @@ iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pdu->outdata.data);
|
iscsi_free(iscsi, pdu->outdata.data);
|
||||||
pdu->outdata.data = NULL;
|
pdu->outdata.data = NULL;
|
||||||
|
|
||||||
free(pdu->indata.data);
|
iscsi_free(iscsi, pdu->indata.data);
|
||||||
pdu->indata.data = NULL;
|
pdu->indata.data = NULL;
|
||||||
|
|
||||||
if (pdu->scsi_cbdata) {
|
if (pdu->scsi_cbdata) {
|
||||||
iscsi_free_scsi_cbdata(pdu->scsi_cbdata);
|
iscsi_free_scsi_cbdata(iscsi, pdu->scsi_cbdata);
|
||||||
pdu->scsi_cbdata = NULL;
|
pdu->scsi_cbdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pdu);
|
iscsi_free(iscsi, pdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -108,8 +123,7 @@ int
|
|||||||
iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
|
iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
|
||||||
unsigned char *dptr, int dsize, int pdualignment)
|
unsigned char *dptr, int dsize, int pdualignment)
|
||||||
{
|
{
|
||||||
int len, aligned;
|
size_t len, aligned;
|
||||||
unsigned char *buf;
|
|
||||||
|
|
||||||
if (dsize == 0) {
|
if (dsize == 0) {
|
||||||
iscsi_set_error(iscsi, "Trying to append zero size data to "
|
iscsi_set_error(iscsi, "Trying to append zero size data to "
|
||||||
@@ -122,25 +136,36 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
|
|||||||
if (pdualignment) {
|
if (pdualignment) {
|
||||||
aligned = (aligned+3)&0xfffffffc;
|
aligned = (aligned+3)&0xfffffffc;
|
||||||
}
|
}
|
||||||
buf = malloc(aligned);
|
|
||||||
if (buf == NULL) {
|
size_t 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) {
|
||||||
|
data->data = iscsi_malloc(iscsi, new_alloc_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (data->alloc_size != new_alloc_size) {
|
||||||
|
data->data = iscsi_realloc(iscsi, data->data, new_alloc_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->data == NULL) {
|
||||||
iscsi_set_error(iscsi, "failed to allocate buffer for %d "
|
iscsi_set_error(iscsi, "failed to allocate buffer for %d "
|
||||||
"bytes", len);
|
"bytes", (int) len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->size > 0) {
|
data->alloc_size = new_alloc_size;
|
||||||
memcpy(buf, data->data, data->size);
|
memcpy(data->data + data->size, dptr, dsize);
|
||||||
}
|
|
||||||
memcpy(buf + data->size, dptr, dsize);
|
|
||||||
if (len != aligned) {
|
if (len != aligned) {
|
||||||
/* zero out any padding at the end */
|
/* zero out any padding at the end */
|
||||||
memset(buf+len, 0, aligned-len);
|
memset(data->data+len, 0, aligned-len);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data->data);
|
|
||||||
|
|
||||||
data->data = buf;
|
|
||||||
data->size = len;
|
data->size = len;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+64
-13
@@ -46,6 +46,12 @@
|
|||||||
#include "iscsi-private.h"
|
#include "iscsi-private.h"
|
||||||
#include "slist.h"
|
#include "slist.h"
|
||||||
|
|
||||||
|
static uint32_t iface_rr = 0;
|
||||||
|
|
||||||
|
void iscsi_decrement_iface_rr() {
|
||||||
|
iface_rr--;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_nonblocking(int fd)
|
static void set_nonblocking(int fd)
|
||||||
{
|
{
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -122,7 +128,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = strdup(portal);
|
addr = iscsi_strdup(iscsi, portal);
|
||||||
if (addr == NULL) {
|
if (addr == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: "
|
iscsi_set_error(iscsi, "Out-of-memory: "
|
||||||
"Failed to strdup portal address.");
|
"Failed to strdup portal address.");
|
||||||
@@ -151,7 +157,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
host ++;
|
host ++;
|
||||||
str = strchr(host, ']');
|
str = strchr(host, ']');
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
free(addr);
|
iscsi_free(iscsi, addr);
|
||||||
iscsi_set_error(iscsi, "Invalid target:%s "
|
iscsi_set_error(iscsi, "Invalid target:%s "
|
||||||
"Missing ']' in IPv6 address", portal);
|
"Missing ']' in IPv6 address", portal);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -161,12 +167,12 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
|
|
||||||
/* is it a hostname ? */
|
/* is it a hostname ? */
|
||||||
if (getaddrinfo(host, NULL, NULL, &ai) != 0) {
|
if (getaddrinfo(host, NULL, NULL, &ai) != 0) {
|
||||||
free(addr);
|
iscsi_free(iscsi, addr);
|
||||||
iscsi_set_error(iscsi, "Invalid target:%s "
|
iscsi_set_error(iscsi, "Invalid target:%s "
|
||||||
"Can not resolv into IPv4/v6.", portal);
|
"Can not resolv into IPv4/v6.", portal);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free(addr);
|
iscsi_free(iscsi, addr);
|
||||||
|
|
||||||
switch (ai->ai_family) {
|
switch (ai->ai_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
@@ -216,6 +222,31 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
set_tcp_syncnt(iscsi);
|
set_tcp_syncnt(iscsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __linux
|
||||||
|
if (iscsi->bind_interfaces[0]) {
|
||||||
|
char *pchr = iscsi->bind_interfaces, *pchr2;
|
||||||
|
int iface_n = iface_rr++%iscsi->bind_interfaces_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;}
|
||||||
|
iface_c++;
|
||||||
|
} while (pchr2);
|
||||||
|
|
||||||
|
int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr));
|
||||||
|
if (res < 0) {
|
||||||
|
ISCSI_LOG(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno));
|
||||||
|
} else {
|
||||||
|
ISCSI_LOG(iscsi,3,"successfully bound to interface '%s'",pchr);
|
||||||
|
}
|
||||||
|
if (pchr2) pchr2[0]=',';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (connect(iscsi->fd, ai->ai_addr, socksize) != 0
|
if (connect(iscsi->fd, ai->ai_addr, socksize) != 0
|
||||||
&& errno != EINPROGRESS) {
|
&& errno != EINPROGRESS) {
|
||||||
iscsi_set_error(iscsi, "Connect failed with errno : "
|
iscsi_set_error(iscsi, "Connect failed with errno : "
|
||||||
@@ -297,12 +328,11 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
|||||||
ssize_t data_size, count;
|
ssize_t data_size, count;
|
||||||
|
|
||||||
if (iscsi->incoming == NULL) {
|
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) {
|
if (iscsi->incoming == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu");
|
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(iscsi->incoming, 0, sizeof(struct iscsi_in_pdu));
|
|
||||||
}
|
}
|
||||||
in = iscsi->incoming;
|
in = iscsi->incoming;
|
||||||
|
|
||||||
@@ -347,7 +377,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
|||||||
/* if not, allocate one */
|
/* if not, allocate one */
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
if (in->data == NULL) {
|
if (in->data == NULL) {
|
||||||
in->data = malloc(data_size);
|
in->data = iscsi_malloc(iscsi, data_size);
|
||||||
if (in->data == NULL) {
|
if (in->data == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size);
|
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -386,7 +416,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SLIST_REMOVE(&iscsi->inqueue, current);
|
SLIST_REMOVE(&iscsi->inqueue, current);
|
||||||
iscsi_free_iscsi_in_pdu(current);
|
iscsi_free_iscsi_in_pdu(iscsi, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -567,18 +597,20 @@ iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
iscsi_free(iscsi, in->data);
|
||||||
free(in);
|
in->data=NULL;
|
||||||
|
iscsi_free(iscsi, in);
|
||||||
|
in=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
while (inqueue != NULL) {
|
||||||
struct iscsi_in_pdu *next = inqueue->next;
|
struct iscsi_in_pdu *next = inqueue->next;
|
||||||
iscsi_free_iscsi_in_pdu(inqueue);
|
iscsi_free_iscsi_in_pdu(iscsi, inqueue);
|
||||||
inqueue = next;
|
inqueue = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -647,3 +679,22 @@ int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, in
|
|||||||
|
|
||||||
return 0;
|
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_interfaces_cnt=0;
|
||||||
|
char * pchr = interfaces;
|
||||||
|
char * pchr2 = NULL;
|
||||||
|
do {
|
||||||
|
pchr2 = strchr(pchr,',');
|
||||||
|
if (pchr2) {pchr=pchr2+1;}
|
||||||
|
iscsi->bind_interfaces_cnt++;
|
||||||
|
} while (pchr2);
|
||||||
|
ISCSI_LOG(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
|
||||||
|
ISCSI_LOG(iscsi,1,"binding to an interface is not supported on your OS");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
+3
-3
@@ -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\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\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\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\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\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
|
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
|
||||||
rem create a linklibrary/dll
|
rem create a linklibrary/dll
|
||||||
rem
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user