From 4a223c70f2c24ee733e29265758babd8c0fbef2f Mon Sep 17 00:00:00 2001 From: Mikhail Zaslonko Date: Tue, 17 Apr 2018 21:06:00 +0200 Subject: [PATCH] zgetdump: Update zgetdump to process the new dump format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update zgetdump tool to process dumps of the new s390 extended format. Signed-off-by: Mikhail Zaslonko Signed-off-by: Jan Höppner --- zdump/Makefile | 4 +- zdump/df_s390.h | 4 + zdump/dfi.c | 69 +++++++++++++++-- zdump/dfi.h | 10 ++- zdump/dfi_s390.c | 109 ++++++++++++++++++++++++--- zdump/dfi_s390_ext.c | 29 ++++++++ zdump/dfi_s390mv.c | 163 ++++++++++++++++++++++++++++++++++------- zdump/dfi_s390mv_ext.c | 30 ++++++++ zdump/zgetdump.h | 2 + 9 files changed, 374 insertions(+), 46 deletions(-) create mode 100644 zdump/dfi_s390_ext.c create mode 100644 zdump/dfi_s390mv_ext.c diff --git a/zdump/Makefile b/zdump/Makefile index 6ada602d..e3170749 100644 --- a/zdump/Makefile +++ b/zdump/Makefile @@ -42,8 +42,8 @@ all: check_dep_fuse check_dep_zlib zgetdump OBJECTS = zgetdump.o opts.o zg.o \ dfi.o dfi_vmcoreinfo.o \ dfi_lkcd.o dfi_elf.o \ - dfi_s390.o \ - dfi_s390mv.o \ + dfi_s390.o dfi_s390_ext.o\ + dfi_s390mv.o dfi_s390mv_ext.o \ dfi_s390tape.o dfi_kdump.o \ dfi_devmem.o dfo.o \ dfo_elf.o dfo_s390.o \ diff --git a/zdump/df_s390.h b/zdump/df_s390.h index 6c7f63a4..dd272176 100644 --- a/zdump/df_s390.h +++ b/zdump/df_s390.h @@ -137,4 +137,8 @@ extern int dt_s390sv_init_gen(bool extended); extern int dt_s390mv_init_gen(bool extended); extern void dt_s390mv_info(void); +extern int dfi_s390_init_gen(bool extended); +extern int dfi_s390mv_init_gen(bool extended); +extern void dfi_s390mv_info(void); + #endif /* DF_S390_H */ diff --git a/zdump/dfi.c b/zdump/dfi.c index 3272d901..fe420b6c 100644 --- a/zdump/dfi.c +++ b/zdump/dfi.c @@ -3,7 +3,7 @@ * * Generic input dump format functions (DFI - Dump Format Input) * - * Copyright IBM Corp. 2001, 2017 + * Copyright IBM Corp. 2001, 2018 * * s390-tools is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -21,7 +21,9 @@ static struct dfi *dfi_vec[] = { &dfi_s390tape, &dfi_devmem, + &dfi_s390mv_ext, &dfi_s390mv, + &dfi_s390_ext, &dfi_s390, &dfi_lkcd, &dfi_elf, @@ -149,12 +151,31 @@ static void mem_update(struct mem *mem) static void mem_map_print(void) { struct dfi_mem_chunk *mem_chunk; + u64 print_start = 0, print_end = 0; + u32 volnr = 0; STDERR("\nMemory map:\n"); + /* + * Merge adjacent memory chunks from the same volume + */ dfi_mem_chunk_iterate(mem_chunk) { - STDERR(" %016llx - %016llx (%llu MB)\n", mem_chunk->start, - mem_chunk->end, TO_MIB(mem_chunk->size)); + if (print_end == 0) { + print_start = mem_chunk->start; + print_end = mem_chunk->end; + volnr = mem_chunk->volnr; + continue; + } + if (mem_chunk->start != print_end + 1 || + mem_chunk->volnr != volnr) { + STDERR(" %016llx - %016llx (%llu MB)\n", print_start, + print_end, TO_MIB(print_end - print_start + 1)); + print_start = mem_chunk->start; + volnr = mem_chunk->volnr; + } + print_end = mem_chunk->end; } + STDERR(" %016llx - %016llx (%llu MB)\n", print_start, + print_end, TO_MIB(print_end - print_start + 1)); } /* @@ -351,9 +372,27 @@ void dfi_mem_chunk_virt_add(u64 start, u64 size, void *data, dfi_mem_chunk_read_fn read_fn, dfi_mem_chunk_free_fn free_fn) { + if (size == 0) + return; mem_chunk_create(&l.mem_virt, start, size, data, read_fn, free_fn); } +/* + * Add memory chunk with volume index + */ +void dfi_mem_chunk_add_vol(u64 start, u64 size, void *data, + dfi_mem_chunk_read_fn read_fn, + dfi_mem_chunk_free_fn free_fn, + u32 volnr) +{ + if (size == 0) + return; + mem_chunk_create(&l.mem_phys, start, size, data, read_fn, free_fn); + mem_chunk_create(&l.mem_virt, start, size, data, read_fn, free_fn); + l.mem_virt.chunk_cache->volnr = volnr; + +} + /* * Add memory chunk */ @@ -361,8 +400,16 @@ void dfi_mem_chunk_add(u64 start, u64 size, void *data, dfi_mem_chunk_read_fn read_fn, dfi_mem_chunk_free_fn free_fn) { - mem_chunk_create(&l.mem_phys, start, size, data, read_fn, free_fn); - mem_chunk_create(&l.mem_virt, start, size, data, read_fn, free_fn); + dfi_mem_chunk_add_vol(start, size, data, read_fn, free_fn, 0); +} + +/* + * Read zero pages + */ +void dfi_mem_chunk_read_zero(struct dfi_mem_chunk *UNUSED(mem_chunk), + u64 UNUSED(off), void *buf, u64 cnt) +{ + memset(buf, 0, cnt); } /* @@ -401,6 +448,16 @@ struct dfi_mem_chunk *dfi_mem_chunk_first(void) return util_list_start(&l.mem_virt.chunk_list); } +/* + * Return last memory chunk + */ +struct dfi_mem_chunk *dfi_mem_chunk_last(void) +{ + if (util_list_is_empty(&l.mem_virt.chunk_list)) + return NULL; + return util_list_end(&l.mem_virt.chunk_list); +} + /* * Return next memory chunk */ @@ -678,7 +735,7 @@ struct new_utsname *dfi_attr_utsname(void) } /* - * Attribute: dump method + * Attribute: Dump method */ void dfi_attr_dump_method_set(char *dump_method) { diff --git a/zdump/dfi.h b/zdump/dfi.h index f591d999..47f889b1 100644 --- a/zdump/dfi.h +++ b/zdump/dfi.h @@ -3,7 +3,7 @@ * * Generic input dump format functions (DFI - Dump Format Input) * - * Copyright IBM Corp. 2001, 2017 + * Copyright IBM Corp. 2001, 2018 * * s390-tools is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. @@ -162,8 +162,15 @@ struct dfi_mem_chunk { dfi_mem_chunk_read_fn read_fn; /* Chunk read callback */ dfi_mem_chunk_free_fn free_fn; /* Free data callback */ void *data; /* Data for callback */ + u32 volnr; /* Volume id where chunk resides */ }; +extern void dfi_mem_chunk_read_zero(struct dfi_mem_chunk *UNUSED(mem_chunk), + u64 UNUSED(off), void *buf, u64 cnt); +extern void dfi_mem_chunk_add_vol(u64 start, u64 size, void *data, + dfi_mem_chunk_read_fn read_fn, + dfi_mem_chunk_free_fn free_fn, + u32 volnr); extern void dfi_mem_chunk_add(u64 start, u64 size, void *data, dfi_mem_chunk_read_fn read_fn, dfi_mem_chunk_free_fn free_fn); @@ -174,6 +181,7 @@ extern u64 dfi_mem_range(void); extern int dfi_mem_range_valid(u64 addr, u64 len); extern unsigned int dfi_mem_chunk_cnt(void); extern struct dfi_mem_chunk *dfi_mem_chunk_first(void); +extern struct dfi_mem_chunk *dfi_mem_chunk_last(void); extern struct dfi_mem_chunk *dfi_mem_chunk_next(struct dfi_mem_chunk *chunk); extern struct dfi_mem_chunk *dfi_mem_chunk_prev(struct dfi_mem_chunk *chunk); extern struct dfi_mem_chunk *dfi_mem_chunk_find(u64 addr); diff --git a/zdump/dfi_s390.c b/zdump/dfi_s390.c index 255582cf..7e8f0145 100644 --- a/zdump/dfi_s390.c +++ b/zdump/dfi_s390.c @@ -26,10 +26,11 @@ static struct { struct df_s390_hdr hdr; /* s390 dump header */ struct df_s390_em em; /* s390 end marker */ + bool extended; /* Extended input dump format */ } l; /* - * S390 mem chunk read callback + * s390 mem chunk read callback */ static void dfi_s390_mem_chunk_read(struct dfi_mem_chunk *mem_chunk, u64 off, void *buf, u64 cnt) @@ -40,16 +41,32 @@ static void dfi_s390_mem_chunk_read(struct dfi_mem_chunk *mem_chunk, u64 off, zg_read(g.fh, buf, cnt, ZG_CHECK); } +/* + * s390_ext mem chunk read callback + */ +static void dfi_s390_ext_mem_chunk_read(struct dfi_mem_chunk *mem_chunk, + u64 off, void *buf, u64 cnt) +{ + u64 *mem_chunk_off = mem_chunk->data; + + zg_seek(g.fh, *mem_chunk_off + off, ZG_CHECK); + zg_read(g.fh, buf, cnt, ZG_CHECK); +} + + /* * Read s390 dump header */ static int read_s390_hdr(void) { + u64 magic_number; + + magic_number = l.extended ? DF_S390_MAGIC_EXT : DF_S390_MAGIC; if ((zg_type(g.fh) == ZG_TYPE_FILE) && (zg_size(g.fh) < sizeof(l.hdr))) return -ENODEV; if (zg_read(g.fh, &l.hdr, sizeof(l.hdr), ZG_CHECK_ERR) != sizeof(l.hdr)) return -ENODEV; - if (l.hdr.magic != DF_S390_MAGIC) + if (l.hdr.magic != magic_number) return -ENODEV; df_s390_hdr_add(&l.hdr); return 0; @@ -62,9 +79,6 @@ static int read_s390_em(void) { u64 rc; - rc = zg_seek(g.fh, l.hdr.mem_size + DF_S390_HDR_SIZE, ZG_CHECK_NONE); - if (rc != l.hdr.mem_size + DF_S390_HDR_SIZE) - return -EINVAL; rc = zg_read(g.fh, &l.em, sizeof(l.em), ZG_CHECK_ERR); if (rc != sizeof(l.em)) return -EINVAL; @@ -75,23 +89,94 @@ static int read_s390_em(void) } /* - * Initialize s390 DFI + * Register memory chunks and verify the end marker */ -static int dfi_s390_init(void) +static int mem_chunks_add(void) { + u64 rc; + + /* Single memory chunk for non-extended dump format */ + dfi_mem_chunk_add(0, l.hdr.mem_size, NULL, + dfi_s390_mem_chunk_read, + NULL); + rc = zg_seek(g.fh, DF_S390_HDR_SIZE + l.hdr.mem_size, + ZG_CHECK_NONE); + if (rc != DF_S390_HDR_SIZE + l.hdr.mem_size) + return -EINVAL; + /* Read and verify the end marker */ + return read_s390_em(); +} + +/* + * Register memory chunks (extended dump format) and verify the end marker + */ +static int mem_chunks_add_ext(void) +{ + struct df_s390_dump_segm_hdr dump_segm; + u64 rc, *off_ptr, old = 0; + + off_ptr = zg_alloc(sizeof(*off_ptr)); + *off_ptr = zg_seek(g.fh, DF_S390_HDR_SIZE, ZG_CHECK_NONE); + if (*off_ptr != DF_S390_HDR_SIZE) + return -EINVAL; + while (*off_ptr < DF_S390_HDR_SIZE + l.hdr.mem_size - PAGE_SIZE) { + rc = zg_read(g.fh, &dump_segm, PAGE_SIZE, ZG_CHECK_ERR); + if (rc != PAGE_SIZE) + return -EINVAL; + *off_ptr += PAGE_SIZE; + /* Add zero memory chunk */ + dfi_mem_chunk_add(old, dump_segm.start - old, NULL, + dfi_mem_chunk_read_zero, NULL); + /* Add memory chunk for a dump segment */ + dfi_mem_chunk_add(dump_segm.start, dump_segm.len, off_ptr, + dfi_s390_ext_mem_chunk_read, zg_free); + old = dump_segm.start + dump_segm.len; + off_ptr = zg_alloc(sizeof(*off_ptr)); + *off_ptr = zg_seek_cur(g.fh, dump_segm.len, ZG_CHECK_NONE); + if (dump_segm.stop_marker) + break; + } + /* Add zero memory chunk at the end */ + dfi_mem_chunk_add(old, l.hdr.mem_size - old, NULL, + dfi_mem_chunk_read_zero, NULL); + /* Check if the last dump segment found */ + if (!dump_segm.stop_marker) + return -EINVAL; + /* Read and verify the end marker */ + return read_s390_em(); +} + +/* + * Initialize s390 single-volume DFI general function + */ +int dfi_s390_init_gen(bool extended) +{ + int rc; + + l.extended = extended; if (read_s390_hdr() != 0) return -ENODEV; - dfi_mem_chunk_add(0, l.hdr.mem_size, NULL, dfi_s390_mem_chunk_read, - NULL); - if (read_s390_em() != 0) - return -EINVAL; + if (!extended) + rc = mem_chunks_add(); + else + rc = mem_chunks_add_ext(); + if (rc) + return rc; df_s390_cpu_info_add(&l.hdr, l.hdr.mem_size); zg_seek(g.fh, sizeof(l.hdr), ZG_CHECK); return 0; } /* - * S390 DFI operations + * Initialize s390 single-volume DFI (non-extended) + */ +static int dfi_s390_init(void) +{ + return dfi_s390_init_gen(DUMP_NON_EXTENDED); +} + +/* + * s390 single-volume DFI (non-extended) operations */ struct dfi dfi_s390 = { .name = "s390", diff --git a/zdump/dfi_s390_ext.c b/zdump/dfi_s390_ext.c new file mode 100644 index 00000000..5794f04c --- /dev/null +++ b/zdump/dfi_s390_ext.c @@ -0,0 +1,29 @@ +/* + * zgetdump - Tool for copying and converting System z dumps + * + * S390 extended dump input format + * + * Copyright IBM Corp. 2001, 2018 + * + * 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 "zgetdump.h" + +/* + * Initialize s390 input dump format (extended) + */ +static int dfi_s390_ext_init(void) +{ + return dfi_s390_init_gen(DUMP_EXTENDED); +} + +/* + * s390 nput dump format (extedned) operations + */ +struct dfi dfi_s390_ext = { + .name = "s390_ext", + .init = dfi_s390_ext_init, + .feat_bits = DFI_FEAT_COPY | DFI_FEAT_SEEK, +}; diff --git a/zdump/dfi_s390mv.c b/zdump/dfi_s390mv.c index 4cb5af34..44dd37a2 100644 --- a/zdump/dfi_s390mv.c +++ b/zdump/dfi_s390mv.c @@ -43,6 +43,14 @@ struct vol { struct df_s390_hdr hdr; }; +/* + * Mem chunk helper structure for extended dump format + */ +struct vol_mem_chunk { + struct vol *vol; + u64 off; /* Offset to the memory chunk from the start of the volume */ +}; + /* * File local static data */ @@ -55,6 +63,7 @@ static struct { struct df_s390_dumper dumper; int dump_incomplete; bool extended; + u64 magic_number; /* Reference value to compare with */ char dumper_magic[7]; /* Reference value to compare with */ } l; @@ -86,6 +95,7 @@ static void em_init(struct vol *vol) l.dump_incomplete = 1; } + /* * Check sysfs, whether a device specified by its bus ID is defined and online. * Find out the corresponding dev_t @@ -177,9 +187,9 @@ static void vol_read(struct vol *vol) } /* - * Read memory + * Read memory chunk */ -static void df_s390mv_mem_read(struct dfi_mem_chunk *mem_chunk, u64 off, +static void dfi_s390mv_mem_read(struct dfi_mem_chunk *mem_chunk, u64 off, void *buf, u64 cnt) { struct vol *vol = mem_chunk->data; @@ -188,6 +198,19 @@ static void df_s390mv_mem_read(struct dfi_mem_chunk *mem_chunk, u64 off, zg_read(vol->fh, buf, cnt, ZG_CHECK); } +/* + * Read memory chunk (extended) + */ +static void dfi_s390mv_ext_mem_read(struct dfi_mem_chunk *mem_chunk, u64 off, + void *buf, u64 cnt) +{ + struct vol_mem_chunk *vol_mem_chunk = mem_chunk->data; + struct vol *vol = vol_mem_chunk->vol; + + zg_seek(vol->fh, vol_mem_chunk->off + off, ZG_CHECK); + zg_read(vol->fh, buf, cnt, ZG_CHECK); +} + /* * Initialize DASD volume */ @@ -214,7 +237,7 @@ static void vol_init(struct vol *vol, struct vol_parm *vol_parm, int ssid, if ((vol->hdr.volnr == vol->nr) && (vol->hdr.mem_size != 0)) vol->sign = SIGN_ACTIVE; - if (vol->hdr.mvdump_sign != DF_S390_MAGIC) { + if (vol->hdr.mvdump_sign != l.magic_number) { vol->sign = SIGN_INVALID; l.dump_incomplete = 1; } @@ -277,16 +300,83 @@ static void vol_print_all(void) */ static void mem_chunks_add(void) { + struct vol *vol; + unsigned int i; + + for (i = 0; i < l.table.vol_cnt; i++) { + vol = &l.vol_vec[i]; + if (vol->sign != SIGN_ACTIVE) + continue; + dfi_mem_chunk_add_vol(vol->mem_start, + vol->mem_end - vol->mem_start + 1, + vol, dfi_s390mv_mem_read, NULL, vol->nr); + } +} + +/* + * Add memory chunks (extended dump format) and verify the end marker + */ +static int mem_chunks_add_ext(void) +{ + u64 off, rc, part_end, old = 0; + struct df_s390_dump_segm_hdr dump_segm; + struct vol_mem_chunk *vol_mem_chunk; unsigned int i; for (i = 0; i < l.table.vol_cnt; i++) { struct vol *vol = &l.vol_vec[i]; if (vol->sign != SIGN_ACTIVE) continue; - dfi_mem_chunk_add(vol->mem_start, - vol->mem_end - vol->mem_start + 1, - vol, df_s390mv_mem_read, NULL); + off = vol->part_off + DF_S390_HDR_SIZE; + part_end = vol->part_off + vol->part_size; + rc = zg_seek(vol->fh, off, ZG_CHECK_NONE); + if (rc != off) + return -EINVAL; + /* + * Reading dump segments from the start of partition (skipping + * the dump header) till the end of partition (considering that + * minimum dump segment size is one megabyte + one page and one + * more page is reserved for the end marker) + */ + while (off < part_end - MIB - PAGE_SIZE) { + rc = zg_read(vol->fh, &dump_segm, sizeof(dump_segm), + ZG_CHECK_ERR); + if (rc != PAGE_SIZE) + return -EINVAL; + off += PAGE_SIZE; + vol_mem_chunk = zg_alloc(sizeof(*vol_mem_chunk)); + vol_mem_chunk->vol = vol; + vol_mem_chunk->off = off; + /* Add zero memory chunk */ + dfi_mem_chunk_add_vol(old, dump_segm.start - old, NULL, + dfi_mem_chunk_read_zero, NULL, + vol->nr); + /* Add memory chunk for a dump segment */ + dfi_mem_chunk_add_vol(dump_segm.start, dump_segm.len, + vol_mem_chunk, + dfi_s390mv_ext_mem_read, NULL, + vol->nr); + old = dump_segm.start + dump_segm.len; + off = zg_seek_cur(vol->fh, dump_segm.len, + ZG_CHECK_NONE); + if (dump_segm.stop_marker) + break; + } + if (dump_segm.stop_marker) { + /* Add zero memory chunk at the end*/ + dfi_mem_chunk_add_vol(old, l.hdr.mem_size - old, NULL, + dfi_mem_chunk_read_zero, NULL, + vol->nr); + /* Read and verify the end marker */ + rc = zg_read(vol->fh, &l.em, sizeof(l.em), ZG_CHECK); + if (rc != sizeof(l.em) || + df_s390_em_verify(&l.em, &l.hdr) != 0) + return -EINVAL; + return 0; + } } + /* No dump segment with the stop marker found */ + return -EINVAL; } /* @@ -364,9 +454,9 @@ static int mvdump_hdr_check(const char *file) fh = zg_open(file, O_RDONLY, ZG_CHECK); if (zg_read(fh, &hdr, sizeof(hdr), ZG_CHECK_ERR) != sizeof(hdr)) goto fail; - if (hdr.magic != DF_S390_MAGIC) + if (hdr.magic != l.magic_number) goto fail; - if (hdr.mvdump_sign != DF_S390_MAGIC) + if (hdr.mvdump_sign != l.magic_number) goto fail; rc = 0; fail: @@ -387,14 +477,6 @@ static void check_sysfs(void) closedir(fh_dir); } -/* - * Print dump information (dfi operation) - */ -static void dfi_s390mvfo_dump(void) -{ - vol_print_all(); -} - /* * Read dump tool from DASD and check if we have a multi-volume dump tool */ @@ -461,10 +543,26 @@ static int open_dump(void) } /* - * Initialize s390 multi-volume input dump format + * Specify reference values for dumper magic and dump magic numbers */ -static int dfi_s390mv_init(void) +static void set_magic_numbers(void) { + if (l.extended) { + l.magic_number = DF_S390_MAGIC_EXT; + strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7); + } else { + l.magic_number = DF_S390_MAGIC; + strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV, 7); + } +} + +/* + * Initialize s390 multi-volume input dump format generic function + */ +int dfi_s390mv_init_gen(bool extended) +{ + l.extended = extended; + set_magic_numbers(); if (open_dump() != 0) return -ENODEV; volumes_init(); @@ -473,7 +571,10 @@ static int dfi_s390mv_init(void) if (l.hdr.mem_size == 0) return -ENODEV; df_s390_hdr_add(&l.hdr); - mem_chunks_add(); + if (!extended) + mem_chunks_add(); + else if (mem_chunks_add_ext() != 0) + return -EINVAL; if (l.dump_incomplete) return -EINVAL; df_s390_cpu_info_add(&l.hdr, l.hdr.mem_end); @@ -481,17 +582,29 @@ static int dfi_s390mv_init(void) return 0; } +/* + * Initializt s390 multi-volume input dump + */ +static int dfi_s390mv_init(void) +{ + return dfi_s390mv_init_gen(DUMP_NON_EXTENDED); +} + +/* + * Print dump information (dfi operation) + */ +void dfi_s390mv_info(void) +{ + vol_print_all(); +} + /* * Initialize s390 multi-volume dump tool generic function */ int dt_s390mv_init_gen(bool extended) { l.extended = extended; - /* Specify dumper magic value for further validation */ - if (extended) - strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7); - else - strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV, 7); + set_magic_numbers(); if (open_dump() != 0) return -ENODEV; volumes_init(); @@ -516,6 +629,6 @@ void dt_s390mv_info(void) struct dfi dfi_s390mv = { .name = "s390mv", .init = dfi_s390mv_init, - .info_dump = dfi_s390mvfo_dump, + .info_dump = dfi_s390mv_info, .feat_bits = DFI_FEAT_COPY | DFI_FEAT_SEEK, }; diff --git a/zdump/dfi_s390mv_ext.c b/zdump/dfi_s390mv_ext.c new file mode 100644 index 00000000..ccc9724a --- /dev/null +++ b/zdump/dfi_s390mv_ext.c @@ -0,0 +1,30 @@ +/* + * zgetdump - Tool for copying and converting System z dumps + * + * S390x multi-volume dump input format + * + * Copyright IBM Corp. 2001, 2018 + * + * 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 "zgetdump.h" + +/* + * Initialize s390 multi-volume input dump format (extedend) + */ +static int dfi_s390mv_ext_init(void) +{ + return dfi_s390mv_init_gen(DUMP_EXTENDED); +} + +/* + * s390 multi-volume DFI (extedned) operations + */ +struct dfi dfi_s390mv_ext = { + .name = "s390mv_ext", + .init = dfi_s390mv_ext_init, + .info_dump = dfi_s390mv_info, + .feat_bits = DFI_FEAT_COPY | DFI_FEAT_SEEK, +}; diff --git a/zdump/zgetdump.h b/zdump/zgetdump.h index 30a26cbf..a1fd9919 100644 --- a/zdump/zgetdump.h +++ b/zdump/zgetdump.h @@ -75,7 +75,9 @@ void zfuse_umount(void); */ extern struct dfi dfi_s390tape; extern struct dfi dfi_s390mv; +extern struct dfi dfi_s390mv_ext; extern struct dfi dfi_s390; +extern struct dfi dfi_s390_ext; extern struct dfi dfi_lkcd; extern struct dfi dfi_elf; extern struct dfi dfi_kdump;