From 6c0f429805a41b6951dae678fde91b7218b09e83 Mon Sep 17 00:00:00 2001 From: Alexander Egorenkov Date: Thu, 5 Aug 2021 13:39:36 +0200 Subject: [PATCH] zdump: Implement DFI interface for NGDump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NGDump DFI interface enables zgetdump to read and mount dumps created with NGDump stand-alone dump. Under the hood, the NGDump DFI delegates the task of reading and parsing of ELF dump files to the ELF DFI interface dfi_elf. Usage example 1: ---------------- $ zgetdump -i /dev/nvme0n1p1 General dump info: Dump format........: elf Version............: 1 UTS node name......: t83lp49.lnxne.boe UTS kernel release.: 5.14.0-20210819.rc6.git0.efb8a921eec7.300.fc34.s390x UTS kernel version.: #1 SMP Thu Aug 19 00:22:04 CEST 2021 System arch........: s390x (64 bit) CPU count (online).: 32 Dump memory range..: 16384 MB Memory map: 0000000000000000 - 00000003ffffffff (16384 MB) Usage example 2: ---------------- $ zgetdump /dev/nvme0n1p1 > dump.elf Usage example 3: ---------------- $ zgetdump -m /dev/nvme0n1p1 /mnt $ ls -l /mnt/dump.elf $ zgetdump -u /mnt Signed-off-by: Alexander Egorenkov Reviewed-by: Alexander Gordeev Reviewed-by: Mikhail Zaslonko Tested-by: Mikhail Zaslonko Signed-off-by: Jan Höppner --- zdump/Makefile | 2 +- zdump/dfi.c | 1 + zdump/dfi.h | 1 + zdump/dfi_ngdump.c | 143 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 zdump/dfi_ngdump.c diff --git a/zdump/Makefile b/zdump/Makefile index 6757d65e..40c7d465 100644 --- a/zdump/Makefile +++ b/zdump/Makefile @@ -54,7 +54,7 @@ OBJECTS = zgetdump.o opts.o zg.o zg_error.o zg_print.o \ dt.o dt_s390sv.o dt_s390sv_ext.o \ dt_s390mv.o dt_s390mv_ext.o \ dt_scsi.o output.o \ - ngdump.o dt_ngdump.o + ngdump.o dt_ngdump.o dfi_ngdump.o ifeq ("$(HAVE_FUSE)","0") FUSE_CFLAGS = -DHAVE_FUSE=0 -D_FILE_OFFSET_BITS=64 diff --git a/zdump/dfi.c b/zdump/dfi.c index 0a52c355..9f30772f 100644 --- a/zdump/dfi.c +++ b/zdump/dfi.c @@ -36,6 +36,7 @@ static struct dfi *dfi_vec[] = { &dfi_elf, &dfi_kdump, &dfi_kdump_flat, + &dfi_ngdump, NULL, }; diff --git a/zdump/dfi.h b/zdump/dfi.h index 1a0e87e1..42e51ecd 100644 --- a/zdump/dfi.h +++ b/zdump/dfi.h @@ -242,5 +242,6 @@ extern struct dfi dfi_elf; extern struct dfi dfi_kdump; extern struct dfi dfi_kdump_flat; extern struct dfi dfi_devmem; +extern struct dfi dfi_ngdump; #endif /* DFI_H */ diff --git a/zdump/dfi_ngdump.c b/zdump/dfi_ngdump.c new file mode 100644 index 00000000..dce95027 --- /dev/null +++ b/zdump/dfi_ngdump.c @@ -0,0 +1,143 @@ +/* + * zgetdump - Tool for copying and converting System z dumps + * + * NGDump dump input format + * + * Copyright IBM Corp. 2021 + * + * 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 +#include + +#include "lib/util_libc.h" + +#include "zgetdump.h" +#include "zg.h" +#include "dfi.h" +#include "ngdump.h" + +/* + * File local static data + */ +static struct { + char *device; + char *mount_point; + struct ngdump_meta meta; +} l; + +static int open_dump_file(void) +{ + char *mount_point = NULL; + char *filename = NULL; + + mount_point = util_strdup("/tmp/zdump-ngdump-XXXXXX"); + + /* Create a mount point directory */ + if (mkdtemp(mount_point) == NULL) + goto fail_free; + + if (mount(l.device, mount_point, NGDUMP_FSTYPE, MS_RDONLY, NULL)) { + warnx("Could not mount \"%s\" (%s)", l.device, strerror(errno)); + goto fail_rmdir; + } + + util_asprintf(&filename, "%s/%s", mount_point, l.meta.file); + + g.fh = zg_open(filename, O_RDONLY, ZG_CHECK); + free(filename); + if (!g.fh) + goto fail_umount; + + l.mount_point = mount_point; + + return 0; + +fail_umount: + umount(mount_point); +fail_rmdir: + rmdir(mount_point); +fail_free: + free(mount_point); + return -1; +} + +static void cleanup(void) +{ + if (l.mount_point) { + zg_close(g.fh); + g.fh = NULL; + umount(l.mount_point); + rmdir(l.mount_point); + free(l.mount_point); + l.mount_point = NULL; + } + if (l.device) { + g.fh = zg_open(l.device, O_RDONLY, ZG_CHECK); + free(l.device); + l.device = NULL; + } +} + +static int dfi_ngdump_init(void) +{ + /* + * Copy path to the dump partition and close its file descriptor + * because we don't read raw partitions with NGDump but use a + * file system instead. + */ + l.device = util_strdup(g.fh->path); + zg_close(g.fh); + g.fh = NULL; + + /* + * First, we need to read information contained in the meta-data + * file because it will tell us where a dump file on the file system + * is located. + */ + if (ngdump_read_meta_from_device(l.device, &l.meta)) { + cleanup(); + return -1; + } + + /* No dump made yet but partition is a valid NGDump partition. */ + if (!l.meta.file) { + cleanup(); + return -1; + } + + /* + * Now we open the dump file and initialize the ELF DFI. + * After that, the control is passed to the ELF DFI. + */ + if (open_dump_file()) { + cleanup(); + return -1; + } + + if (dfi_elf.init()) { + cleanup(); + return -1; + } + + return 0; +} + +static void dfi_ngdump_exit(void) +{ + if (dfi_elf.exit) + dfi_elf.exit(); + cleanup(); +} + +/* + * NGDump DFI operations + */ +struct dfi dfi_ngdump = { + .name = "elf", + .init = dfi_ngdump_init, + .exit = dfi_ngdump_exit, + .feat_bits = DFI_FEAT_COPY | DFI_FEAT_SEEK, +};