mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-06 14:56:51 +08:00
b65405439d
* "Simultaneous and equivalent" Read-Write and Write-Only channels for file I/O. * Only supports drivers with the H5FD_FEAT_DEFAULT_VFD_COMPATIBLE flag for now, preventing issues with multi-file drivers. Add Mirror VFD to library. * Write-only operations over a network. * Uses TCP/IP sockets. * Server and auxiliary server-shutdown programs provided in a new directory, `utils/mirror_vfd`. * Automated testing via loopback ("remote" of localhost).
226 lines
7.2 KiB
C
226 lines
7.2 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Copyright by The HDF Group. *
|
||
* All rights reserved. *
|
||
* *
|
||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||
* terms governing use, modification, and redistribution, is contained in *
|
||
* the COPYING file, which can be found at the root of the source code *
|
||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||
* If you do not have access to either file, you may request a copy from *
|
||
* help@hdfgroup.org. *
|
||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
||
/* Common operations for "remote" processes for the Mirror VFD.
|
||
*
|
||
* Jacob Smith, 2020-03-06
|
||
*/
|
||
|
||
#include "mirror_remote.h"
|
||
|
||
#ifdef H5_HAVE_MIRROR_VFD
|
||
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
* Function: mirror_log
|
||
*
|
||
* Purpose: Write message to the logging stream/file.
|
||
* If logging info pointer is NULL, uses logging defaults.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
void
|
||
mirror_log(struct mirror_log_info *info,
|
||
unsigned int level,
|
||
const char *format,
|
||
...)
|
||
{
|
||
FILE *stream = MIRROR_LOG_DEFAULT_STREAM;
|
||
unsigned int verbosity = MIRROR_LOG_DEFAULT_VERBOSITY;
|
||
hbool_t custom = FALSE;
|
||
|
||
if (info != NULL && info->magic == MIRROR_LOG_INFO_MAGIC) {
|
||
stream = info->stream;
|
||
verbosity = info->verbosity;
|
||
custom = TRUE;
|
||
}
|
||
|
||
if (level == V_NONE) {
|
||
return;
|
||
}
|
||
else
|
||
if (level <= verbosity) {
|
||
if (custom == TRUE && info->prefix[0] != '\0') {
|
||
HDfprintf(stream, "%s", info->prefix);
|
||
}
|
||
|
||
switch (level) {
|
||
case (V_ERR) :
|
||
HDfprintf(stream, "ERROR ");
|
||
break;
|
||
case (V_WARN) :
|
||
HDfprintf(stream, "WARNING ");
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (format != NULL) {
|
||
va_list args;
|
||
HDva_start(args, format);
|
||
HDvfprintf(stream, format, args);
|
||
HDva_end(args);
|
||
}
|
||
|
||
HDfprintf(stream, "\n");
|
||
HDfflush(stream);
|
||
} /* end if sufficiently verbose to print */
|
||
} /* end mirror_log() */
|
||
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
* Function: session_log_bytes
|
||
*
|
||
* Purpose: "Pretty-print" raw binary data to logging stream/file.
|
||
* If info pointer is NULL, uses logging defaults.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
void
|
||
mirror_log_bytes(struct mirror_log_info *info,
|
||
unsigned int level,
|
||
size_t n_bytes,
|
||
const unsigned char *buf)
|
||
{
|
||
FILE *stream = MIRROR_LOG_DEFAULT_STREAM;
|
||
unsigned int verbosity = MIRROR_LOG_DEFAULT_VERBOSITY;
|
||
|
||
if (buf == NULL) {
|
||
return;
|
||
}
|
||
|
||
if (info != NULL && info->magic == MIRROR_LOG_INFO_MAGIC) {
|
||
stream = info->stream;
|
||
verbosity = info->verbosity;
|
||
}
|
||
|
||
if (level <= verbosity) {
|
||
size_t bytes_written = 0;
|
||
const unsigned char *b = NULL;
|
||
|
||
/* print whole lines */
|
||
while ((n_bytes - bytes_written) >= 32) {
|
||
b = buf + bytes_written; /* point to region in buffer */
|
||
HDfprintf(stream,
|
||
"%04zX %02X%02X%02X%02X %02X%02X%02X%02X" \
|
||
" %02X%02X%02X%02X %02X%02X%02X%02X" \
|
||
" %02X%02X%02X%02X %02X%02X%02X%02X" \
|
||
" %02X%02X%02X%02X %02X%02X%02X%02X\n",
|
||
bytes_written,
|
||
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
|
||
b[8], b[9], b[10],b[11], b[12],b[13],b[14],b[15],
|
||
b[16],b[17],b[18],b[19], b[20],b[21],b[22],b[23],
|
||
b[24],b[25],b[26],b[27], b[28],b[29],b[30],b[31]);
|
||
bytes_written += 32;
|
||
}
|
||
|
||
/* start partial line */
|
||
if (n_bytes > bytes_written) {
|
||
HDfprintf(stream, "%04zX ", bytes_written);
|
||
}
|
||
|
||
/* partial line blocks */
|
||
while ((n_bytes - bytes_written) >= 4) {
|
||
HDfprintf(stream, " %02X%02X%02X%02X",
|
||
buf[bytes_written], buf[bytes_written+1],
|
||
buf[bytes_written+2], buf[bytes_written+3]);
|
||
bytes_written += 4;
|
||
}
|
||
|
||
/* block separator before partial block */
|
||
if (n_bytes > bytes_written) {
|
||
HDfprintf(stream, " ");
|
||
}
|
||
|
||
/* partial block individual bytes */
|
||
while (n_bytes > bytes_written) {
|
||
HDfprintf(stream, "%02X", buf[bytes_written++]);
|
||
}
|
||
|
||
/* end partial line */
|
||
HDfprintf(stream, "\n");
|
||
} /* end if suitably verbose to log */
|
||
} /* end mirror_log_bytes() */
|
||
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
* Function: mirror_log_init
|
||
*
|
||
* Purpose: Prepare a loginfo_t structure for use.
|
||
*
|
||
* Return: Success: Pointer to newly-ceated info.
|
||
* Failure: NULL. Either unable to allocate or cannot open file.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
loginfo_t *
|
||
mirror_log_init(char *path, char *prefix, unsigned int verbosity)
|
||
{
|
||
loginfo_t *info = NULL;
|
||
|
||
info = (loginfo_t *)HDmalloc(sizeof(loginfo_t));
|
||
if (info != NULL) {
|
||
info->magic = MIRROR_LOG_INFO_MAGIC;
|
||
info->verbosity = verbosity;
|
||
info->stream = MIRROR_LOG_DEFAULT_STREAM;
|
||
info->prefix[0] = '\0';
|
||
|
||
if (prefix && *prefix) {
|
||
HDstrncpy(info->prefix, prefix, MIRROR_LOG_PREFIX_MAX);
|
||
}
|
||
|
||
if (path && *path) {
|
||
FILE *f = NULL;
|
||
f = HDfopen(path, "w");
|
||
if (NULL == f) {
|
||
HDfprintf(MIRROR_LOG_DEFAULT_STREAM,
|
||
"WARN custom logging path could not be opened: %s\n",
|
||
path);
|
||
info->magic += 1;
|
||
HDfree(info);
|
||
}
|
||
else {
|
||
info->stream = f;
|
||
}
|
||
}
|
||
|
||
} /* end if able to allocate */
|
||
|
||
return info;
|
||
} /* end mirror_log_init() */
|
||
|
||
|
||
/* ---------------------------------------------------------------------------
|
||
* Function: mirror_log_term
|
||
*
|
||
* Purpose: Shut down and clean up a loginfo_t structure.
|
||
*
|
||
* Return: Success: SUCCEED. Resources released.
|
||
* Failure: FAIL. Indeterminite state.
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
mirror_log_term(loginfo_t *info)
|
||
{
|
||
if (info == NULL || info->magic != MIRROR_LOG_INFO_MAGIC) {
|
||
return FAIL;
|
||
}
|
||
if (info->stream != stderr || info->stream != stdout) {
|
||
if (HDfclose(info->stream) < 0) {
|
||
return FAIL;
|
||
}
|
||
}
|
||
info->magic += 1;
|
||
HDfree(info);
|
||
return SUCCEED;
|
||
} /* end mirror_log_term() */
|
||
|
||
#endif /* H5_HAVE_MIRROR_VFD */
|
||
|