diff options
Diffstat (limited to 'tools/src/misc/h5clear.c')
| -rw-r--r-- | tools/src/misc/h5clear.c | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/tools/src/misc/h5clear.c b/tools/src/misc/h5clear.c new file mode 100644 index 0000000..faf7d94 --- /dev/null +++ b/tools/src/misc/h5clear.c @@ -0,0 +1,371 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: A tool used to do the following: + * (1) -s, --status: clear the status_flags field from the file's superblock + * (2) -m, --image: remove the metadata cache image from the file + * (3) --increment=C: set the file's EOA to the maximum of (EOA, EOF) + C + * (4) --filesize: print the file's EOA and EOF + */ +#include "hdf5.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" + +/* Name of tool */ +#define PROGRAMNAME "h5clear" + +/* Make these private properties (defined in H5Fprivate.h) available to h5clear. */ +#define H5F_ACS_CLEAR_STATUS_FLAGS_NAME "clear_status_flags" +#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" +#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" + +/* Default increment is 1 megabytes for the --increment option */ +#define DEFAULT_INCREMENT (1024 * 1024) + +static char *fname_g = NULL; +static hbool_t clear_status_flags = FALSE; +static hbool_t remove_cache_image = FALSE; +static hbool_t print_filesize = FALSE; +static hbool_t increment_eoa_eof = FALSE; +static hsize_t increment = DEFAULT_INCREMENT; + +/* + * Command-line options: only publicize long options + */ +static const char *s_opts = "hVsmzi*"; +static struct h5_long_options l_opts[] = { + {"help", no_arg, 'h'}, {"version", no_arg, 'V'}, {"status", no_arg, 's'}, + {"image", no_arg, 'm'}, {"filesize", no_arg, 'z'}, {"increment", optional_arg, 'i'}, + {NULL, 0, '\0'}}; + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Prints a usage message + * + * Return: void + * + *------------------------------------------------------------------------- + */ +static void +usage(const char *prog) +{ + HDfprintf(stdout, "usage: %s [OPTIONS] file_name\n", prog); + HDfprintf(stdout, " OPTIONS\n"); + HDfprintf(stdout, " -h, --help Print a usage message and exit\n"); + HDfprintf(stdout, " -V, --version Print version number and exit\n"); + HDfprintf(stdout, " -s, --status Clear the status_flags field in the file's superblock\n"); + HDfprintf(stdout, " -m, --image Remove the metadata cache image from the file\n"); + HDfprintf(stdout, " --filesize Print the file's EOA and EOF\n"); + HDfprintf(stdout, + " --increment=C Set the file's EOA to the maximum of (EOA, EOF) + C for\n"); + HDfprintf(stdout, " the file <file_name>.\n"); + HDfprintf(stdout, + " C is >= 0; C is optional and will default to 1M when not set.\n"); + HDfprintf( + stdout, + " This option helps to repair a crashed file where the stored EOA\n"); + HDfprintf(stdout, " in the superblock is different from the actual EOF.\n"); + HDfprintf(stdout, + " The file’s EOA and EOF will be the same after applying\n"); + HDfprintf(stdout, " this option to the file.\n"); + HDfprintf(stdout, "\n"); + HDfprintf(stdout, "Examples of use:\n"); + HDfprintf(stdout, "\n"); + HDfprintf(stdout, "h5clear -s file_name\n"); + HDfprintf(stdout, " Clear the status_flags field in the superblock of the HDF5 file <file_name>.\n"); + HDfprintf(stdout, "\n"); + HDfprintf(stdout, "h5clear -m file_name\n"); + HDfprintf(stdout, " Remove the metadata cache image from the HDF5 file <file_name>.\n"); + HDfprintf(stdout, "\n"); + HDfprintf(stdout, "h5clear --increment file_name\n"); + HDfprintf(stdout, " Set the EOA to the maximum of (EOA, EOF) + 1M for the file <file_name>.\n"); + HDfprintf(stdout, "\n"); + HDfprintf(stdout, "h5clear --increment=512 file_name\n"); + HDfprintf(stdout, " Set the EOA to the maximum of (EOA, EOF) + 512 for the file <file_name>.\n"); +} /* usage() */ + +/*------------------------------------------------------------------------- + * Function: parse_command_line + * + * Purpose: Parses command line and sets up global variable to control output + * + * Return: Success: 0 + * + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static int +parse_command_line(int argc, const char *const *argv) +{ + int opt; + + /* no arguments */ + if (argc == 1) { + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + goto error; + } + + /* parse command line options */ + while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) { + switch ((char)opt) { + case 'h': + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_SUCCESS); + goto done; + + case 'V': + print_version(h5tools_getprogname()); + h5tools_setstatus(EXIT_SUCCESS); + goto done; + + case 's': + clear_status_flags = TRUE; + break; + + case 'm': + remove_cache_image = TRUE; + break; + + case 'z': + print_filesize = TRUE; + break; + + case 'i': + increment_eoa_eof = TRUE; + if (H5_optarg != NULL) { + if (HDatoi(H5_optarg) < 0) { + usage(h5tools_getprogname()); + goto done; + } + increment = (hsize_t)HDatoi(H5_optarg); + } + break; + + default: + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + goto error; + } /* end switch */ + } /* end while */ + + /* check for file name to be processed */ + if (argc <= H5_optind) { + error_msg("missing file name\n"); + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + goto error; + } /* end if */ + + fname_g = HDstrdup(argv[H5_optind]); + +done: + return (0); + +error: + return -1; +} + +/*------------------------------------------------------------------------- + * Function: leave + * + * Purpose: Close the tools library and exit + * + * Return: Does not return + * + *------------------------------------------------------------------------- + */ +static void +leave(int ret) +{ + h5tools_close(); + HDexit(ret); +} /* leave() */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: The options are: + * (1) -s, --status: clear the status_flags field from the file's superblock + * (2) -m, --image: remove the metadata cache image from the file + * (3) --increment=C: set the file's EOA to the maximum of (EOA, EOF) + C + * (4) --filesize: print the file's EOA and EOF + * + * The three options: -s, -m, and --increment will modify the file + * so the file is opened with write access. + * The --filesize option just prints the EOA and EOF, so the file + * is opened with read access. + * + * The -s option will activate the private property: + * --H5F_ACS_CLEAR_STATUS_FLAGS_NAME + * The --increment option will active these two private properties: + * --H5F_ACS_NULL_FSM_ADDR_NAME + * --H5F_ACS_SKIP_EOF_CHECK_NAME + * The --filesize will activate the private property: + * --H5F_ACS_SKIP_EOF_CHECK_NAME + * + * Return: Success: 0 + * Failure: 1 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + char *fname = NULL; /* File name */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + haddr_t image_addr; + hsize_t image_len; + unsigned flags = H5F_ACC_RDWR; /* file access flags */ + + h5tools_setprogname(PROGRAMNAME); + h5tools_setstatus(EXIT_SUCCESS); + + /* initialize h5tools lib */ + h5tools_init(); + + /* Parse command line options */ + if (parse_command_line(argc, (const char *const *)argv) < 0) + goto done; + + if (fname_g == NULL) + goto done; + + /* enable error reporting if command line option */ + h5tools_error_report(); + + /* Print usage/exit if not using at least one of the options */ + if (!clear_status_flags && !remove_cache_image && !increment_eoa_eof && !print_filesize) { + usage(h5tools_getprogname()); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + + /* Cannot combine the --filesize option with other options */ + if (print_filesize && (clear_status_flags || remove_cache_image || increment_eoa_eof)) { + error_msg("Cannot combine --filesize with other options\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + + /* Duplicate the file name */ + fname = HDstrdup(fname_g); + + /* Get a copy of the file access property list */ + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + error_msg("H5Pcreate\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + + /* -s option */ + if (clear_status_flags) { + /* Set to clear the status_flags in the file's superblock */ + /* Activate this private property */ + if (H5Pset(fapl, H5F_ACS_CLEAR_STATUS_FLAGS_NAME, &clear_status_flags) < 0) { + error_msg("H5Pset\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + + /* --increment option */ + if (increment_eoa_eof) { + /* Activate this private property */ + if (H5Pset(fapl, H5F_ACS_SKIP_EOF_CHECK_NAME, &increment_eoa_eof) < 0) { + error_msg("H5Pset\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + /* Activate this private property */ + if (H5Pset(fapl, H5F_ACS_NULL_FSM_ADDR_NAME, &increment_eoa_eof) < 0) { + error_msg("H5Pset\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + + /* --filesize option; open the file read-only */ + if (print_filesize) { + /* Activate this private property */ + if (H5Pset(fapl, H5F_ACS_SKIP_EOF_CHECK_NAME, &print_filesize) < 0) { + error_msg("H5Pset\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + flags = H5F_ACC_RDONLY; + } + + /* Open the file */ + if ((fid = h5tools_fopen(fname, flags, fapl, FALSE, NULL, (size_t)0)) < 0) { + error_msg("h5tools_fopen\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + + /* --filesize option */ + if (print_filesize) { + h5_stat_t st; /* Stat info call */ + haddr_t eoa; /* The EOA value */ + + /* Get the file's EOA and EOF */ + if (H5Fget_eoa(fid, &eoa) < 0 || HDstat(fname, &st) < 0) { + error_msg("H5Fget_eoa or HDstat\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + HDfprintf(stdout, "EOA is %" PRIuHADDR "; EOF is %" PRIuHADDR " \n", eoa, (haddr_t)st.st_size); + } + + /* --increment option */ + if (increment_eoa_eof) { + /* Set the file's EOA to the maximum of (EOA, EOF) + increment */ + if (H5Fincrement_filesize(fid, increment) < 0) { + error_msg("H5Fset_eoa\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + } + + /* -m option */ + if (remove_cache_image) { + if (H5Fget_mdc_image_info(fid, &image_addr, &image_len) < 0) { + error_msg("H5Fget_mdc_image_info\n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + if (image_addr == HADDR_UNDEF && image_len == 0) + warn_msg("No cache image in the file\n"); + } + + h5tools_setstatus(EXIT_SUCCESS); + +done: + if (fname) + HDfree(fname); + if (fname_g) + HDfree(fname_g); + + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Fclose(fid); + } + H5E_END_TRY + + leave(h5tools_getstatus()); +} /* main() */ |
