diff --git a/include/iscsi-private.h b/include/iscsi-private.h index a649254..82a328f 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -19,6 +19,7 @@ #include #include +#include #if defined(_WIN32) #include @@ -171,6 +172,8 @@ struct iscsi_context { struct iscsi_context *old_iscsi; int retry_cnt; int no_ua_on_reconnect; + void (*fd_dup_cb)(struct iscsi_context *iscsi, void *opaque); + void *fd_dup_opaque; }; #define ISCSI_PDU_IMMEDIATE 0x40 @@ -397,6 +400,15 @@ typedef struct iscsi_transport { int (*which_events)(struct iscsi_context *iscsi); } iscsi_transport; +static inline int iscsi_dup2(struct iscsi_context *iscsi, int oldfd, int newfd) +{ + int ret = dup2(oldfd, newfd); + if ((ret >= 0) && iscsi->fd_dup_cb) + iscsi->fd_dup_cb(iscsi, iscsi->fd_dup_opaque); + + return ret; +} + #ifdef __cplusplus } #endif diff --git a/include/iscsi.h b/include/iscsi.h index 2760fc6..c9f097d 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1648,6 +1648,12 @@ iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count); EXTERN void iscsi_set_no_ua_on_reconnect(struct iscsi_context *iscsi, int state); +/* Set callback on iscsi file descriptor on duplicating */ +EXTERN void +iscsi_set_fd_dup_cb(struct iscsi_context *iscsi, + void (*cb)(struct iscsi_context *iscsi, void *opaque), + void *opaque); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index 38b8d19..5234e46 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -454,6 +454,8 @@ static int reconnect(struct iscsi_context *iscsi, int force) tmp_iscsi->cache_allocations = iscsi->cache_allocations; tmp_iscsi->scsi_timeout = iscsi->scsi_timeout; tmp_iscsi->no_ua_on_reconnect = iscsi->no_ua_on_reconnect; + tmp_iscsi->fd_dup_cb = iscsi->fd_dup_cb; + tmp_iscsi->fd_dup_opaque = iscsi->fd_dup_opaque; tmp_iscsi->reconnect_max_retries = iscsi->reconnect_max_retries; diff --git a/lib/init.c b/lib/init.c index 031299a..6bcc761 100644 --- a/lib/init.c +++ b/lib/init.c @@ -831,3 +831,12 @@ iscsi_set_timeout(struct iscsi_context *iscsi, int timeout) iscsi->scsi_timeout = timeout; return 0; } + +void +iscsi_set_fd_dup_cb(struct iscsi_context *iscsi, + void (*cb)(struct iscsi_context *iscsi, void *opaque), + void *opaque) +{ + iscsi->fd_dup_cb = cb; + iscsi->fd_dup_opaque = opaque; +} diff --git a/lib/iser.c b/lib/iser.c index d5cc8b9..3740564 100644 --- a/lib/iser.c +++ b/lib/iser.c @@ -1525,7 +1525,7 @@ static int iser_connected_handler(struct rdma_cm_id *cma_id) { struct iscsi_context *iscsi = cma_id->context; struct iser_conn *iser_conn = iscsi->opaque; - if (dup2(iser_conn->comp_channel->fd, iscsi->fd) == -1) { + if (iscsi_dup2(iscsi, iser_conn->comp_channel->fd, iscsi->fd) == -1) { return -1; } @@ -1683,7 +1683,7 @@ iscsi_iser_connect(struct iscsi_context *iscsi, union socket_address *sa,__attri goto error; } - if (dup2(iser_conn->cma_channel->fd, iscsi->fd) < 0) { + if (iscsi_dup2(iscsi, iser_conn->cma_channel->fd, iscsi->fd) < 0) { iscsi_set_error(iscsi, "Failed dup event channel fd"); goto error; } diff --git a/lib/libiscsi.def b/lib/libiscsi.def index a32be9d..c56fe59 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -286,3 +286,4 @@ scsi_task_set_iov_out scsi_version_to_str scsi_version_descriptor_to_str win32_poll +iscsi_set_fd_dup_cb diff --git a/lib/socket.c b/lib/socket.c index 05a3e7d..aaa061a 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -228,7 +228,7 @@ static int iscsi_tcp_connect(struct iscsi_context *iscsi, union socket_address * } if (iscsi->old_iscsi && iscsi->fd != iscsi->old_iscsi->fd) { - if (dup2(iscsi->fd, iscsi->old_iscsi->fd) == -1) { + if (iscsi_dup2(iscsi, iscsi->fd, iscsi->old_iscsi->fd) == -1) { return -1; } close(iscsi->fd);