Files
s390-tools/zdump/zgetdump.c
Marc Hartmayer f957d895cd zdump: consolidate error reporting
Consolidate error reporting to make sure that error messages are used
consistently. In addition, don't call `zg_exit()` directly, but instead
return the value 1 in `main()`.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-11-03 17:45:38 +01:00

240 lines
4.4 KiB
C

/*
* zgetdump - Tool for copying and converting System z dumps
*
* Main functions
*
* Copyright IBM Corp. 2001, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <linux/fs.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "zgetdump.h"
#include "dt.h"
#include "dfi.h"
#include "dfo.h"
#include "output.h"
#include "zfuse.h"
/*
* Globals
*/
struct zgetdump_globals g;
/*
* Signal handler for exiting zgetdump (the atexit handler will do the work)
*/
static void sig_exit(int sig)
{
(void) sig;
STDERR("\n"); /* E.g. to get newline after '^C' */
ERR_EXIT("Got signal %i, exiting...", sig);
}
/*
* Install signal handler
*/
static void sig_handler_init(void)
{
struct sigaction sigact = { 0 };
/* Ignore signals SIGUSR1 and SIGUSR2 */
if (sigemptyset(&sigact.sa_mask) < 0)
goto fail;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGUSR1, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGUSR2, &sigact, NULL) < 0)
goto fail;
/* Exit on SIGINT, SIGTERM, SIGHUP, ... */
if (sigemptyset(&sigact.sa_mask) < 0)
goto fail;
sigact.sa_handler = sig_exit;
if (sigaction(SIGINT, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGTERM, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGHUP, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGQUIT, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGALRM, &sigact, NULL) < 0)
goto fail;
if (sigaction(SIGPIPE, &sigact, NULL) < 0)
goto fail;
return;
fail:
ERR_EXIT_ERRNO("Could not initialize signal handler");
}
/*
* Check if dump contains kdump dump and production system dump
*/
static void kdump_select_check(void)
{
static char *msg =
"The dump contains \"kdump\" and \"production system\"\n"
" Access \"production system\" with \"-s prod\"\n"
" Access \"kdump\" with \"-s kdump\"\n"
" Access the complete dump with \"-s all\"\n"
" Send both dumps to your service organization";
if (g.opts.select_specified)
return;
if (!dfi_kdump_base())
return;
ERR_EXIT("%s", msg);
}
static int dfi_init_error(int UNUSED(rc))
{
STDERR("Dump cannot be processed (is not complete)\n");
return 1;
}
/*
* Run "--umount" action
*/
static int do_umount(void)
{
zfuse_umount();
return 0;
}
/*
* Run "--device" action
*/
static int do_device_info(void)
{
dt_init();
dt_info_print();
return 0;
}
/*
* Run "--info" action
*/
static int do_dump_info(void)
{
int rc;
rc = dfi_init();
if (rc != 0) {
dfi_info_print();
STDERR("\n");
return dfi_init_error(rc);
}
kdump_select_check();
dfi_info_print();
dfi_exit();
return 0;
}
/*
* Run "--mount" action
*/
static int do_mount(void)
{
int rc;
rc = dfi_init();
if (rc != 0)
return dfi_init_error(rc);
dfo_init();
kdump_select_check();
rc = zfuse_mount_dump();
dfi_exit();
return rc;
}
static FILE *open_file_for_writing(const char *output)
{
FILE *stream;
int fd;
if (output) {
fd = open(output,
O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC,
0600);
if (fd == -1)
ERR_EXIT_ERRNO("Could not open '%s' exclusively", output);
} else {
fd = dup(STDOUT_FILENO);
if (fd == -1)
ERR_EXIT_ERRNO("Could not dup() stdout");
}
stream = fdopen(fd, "w");
if (!stream)
ERR_EXIT_ERRNO("Could not fdopen()");
fd = -1;
return stream;
}
/*
* Run "copy to output" action
*/
static int do_copy(const char *output)
{
FILE *stream;
int rc;
rc = dfi_init();
if (rc != 0)
return dfi_init_error(rc);
dfo_init();
kdump_select_check();
stream = open_file_for_writing(output);
rc = write_dump(stream);
fclose(stream);
dfi_exit();
return rc;
}
/*
* The zgetdump main function
*/
int main(int argc, char *argv[])
{
sig_handler_init();
opts_parse(argc, argv, &g.opts);
if (dfo_set(g.opts.fmt) != 0)
ERR_EXIT("Invalid target format \"%s\" specified", g.opts.fmt);
switch (g.opts.action) {
case ZG_ACTION_COPY:
return do_copy(g.opts.output_path);
case ZG_ACTION_DUMP_INFO:
return do_dump_info();
case ZG_ACTION_DEVICE_INFO:
return do_device_info();
case ZG_ACTION_MOUNT:
return do_mount();
case ZG_ACTION_UMOUNT:
return do_umount();
}
ABORT("Invalid action: %i", g.opts.action);
}