Add a logging subsystem and change all DPRINTF to ISCSI_LOG

Add a mechanism where we can set a logging subsystem that libiscsi can use.
Create an example 'log to stderr' that utilities can use for convenience.
This commit is contained in:
Ronnie Sahlberg
2012-11-07 06:34:38 -08:00
parent c10ae3ae3e
commit 50e7c682bb
13 changed files with 134 additions and 51 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

@@ -127,7 +127,9 @@ 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;
}; };
#define ISCSI_PDU_IMMEDIATE 0x40 #define ISCSI_PDU_IMMEDIATE 0x40
@@ -284,6 +286,16 @@ 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);
#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

@@ -966,18 +966,6 @@ iscsi_scsi_task_cancel(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
* *
@@ -987,9 +975,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

@@ -177,7 +177,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
@@ -235,10 +235,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);
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;
@@ -254,7 +254,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

@@ -76,7 +76,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) {
@@ -243,25 +244,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);
} }
} }
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_task_cancel iscsi_scsi_task_cancel
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_task_cancel iscsi_scsi_task_cancel
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

@@ -1075,7 +1075,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

@@ -86,7 +86,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;
} }
@@ -100,7 +100,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;
} }
@@ -114,7 +114,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,
@@ -244,8 +244,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;
@@ -510,7 +511,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) {
@@ -585,31 +586,31 @@ iscsi_free_iscsi_inqueue(struct iscsi_in_pdu *inqueue)
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)
@@ -620,27 +621,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

View File

@@ -265,9 +265,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");

View File

@@ -368,7 +368,8 @@ 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);

View File

@@ -108,7 +108,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) {