summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSebastian Vater2025-10-06 15:42:16 +0200
committerSebastian Vater2025-10-06 15:42:16 +0200
commit539c05839d6126f592fd06e364c75cb9ac2da96f (patch)
treef88194f9153c7f539d791e3f1f807107a2ffebb0 /src
parent[SERVER] iscsi: Implement relaying requests to uplink servers (diff)
downloaddnbd3-539c05839d6126f592fd06e364c75cb9ac2da96f.tar.gz
dnbd3-539c05839d6126f592fd06e364c75cb9ac2da96f.tar.xz
dnbd3-539c05839d6126f592fd06e364c75cb9ac2da96f.zip
Moved uplink mutex / condition init and destroy to task creation and destruction functions. Finally, some small code refactoring.
Diffstat (limited to 'src')
-rw-r--r--src/server/iscsi.c87
-rw-r--r--src/server/iscsi.h12
2 files changed, 62 insertions, 37 deletions
diff --git a/src/server/iscsi.c b/src/server/iscsi.c
index c634013..afb1e6c 100644
--- a/src/server/iscsi.c
+++ b/src/server/iscsi.c
@@ -1312,7 +1312,7 @@ int iscsi_create()
}
globvec->flags = (ISCSI_GLOBALS_FLAGS_INIT_R2T | ISCSI_GLOBALS_FLAGS_IMMEDIATE_DATA | ISCSI_GLOBALS_FLAGS_DATA_PDU_IN_ORDER | ISCSI_GLOBALS_FLAGS_DATA_SEQ_IN_ORDER | ISCSI_GLOBALS_FLAGS_SCSI_IO_REMOVABLE | ISCSI_GLOBALS_FLAGS_SCSI_IO_WRITE_PROTECT);
- globvec->target_name_check = ISCSI_GLOBALS_TARGET_NAME_CHECK_RELAXED;
+ globvec->target_name_check = ISCSI_GLOBALS_TARGET_NAME_CHECK_FULL;
globvec->max_sessions = 0U;
globvec->header_digest = 0;
globvec->data_digest = 0;
@@ -2871,6 +2871,20 @@ iscsi_task *iscsi_task_create(iscsi_connection *conn, iscsi_task *parent, iscsi_
iscsi_scsi_task_create( &task->scsi_task, callback, iscsi_task_destroy_callback );
+ if ( pthread_mutex_init( &task->scsi_task.uplink_mutex, NULL ) != 0 ) {
+ logadd( LOG_ERROR, "iscsi_task_create: Error while initializing DNBD3 uplink mutex for iSCSI SCSI task" );
+
+ return NULL;
+ }
+
+ if ( pthread_cond_init( &task->scsi_task.uplink_cond, NULL ) != 0 ) {
+ logadd( LOG_ERROR, "iscsi_task_create: Error while initializing DNBD3 uplink condition for iSCSI SCSI task" );
+
+ pthread_mutex_destroy( &task->scsi_task.uplink_mutex );
+
+ return NULL;
+ }
+
if ( parent != NULL ) {
parent->scsi_task.ref++;
@@ -2917,6 +2931,9 @@ void iscsi_task_destroy_callback(iscsi_scsi_task *scsi_task)
task->parent = NULL;
}
+ pthread_cond_destroy( &task->scsi_task.uplink_cond );
+ pthread_mutex_destroy( &task->scsi_task.uplink_mutex );
+
if ( task->pdu != NULL ) {
iscsi_connection_pdu_destroy( task->pdu );
@@ -3852,13 +3869,13 @@ void iscsi_scsi_task_create(iscsi_scsi_task *scsi_task, iscsi_scsi_task_xfer_com
scsi_task->target_port = NULL;
scsi_task->init_port = NULL;
scsi_task->cdb = NULL;
+ scsi_task->sense_data = NULL;
scsi_task->xfer_complete_callback = xfer_complete_callback;
scsi_task->destroy_callback = destroy_callback;
scsi_task->io_complete_callback = NULL;
scsi_task->io_wait.image = NULL;
scsi_task->io_wait.callback = NULL;
scsi_task->io_wait.user_data = NULL;
- scsi_task->sense_data = NULL;
scsi_task->buf = NULL;
scsi_task->pos = 0UL;
scsi_task->len = 0UL;
@@ -5273,20 +5290,28 @@ static uint64_t iscsi_scsi_emu_blocks_to_bytes(uint64_t *offset_bytes, const uin
/**
* @brief Called when data requested via an uplink server has arrived.
*
- * @param[in] data related scsi_task
- * @param[in] handle pointer to destination buffer, as passed to iscsi_scsi_emu_io_block_read()
- * @param[in] start start of range in bytes
- * @param[in] length length of range in bytes, as passed to uplink_request()
- * @param[in] buffer data for requested range
+ * This function is used to retrieve
+ * block data which is NOT locally
+ * available.
+ *
+ * @param[in] data Pointer to related scsi_task. May NOT
+ * be NULL, so be careful.
+ * @param[in] handle Pointer to destination buffer, as passed to
+ * iscsi_scsi_emu_io_block_read().
+ * @param[in] start Start of range in bytes.
+ * @param[in] length Length of range in bytes, as passed to
+ * uplink_request().
+ * @param[in] buffer Data for requested range.
*/
static void iscsi_uplink_callback(void *data, uint64_t handle, uint64_t start UNUSED, uint32_t length, const char *buffer)
{
- iscsi_scsi_task *scsi_task = (iscsi_scsi_task*)data;
+ iscsi_scsi_task *scsi_task = (iscsi_scsi_task *) data;
- memcpy( (uint8_t*)handle, buffer, length );
- pthread_mutex_lock( &scsi_task->up_mutex );
- pthread_cond_signal( &scsi_task->up_cond );
- pthread_mutex_unlock( &scsi_task->up_mutex );
+ memcpy( (uint8_t *) handle, buffer, length );
+
+ pthread_mutex_lock( &scsi_task->uplink_mutex );
+ pthread_cond_signal( &scsi_task->uplink_cond );
+ pthread_mutex_unlock( &scsi_task->uplink_mutex );
}
/**
@@ -5325,7 +5350,7 @@ int iscsi_scsi_emu_io_block_read(iscsi_scsi_task *scsi_task, uint8_t *buf, dnbd3
iscsi_connection_exec_queue *exec_queue = (iscsi_connection_exec_queue *) malloc( sizeof(struct iscsi_connection_exec_queue) );
if ( exec_queue == NULL ) {
- logadd( LOG_ERROR, "iscsi_scsi_emu_io_block_read: Out of memory while allocating execution queue for async I/O" );
+ logadd( LOG_ERROR, "iscsi_scsi_emu_io_block_read: Out of memory while allocating execution queue for I/O read" );
return -ENOMEM;
}
@@ -5337,38 +5362,38 @@ int iscsi_scsi_emu_io_block_read(iscsi_scsi_task *scsi_task, uint8_t *buf, dnbd3
readFromFile = true;
} else {
// This is a proxyed image, check if we need to relay the request...
- const uint64_t start = offset_bytes & ~(uint64_t)(DNBD3_BLOCK_SIZE - 1);
- const uint64_t end = (offset_bytes + num_bytes + DNBD3_BLOCK_SIZE - 1) & ~(uint64_t)(DNBD3_BLOCK_SIZE - 1);
+ const uint64_t start = (offset_bytes & ~(uint64_t)(DNBD3_BLOCK_SIZE - 1));
+ const uint64_t end = ((offset_bytes + num_bytes + DNBD3_BLOCK_SIZE - 1) & ~(uint64_t) (DNBD3_BLOCK_SIZE - 1));
+
readFromFile = image_isRangeCachedUnsafe( cache, start, end );
ref_put( &cache->reference );
if ( !readFromFile ) {
// Not cached, request via uplink
- pthread_mutex_init( &scsi_task->up_mutex, NULL );
- pthread_cond_init( &scsi_task->up_cond, NULL );
- pthread_mutex_lock( &scsi_task->up_mutex );
- if ( !uplink_request( image, scsi_task, &iscsi_uplink_callback, (uint64_t)buf, offset_bytes, num_bytes ) ) {
- pthread_mutex_unlock( &scsi_task->up_mutex );
- pthread_cond_destroy( &scsi_task->up_cond );
- pthread_mutex_destroy( &scsi_task->up_mutex );
+ pthread_mutex_lock( &scsi_task->uplink_mutex );
+
+ if ( !uplink_request( image, scsi_task, iscsi_uplink_callback, (uint64_t) buf, offset_bytes, num_bytes ) ) {
+ pthread_mutex_unlock( &scsi_task->uplink_mutex );
+
logadd( LOG_DEBUG1, "Could not relay uncached request to upstream proxy for image %s:%d",
image->name, image->rid );
+
return -EIO;
}
+
// Wait sync (Maybe use pthread_cond_timedwait to detect unavailable uplink instead of hanging...)
- pthread_cond_wait( &scsi_task->up_cond, &scsi_task->up_mutex );
- pthread_mutex_unlock( &scsi_task->up_mutex );
- pthread_cond_destroy( &scsi_task->up_cond );
- pthread_mutex_destroy( &scsi_task->up_mutex );
+ pthread_cond_wait( &scsi_task->uplink_cond, &scsi_task->uplink_mutex );
+ pthread_mutex_unlock( &scsi_task->uplink_mutex );
}
}
bool success;
+
if ( readFromFile ) {
- const int64_t len = pread( image->readFd, buf, (size_t) num_bytes, offset_bytes );
- success = ((uint64_t) len == num_bytes);
+ const int64_t len = pread( image->readFd, buf, (size_t) num_bytes, offset_bytes );
+ success = ((uint64_t) len == num_bytes);
} else {
- success = true;
+ success = true;
}
exec_queue->data.io.callback = callback;
@@ -5527,7 +5552,7 @@ int iscsi_scsi_emu_io_block_write(iscsi_scsi_task *scsi_task, uint8_t *buf, dnbd
iscsi_connection_exec_queue *exec_queue = (iscsi_connection_exec_queue *) malloc( sizeof(struct iscsi_connection_exec_queue) );
if ( exec_queue == NULL ) {
- logadd( LOG_ERROR, "iscsi_scsi_emu_io_block_read: Out of memory while allocating execution queue for async I/O" );
+ logadd( LOG_ERROR, "iscsi_scsi_emu_io_block_read: Out of memory while allocating execution queue for I/O write" );
return -ENOMEM;
}
@@ -5786,7 +5811,7 @@ static int iscsi_scsi_emu_block_write_same(dnbd3_image_t *image, iscsi_scsi_task
* @retval true The DNBD3 image has been initialized
* successfully and is readable.
* @retval false The DNBD3 image has NOT been
- * successfully and is read is not possible.
+ * successfully and reading is not possible.
*/
static bool iscsi_scsi_emu_image_init(iscsi_scsi_task *scsi_task, const bool access)
{
diff --git a/src/server/iscsi.h b/src/server/iscsi.h
index 4c284e0..7ce4122 100644
--- a/src/server/iscsi.h
+++ b/src/server/iscsi.h
@@ -10823,6 +10823,12 @@ typedef struct iscsi_scsi_task {
/// I/O task wait.
iscsi_scsi_emu_io_wait io_wait;
+ /// Uplink read mutex for sync
+ pthread_mutex_t uplink_mutex;
+
+ /// Conditional to signal uplink read complete
+ pthread_cond_t uplink_cond;
+
/// Output buffer.
uint8_t *buf;
@@ -10858,12 +10864,6 @@ typedef struct iscsi_scsi_task {
/// Task management response code.
uint8_t task_mgmt_response;
-
- /// Uplink read mutex for sync
- pthread_mutex_t up_mutex;
-
- /// Conditional to signal uplink read complete
- pthread_cond_t up_cond;
} iscsi_scsi_task;