Merge remote-tracking branch 'upstream-git/master'

Conflicts:
	include/iscsi-private.h
	include/iscsi.h
	lib/connect.c
	lib/init.c
	lib/scsi-lowlevel.c
This commit is contained in:
Peter Lieven
2012-11-12 16:02:57 +01:00
21 changed files with 205 additions and 85 deletions

View File

@@ -26,7 +26,8 @@ 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/scsi-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
SONAME=$(firstword $(subst ., ,$(VERSION))) SONAME=$(firstword $(subst ., ,$(VERSION)))
SOREL=$(shell printf "%d%02d%02d" $(subst ., ,$(VERSION))) SOREL=$(shell printf "%d%02d%02d" $(subst ., ,$(VERSION)))

View File

@@ -22,7 +22,7 @@ AM_CONDITIONAL(LD_ISCSI,
[expr "$host_os" : linux > /dev/null 2>&1]) [expr "$host_os" : linux > /dev/null 2>&1])
if test "$ac_cv_prog_gcc" = yes; then if test "$ac_cv_prog_gcc" = yes; then
WARN_CFLAGS="-Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings" WARN_CFLAGS="-Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Werror"
fi fi
AC_SUBST(WARN_CFLAGS) AC_SUBST(WARN_CFLAGS)

View File

@@ -52,7 +52,7 @@ WSADATA wsaData;
struct client_state { struct client_state {
int finished; int finished;
char *message; const char *message;
int has_discovered_target; int has_discovered_target;
char *target_name; char *target_name;
char *target_address; char *target_address;

View File

@@ -130,7 +130,10 @@ struct iscsi_context {
int lun; int lun;
int no_auto_reconnect; int no_auto_reconnect;
int reconnect_deferred; int reconnect_deferred;
int debug;
int log_level;
iscsi_log_fn log_fn;
int mallocs; int mallocs;
int reallocs; int reallocs;
int frees; int frees;
@@ -309,6 +312,16 @@ void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state);
void iscsi_decrement_iface_rr(void); void iscsi_decrement_iface_rr(void);
#define ISCSI_LOG(iscsi, level, format, args...) \
do { \
if (level <= iscsi->log_level && iscsi->log_fn) { \
iscsi_log_message(iscsi, level, format, ## args); \
} \
} while (0)
void
iscsi_log_message(struct iscsi_context *iscsi, int level, const char *format, ...);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -533,7 +533,7 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi,
struct iscsi_data { struct iscsi_data {
int size; int size;
int alloc_size; size_t alloc_size;
unsigned char *data; unsigned char *data;
}; };
@@ -956,7 +956,7 @@ EXTERN int scsi_task_add_data_in_buffer(struct scsi_task *task, int len, unsigne
*/ */
EXTERN int EXTERN int
iscsi_scsi_cancel_task(struct iscsi_context *iscsi, iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
struct scsi_task *task); struct scsi_task *task);
/* /*
* This function is used when you want to cancel all scsi tasks. * This function is used when you want to cancel all scsi tasks.
@@ -968,18 +968,6 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
EXTERN void EXTERN void
iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); 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); \
if (iscsi->target_name[0]) { \
fprintf(stderr," [%s]",iscsi->target_name); \
} \
fprintf(stderr,"\n"); \
} \
} while (0);
/* /*
* This function is to set the debugging level where level is * This function is to set the debugging level where level is
* *
@@ -989,9 +977,18 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi);
* 3 = user set variables * 3 = user set variables
* 4 = function calls * 4 = function calls
* 5 = ... * 5 = ...
* 10 = everything
*/ */
EXTERN void EXTERN void
iscsi_set_debug(struct iscsi_context *iscsi, int level); iscsi_set_log_level(struct iscsi_context *iscsi, int level);
typedef void (*iscsi_log_fn)(int level, const char *mesage);
/* Set the logging function to use */
EXTERN void iscsi_set_log_fn(struct iscsi_context *iscsi, iscsi_log_fn fn);
/* predefined log function that just writes to stderr */
EXTERN void iscsi_log_to_stderr(int level, const char *message);
/* /*
* This function is to set the TCP_USER_TIMEOUT option. It has to be called after iscsi * This function is to set the TCP_USER_TIMEOUT option. It has to be called after iscsi

View File

@@ -179,7 +179,7 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi)
{ {
struct iscsi_context *iscsi = old_iscsi; struct iscsi_context *iscsi = old_iscsi;
DPRINTF(iscsi,2,"reconnect initiated"); ISCSI_LOG(iscsi, 2, "reconnect initiated");
/* This is mainly for tests, where we do not want to automatically /* This is mainly for tests, where we do not want to automatically
reconnect but rather want the commands to fail with an error reconnect but rather want the commands to fail with an error
@@ -246,8 +246,8 @@ try_again:
strncpy(iscsi->bind_interfaces,old_iscsi->bind_interfaces,MAX_STRING_SIZE); strncpy(iscsi->bind_interfaces,old_iscsi->bind_interfaces,MAX_STRING_SIZE);
iscsi->bind_interfaces_cnt = old_iscsi->bind_interfaces_cnt; iscsi->bind_interfaces_cnt = old_iscsi->bind_interfaces_cnt;
iscsi->debug = old_iscsi->debug; iscsi->log_level = old_iscsi->log_level;
iscsi->log_fn = old_iscsi->log_fn;
iscsi->tcp_user_timeout = old_iscsi->tcp_user_timeout; iscsi->tcp_user_timeout = old_iscsi->tcp_user_timeout;
iscsi->tcp_keepidle = old_iscsi->tcp_keepidle; iscsi->tcp_keepidle = old_iscsi->tcp_keepidle;
iscsi->tcp_keepcnt = old_iscsi->tcp_keepcnt; iscsi->tcp_keepcnt = old_iscsi->tcp_keepcnt;
@@ -263,7 +263,7 @@ try_again:
if (backoff > 30) { if (backoff > 30) {
backoff=30; backoff=30;
} }
DPRINTF(iscsi,1,"reconnect try %d failed, waiting %d seconds",retry,backoff); ISCSI_LOG(iscsi, 1, "reconnect try %d failed, waiting %d seconds",retry,backoff);
iscsi_destroy_context(iscsi); iscsi_destroy_context(iscsi);
sleep(backoff); sleep(backoff);
retry++; retry++;

View File

@@ -87,8 +87,8 @@ iscsi_create_context(const char *initiator_name)
strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE); strncpy(iscsi->initiator_name,initiator_name,MAX_STRING_SIZE);
iscsi->fd = -1; iscsi->fd = -1;
srand(time(NULL) ^ getpid() ^ (u_int32_t) iscsi); 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);
@@ -113,7 +113,8 @@ iscsi_create_context(const char *initiator_name)
iscsi->tcp_keepidle=30; iscsi->tcp_keepidle=30;
if (getenv("LIBISCSI_DEBUG") != NULL) { if (getenv("LIBISCSI_DEBUG") != NULL) {
iscsi_set_debug(iscsi,atoi(getenv("LIBISCSI_DEBUG"))); iscsi_set_log_level(iscsi, atoi(getenv("LIBISCSI_DEBUG")));
iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
} }
if (getenv("LIBISCSI_TCP_USER_TIMEOUT") != NULL) { if (getenv("LIBISCSI_TCP_USER_TIMEOUT") != NULL) {
@@ -276,9 +277,9 @@ iscsi_destroy_context(struct iscsi_context *iscsi)
iscsi->connect_data = NULL; iscsi->connect_data = NULL;
if (iscsi->mallocs != iscsi->frees) { if (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); 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 { } else {
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); 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)); memset(iscsi, 0, sizeof(struct iscsi_context));
@@ -291,28 +292,25 @@ void
iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, ...) iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, ...)
{ {
va_list ap; va_list ap;
char errstr[MAX_STRING_SIZE+1] = {0}; char errstr[MAX_STRING_SIZE + 1] = {0};
va_start(ap, error_string); va_start(ap, error_string);
if (vsnprintf(errstr, MAX_STRING_SIZE, error_string, ap) < 0) { if (vsnprintf(errstr, MAX_STRING_SIZE, error_string, ap) < 0) {
strncpy(errstr,"could not format error string!",MAX_STRING_SIZE); strncpy(errstr, "could not format error string!", MAX_STRING_SIZE);
} }
va_end(ap); va_end(ap);
if (iscsi != NULL) { if (iscsi != NULL) {
strncpy(iscsi->error_string,errstr,MAX_STRING_SIZE); strncpy(iscsi->error_string, errstr,MAX_STRING_SIZE);
DPRINTF(iscsi,1,"%s",iscsi->error_string); ISCSI_LOG(iscsi, 1, "%s",iscsi->error_string);
}
else {
fprintf(stderr,"libiscsi: %s\n", errstr);
} }
} }
void void
iscsi_set_debug(struct iscsi_context *iscsi, int level) iscsi_set_log_level(struct iscsi_context *iscsi, int level)
{ {
iscsi->debug = level; iscsi->log_level = level;
DPRINTF(iscsi,2,"set debug level to %d",level); ISCSI_LOG(iscsi, 2, "set log level to %d", level);
} }
const char * const char *

View File

@@ -17,6 +17,7 @@ iscsi_get_target_address
iscsi_inquiry_sync iscsi_inquiry_sync
iscsi_inquiry_task iscsi_inquiry_task
iscsi_is_logged_in iscsi_is_logged_in
iscsi_log_to_stderr
iscsi_login_async iscsi_login_async
iscsi_login_sync iscsi_login_sync
iscsi_logout_async iscsi_logout_async
@@ -64,7 +65,8 @@ iscsi_scsi_command_sync
iscsi_scsi_cancel_task iscsi_scsi_cancel_task
iscsi_service iscsi_service
iscsi_set_alias iscsi_set_alias
iscsi_set_debug iscsi_set_log_level
iscsi_set_log_fn
iscsi_set_header_digest iscsi_set_header_digest
iscsi_set_initiator_username_pwd iscsi_set_initiator_username_pwd
iscsi_set_isid_en iscsi_set_isid_en

View File

@@ -15,6 +15,7 @@ iscsi_get_target_address
iscsi_inquiry_sync iscsi_inquiry_sync
iscsi_inquiry_task iscsi_inquiry_task
iscsi_is_logged_in iscsi_is_logged_in
iscsi_log_to_stderr
iscsi_login_async iscsi_login_async
iscsi_login_sync iscsi_login_sync
iscsi_logout_async iscsi_logout_async
@@ -62,7 +63,8 @@ iscsi_scsi_command_sync
iscsi_scsi_cancel_task iscsi_scsi_cancel_task
iscsi_service iscsi_service
iscsi_set_alias iscsi_set_alias
iscsi_set_debug iscsi_set_log_level
iscsi_set_log_fn
iscsi_set_header_digest iscsi_set_header_digest
iscsi_set_initiator_username_pwd iscsi_set_initiator_username_pwd
iscsi_set_isid_en iscsi_set_isid_en

64
lib/logging.c Normal file
View File

@@ -0,0 +1,64 @@
/*
Copyright (C) 2012 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#if defined(WIN32)
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include "iscsi.h"
#include "iscsi-private.h"
#include "scsi-lowlevel.h"
void
iscsi_log_to_stderr(int level, const char *message)
{
fprintf(stderr, "libiscsi:%d %s\n", level, message);
}
void
iscsi_set_log_fn(struct iscsi_context *iscsi, iscsi_log_fn fn)
{
iscsi->log_fn = fn;
}
void
iscsi_log_message(struct iscsi_context *iscsi, int level, const char *format, ...)
{
va_list ap;
static char message[1024];
int ret;
if (iscsi->log_fn == NULL) {
return;
}
va_start(ap, format);
ret = vsnprintf(message, 1024, format, ap);
va_end(ap);
if (ret < 0) {
return;
}
iscsi->log_fn(level, message);
}

View File

@@ -1045,7 +1045,7 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
} }
if (status == SCSI_STATUS_REDIRECT && iscsi->target_address) { if (status == SCSI_STATUS_REDIRECT && iscsi->target_address) {
DPRINTF(iscsi,2,"target requests redirect to %s",iscsi->target_address); ISCSI_LOG(iscsi, 2, "target requests redirect to %s",iscsi->target_address);
pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL, pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL,
pdu->private_data); pdu->private_data);
return 0; return 0;

View File

@@ -123,7 +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;
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 "
@@ -137,7 +137,7 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
aligned = (aligned+3)&0xfffffffc; aligned = (aligned+3)&0xfffffffc;
} }
int new_alloc_size = data->alloc_size; size_t new_alloc_size = data->alloc_size;
if (new_alloc_size < 64) new_alloc_size=64; if (new_alloc_size < 64) new_alloc_size=64;
while (aligned > new_alloc_size) new_alloc_size<<=1; while (aligned > new_alloc_size) new_alloc_size<<=1;
@@ -154,7 +154,7 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data,
if (data->data == NULL) { 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;
} }

View File

@@ -48,8 +48,8 @@ scsi_free_scsi_task(struct scsi_task *task)
struct scsi_allocated_memory *mem; struct scsi_allocated_memory *mem;
while ((mem = task->mem)) { while ((mem = task->mem)) {
SLIST_REMOVE(&task->mem, mem); SLIST_REMOVE(&task->mem, mem);
free(mem); free(mem);
} }
free(task->datain.data); free(task->datain.data);
@@ -2555,3 +2555,4 @@ scsi_task_get_data_in_buffer(struct scsi_task *task, uint32_t pos, ssize_t *coun
return &sdb->data[pos]; return &sdb->data[pos];
} }

View File

@@ -92,7 +92,7 @@ int set_tcp_user_timeout(struct iscsi_context *iscsi)
iscsi_set_error(iscsi, "TCP: Failed to set tcp user timeout. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set tcp user timeout. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"TCP_USER_TIMEOUT set to %d",iscsi->tcp_user_timeout); ISCSI_LOG(iscsi, 3, "TCP_USER_TIMEOUT set to %d",iscsi->tcp_user_timeout);
return 0; return 0;
} }
@@ -106,7 +106,7 @@ int set_tcp_syncnt(struct iscsi_context *iscsi)
iscsi_set_error(iscsi, "TCP: Failed to set tcp syn retries. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set tcp syn retries. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"TCP_SYNCNT set to %d",iscsi->tcp_syncnt); ISCSI_LOG(iscsi, 3, "TCP_SYNCNT set to %d",iscsi->tcp_syncnt);
return 0; return 0;
} }
@@ -120,7 +120,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
struct addrinfo *ai = NULL; struct addrinfo *ai = NULL;
int socksize; int socksize;
DPRINTF(iscsi,2,"connecting to portal %s",portal); ISCSI_LOG(iscsi, 2, "connecting to portal %s",portal);
if (iscsi->fd != -1) { if (iscsi->fd != -1) {
iscsi_set_error(iscsi, iscsi_set_error(iscsi,
@@ -239,9 +239,9 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr)); int res = setsockopt(iscsi->fd, SOL_SOCKET, SO_BINDTODEVICE, pchr, strlen(pchr));
if (res < 0) { if (res < 0) {
DPRINTF(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno)); ISCSI_LOG(iscsi,1,"failed to bind to interface '%s': %s",pchr,strerror(errno));
} else { } else {
DPRINTF(iscsi,3,"successfully bound to interface '%s'",pchr); ISCSI_LOG(iscsi,3,"successfully bound to interface '%s'",pchr);
} }
if (pchr2) pchr2[0]=','; if (pchr2) pchr2[0]=',';
} }
@@ -275,8 +275,9 @@ iscsi_disconnect(struct iscsi_context *iscsi)
close(iscsi->fd); close(iscsi->fd);
if (iscsi->connected_portal[0]) if (iscsi->connected_portal[0]) {
DPRINTF(iscsi,2,"disconnected from portal %s",iscsi->connected_portal); ISCSI_LOG(iscsi, 2, "disconnected from portal %s",iscsi->connected_portal);
}
iscsi->fd = -1; iscsi->fd = -1;
iscsi->is_connected = 0; iscsi->is_connected = 0;
@@ -540,7 +541,7 @@ iscsi_service(struct iscsi_context *iscsi, int revents)
return iscsi_service_reconnect_if_loggedin(iscsi); return iscsi_service_reconnect_if_loggedin(iscsi);
} }
DPRINTF(iscsi,2,"connection to %s established",iscsi->connected_portal); ISCSI_LOG(iscsi, 2, "connection to %s established",iscsi->connected_portal);
iscsi->is_connected = 1; iscsi->is_connected = 1;
if (iscsi->socket_status_cb) { if (iscsi->socket_status_cb) {
@@ -617,31 +618,31 @@ iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inque
void iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value) void iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value)
{ {
iscsi->tcp_syncnt=value; iscsi->tcp_syncnt=value;
DPRINTF(iscsi,2,"TCP_SYNCNT will be set to %d on next socket creation",value); ISCSI_LOG(iscsi, 2, "TCP_SYNCNT will be set to %d on next socket creation",value);
} }
void iscsi_set_tcp_user_timeout(struct iscsi_context *iscsi, int value) void iscsi_set_tcp_user_timeout(struct iscsi_context *iscsi, int value)
{ {
iscsi->tcp_user_timeout=value; iscsi->tcp_user_timeout=value;
DPRINTF(iscsi,2,"TCP_USER_TIMEOUT will be set to %dms on next socket creation",value); ISCSI_LOG(iscsi, 2, "TCP_USER_TIMEOUT will be set to %dms on next socket creation",value);
} }
void iscsi_set_tcp_keepidle(struct iscsi_context *iscsi, int value) void iscsi_set_tcp_keepidle(struct iscsi_context *iscsi, int value)
{ {
iscsi->tcp_keepidle=value; iscsi->tcp_keepidle=value;
DPRINTF(iscsi,2,"TCP_KEEPIDLE will be set to %d on next socket creation",value); ISCSI_LOG(iscsi, 2, "TCP_KEEPIDLE will be set to %d on next socket creation",value);
} }
void iscsi_set_tcp_keepcnt(struct iscsi_context *iscsi, int value) void iscsi_set_tcp_keepcnt(struct iscsi_context *iscsi, int value)
{ {
iscsi->tcp_keepcnt=value; iscsi->tcp_keepcnt=value;
DPRINTF(iscsi,2,"TCP_KEEPCNT will be set to %d on next socket creation",value); ISCSI_LOG(iscsi, 2, "TCP_KEEPCNT will be set to %d on next socket creation",value);
} }
void iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value) void iscsi_set_tcp_keepintvl(struct iscsi_context *iscsi, int value)
{ {
iscsi->tcp_keepintvl=value; iscsi->tcp_keepintvl=value;
DPRINTF(iscsi,2,"TCP_KEEPINTVL will be set to %d on next socket creation",value); ISCSI_LOG(iscsi, 2, "TCP_KEEPINTVL will be set to %d on next socket creation",value);
} }
int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, int interval) int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, int interval)
@@ -652,27 +653,27 @@ int iscsi_set_tcp_keepalive(struct iscsi_context *iscsi, int idle, int count, in
iscsi_set_error(iscsi, "TCP: Failed to set socket option SO_KEEPALIVE. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set socket option SO_KEEPALIVE. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"SO_KEEPALIVE set to %d",value); ISCSI_LOG(iscsi, 3, "SO_KEEPALIVE set to %d",value);
#ifdef TCP_KEEPCNT #ifdef TCP_KEEPCNT
if (set_tcp_sockopt(iscsi->fd, TCP_KEEPCNT, count) != 0) { if (set_tcp_sockopt(iscsi->fd, TCP_KEEPCNT, count) != 0) {
iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive count. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive count. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"TCP_KEEPCNT set to %d",count); ISCSI_LOG(iscsi, 3, "TCP_KEEPCNT set to %d",count);
#endif #endif
#ifdef TCP_KEEPINTVL #ifdef TCP_KEEPINTVL
if (set_tcp_sockopt(iscsi->fd, TCP_KEEPINTVL, interval) != 0) { if (set_tcp_sockopt(iscsi->fd, TCP_KEEPINTVL, interval) != 0) {
iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive interval. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive interval. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"TCP_KEEPINTVL set to %d",interval); ISCSI_LOG(iscsi, 3, "TCP_KEEPINTVL set to %d",interval);
#endif #endif
#ifdef TCP_KEEPIDLE #ifdef TCP_KEEPIDLE
if (set_tcp_sockopt(iscsi->fd, TCP_KEEPIDLE, idle) != 0) { if (set_tcp_sockopt(iscsi->fd, TCP_KEEPIDLE, idle) != 0) {
iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive idle. Error %s(%d)", strerror(errno), errno); iscsi_set_error(iscsi, "TCP: Failed to set tcp keepalive idle. Error %s(%d)", strerror(errno), errno);
return -1; return -1;
} }
DPRINTF(iscsi,3,"TCP_KEEPIDLE set to %d",idle); ISCSI_LOG(iscsi, 3, "TCP_KEEPIDLE set to %d",idle);
#endif #endif
#endif #endif
@@ -691,9 +692,9 @@ void iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces)
if (pchr2) {pchr=pchr2+1;} if (pchr2) {pchr=pchr2+1;}
iscsi->bind_interfaces_cnt++; iscsi->bind_interfaces_cnt++;
} while (pchr2); } while (pchr2);
DPRINTF(iscsi,2,"will bind to one of the following %d interface(s) on next socket creation: %s",iscsi->bind_interfaces_cnt,interfaces); 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; if (!iface_rr) iface_rr=rand()%iscsi->bind_interfaces_cnt+1;
#else #else
DPRINTF(iscsi,1,"binding to an interface is not supported on your OS"); ISCSI_LOG(iscsi,1,"binding to an interface is not supported on your OS");
#endif #endif
} }

View File

@@ -1,6 +1,6 @@
Name: libiscsi Name: libiscsi
Summary: iSCSI client library Summary: iSCSI client library
Version: 1.6.0 Version: 1.7.0
Release: 1GITHASH%{?dist} Release: 1GITHASH%{?dist}
License: LGPLv2+ License: LGPLv2+
Group: System Environment/Libraries Group: System Environment/Libraries
@@ -91,6 +91,17 @@ The libiscsi-devel package includes the header files for libiscsi.
%{_libdir}/libiscsi.so %{_libdir}/libiscsi.so
%changelog %changelog
* Tue Nov 6 2012 : 1.7.0
- Lots of additional tests.
- ld_iscsi updates and bugfixes.
- Fix a protocol bug where we might send > FirstBurstLength amount of data
as unsolicited data.
- Tcp keepalive improvements.
- Debugging framework.
- Add support for redirection.
- Fix reconnect bug where we would incorrectly re-queue DATA-OUT PDUs after reconnecting.
- Add a new iscsi-readcapacity16 command.
- Squelch a huge number of compiler warnings.
* Mon Sep 3 2012 : 1.6.0 * Mon Sep 3 2012 : 1.6.0
- Lots of test updates. - Lots of test updates.
- Fix for iscsi-ls for removable media/medium not present - Fix for iscsi-ls for removable media/medium not present

View File

@@ -24,8 +24,11 @@
#include "iscsi.h" #include "iscsi.h"
#include "scsi-lowlevel.h" #include "scsi-lowlevel.h"
const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-inq"; #ifndef discard_const
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#endif
const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-inq";
void inquiry_block_limits(struct scsi_inquiry_block_limits *inq) void inquiry_block_limits(struct scsi_inquiry_block_limits *inq)
{ {
@@ -216,7 +219,7 @@ int main(int argc, const char *argv[])
struct iscsi_context *iscsi; struct iscsi_context *iscsi;
const char **extra_argv; const char **extra_argv;
int extra_argc = 0; int extra_argc = 0;
char *url = NULL; const char *url = NULL;
struct iscsi_url *iscsi_url = NULL; struct iscsi_url *iscsi_url = NULL;
int evpd = 0, pagecode = 0; int evpd = 0, pagecode = 0;
int show_help = 0, show_usage = 0, debug = 0; int show_help = 0, show_usage = 0, debug = 0;
@@ -265,9 +268,10 @@ int main(int argc, const char *argv[])
exit(10); exit(10);
} }
if (debug > 0) { if (debug > 0) {
iscsi_set_debug(iscsi, debug); iscsi_set_log_level(iscsi, debug);
} iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
}
if (url == NULL) { if (url == NULL) {
fprintf(stderr, "You must specify the URL\n"); fprintf(stderr, "You must specify the URL\n");
@@ -276,8 +280,10 @@ int main(int argc, const char *argv[])
} }
iscsi_url = iscsi_parse_full_url(iscsi, url); iscsi_url = iscsi_parse_full_url(iscsi, url);
if (url) free(url); if (url) {
free(discard_const(url));
}
if (iscsi_url == NULL) { if (iscsi_url == NULL) {
fprintf(stderr, "Failed to parse URL: %s\n", fprintf(stderr, "Failed to parse URL: %s\n",
iscsi_get_error(iscsi)); iscsi_get_error(iscsi));

View File

@@ -24,6 +24,10 @@
#include "iscsi.h" #include "iscsi.h"
#include "scsi-lowlevel.h" #include "scsi-lowlevel.h"
#ifndef discard_const
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#endif
int showluns; int showluns;
const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-ls"; const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-ls";
@@ -312,7 +316,7 @@ int main(int argc, const char *argv[])
struct client_state state; struct client_state state;
const char **extra_argv; const char **extra_argv;
int extra_argc = 0; int extra_argc = 0;
char *url = NULL; const char *url = NULL;
poptContext pc; poptContext pc;
int res; int res;
int show_help = 0, show_usage = 0, debug = 0; int show_help = 0, show_usage = 0, debug = 0;
@@ -368,13 +372,16 @@ int main(int argc, const char *argv[])
} }
if (debug > 0) { if (debug > 0) {
iscsi_set_debug(iscsi, debug); iscsi_set_log_level(iscsi, debug);
iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
} }
iscsi_url = iscsi_parse_portal_url(iscsi, url); iscsi_url = iscsi_parse_portal_url(iscsi, url);
if (url) free(url); if (url) {
free(discard_const(url));
}
if (iscsi_url == NULL) { if (iscsi_url == NULL) {
fprintf(stderr, "Failed to parse URL: %s\n", fprintf(stderr, "Failed to parse URL: %s\n",
iscsi_get_error(iscsi)); iscsi_get_error(iscsi));

View File

@@ -26,6 +26,10 @@
#include "iscsi.h" #include "iscsi.h"
#include "scsi-lowlevel.h" #include "scsi-lowlevel.h"
#ifndef discard_const
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#endif
const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-readcapacity16"; const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-readcapacity16";
void print_usage(void) void print_usage(void)
@@ -58,7 +62,7 @@ int main(int argc, const char *argv[])
struct iscsi_context *iscsi; struct iscsi_context *iscsi;
const char **extra_argv; const char **extra_argv;
int extra_argc = 0; int extra_argc = 0;
char *url = NULL; const char *url = NULL;
struct iscsi_url *iscsi_url = NULL; struct iscsi_url *iscsi_url = NULL;
int show_help = 0, show_usage = 0, debug = 0, size_only=0; int show_help = 0, show_usage = 0, debug = 0, size_only=0;
int res; int res;
@@ -108,7 +112,8 @@ int main(int argc, const char *argv[])
} }
if (debug > 0) { if (debug > 0) {
iscsi_set_debug(iscsi, debug); iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
iscsi_set_log_level(iscsi, debug);
} }
if (url == NULL) { if (url == NULL) {
@@ -118,8 +123,10 @@ int main(int argc, const char *argv[])
} }
iscsi_url = iscsi_parse_full_url(iscsi, url); iscsi_url = iscsi_parse_full_url(iscsi, url);
if (url) free(url); if (url) {
free(discard_const(url));
}
if (iscsi_url == NULL) { if (iscsi_url == NULL) {
fprintf(stderr, "Failed to parse URL: %s\n", fprintf(stderr, "Failed to parse URL: %s\n",
iscsi_get_error(iscsi)); iscsi_get_error(iscsi));

View File

@@ -26,6 +26,8 @@ static int clamp_datasn;
static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu) static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu)
{ {
uint32_t datasn;
if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) { if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) {
return 0; return 0;
} }
@@ -44,7 +46,8 @@ static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu
break; break;
case 4: case 4:
/* change datasn from (0,1) to (1,0) */ /* change datasn from (0,1) to (1,0) */
*(uint32_t *)&pdu->outdata.data[36] = htonl(1 - ntohl(*(uint32_t *)&pdu->outdata.data[36])); datasn = ntohl(*(uint32_t *)&pdu->outdata.data[36]);
*(uint32_t *)&pdu->outdata.data[36] = htonl(1 - datasn);
break; break;
} }
return 0; return 0;

View File

@@ -28,17 +28,20 @@ uint32_t block_size;
static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu) static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu)
{ {
uint32_t buffer_offset;
if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) { if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) {
return 0; return 0;
} }
buffer_offset = ntohl(*(uint32_t *)&pdu->outdata.data[40]);
switch (change_bufferoffset) { switch (change_bufferoffset) {
case 1: case 1:
/* Add 1M to the buffer offset */ /* Add 1M to the buffer offset */
*(uint32_t *)&pdu->outdata.data[40] = htonl(ntohl(*(uint32_t *)&pdu->outdata.data[40]) + 1024*1024); *(uint32_t *)&pdu->outdata.data[40] = htonl(buffer_offset + 1024*1024);
break; break;
case 2: case 2:
/* Add -'block_size' to the buffer offset */ /* Add -'block_size' to the buffer offset */
*(uint32_t *)&pdu->outdata.data[40] = htonl(ntohl(*(uint32_t *)&pdu->outdata.data[40]) - block_size); *(uint32_t *)&pdu->outdata.data[40] = htonl(buffer_offset - block_size);
break; break;
} }
return 0; return 0;

View File

@@ -34,6 +34,10 @@
#include "iscsi-private.h" #include "iscsi-private.h"
#include "iscsi-test.h" #include "iscsi-test.h"
#ifndef discard_const
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
#endif
const char *initiatorname1 = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-test"; const char *initiatorname1 = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-test";
const char *initiatorname2 = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-test-2"; const char *initiatorname2 = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-test-2";
@@ -478,7 +482,7 @@ int main(int argc, const char *argv[])
free(skipname); free(skipname);
free(testname); free(testname);
free(url); free(discard_const(url));
return num_failed ? num_failed : num_skipped ? 77 : 0; return num_failed ? num_failed : num_skipped ? 77 : 0;
} }