Files
s390-tools/zdump/df_s390.c
Mikhail Zaslonko ee4cb78dc2 zdump: Drop non-extended multi-volume DASD dump support
Since DASD standalone dumper does not support non-extended s390
multi-volume dumps for years, drop zgetdump support of non-extended s390_mv
DASD dumps and dump-tools:
- Merge dfi_s390mv_ext and dt_s390mv_ext with related dfi_s390mv and
  dt_s390mv counterparts.
- Update DFI and DT vectors of supported dump formats and dump-tools
  removing dfi_s390mv and dt_s390mv entries and keeping dt_s390mv_ext and
  dfi_s390mv_ext ones for s390_mv extended dump and dump-tool accordingly.
- Remove dfi_s390mv.c and dt_s390mv.c sources and update the Makefile.
- Make dfi_s390mv_ext_init() and dfi_s390mv_info() static.
- Remove magic number relevant to non-extended s390_mv DASD dumper.
- Completely drop DASD dumper version 5 case in df_s390_dumper_read().

Note: Since non-extended s390 multi-volume dumps can reside on DASD
partitions only and cannot be produced via DFO interface, we can drop this
dump format entirely.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-04-07 17:42:18 +02:00

181 lines
4.5 KiB
C

/*
* zgetdump - Tool for copying and converting System z dumps
*
* S390 dump format common functions
*
* 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 <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "dump/s390_dump.h"
#include "df_s390.h"
/*
* Check, if we can access the lowcore information in the dump
*/
static int check_addr_max(struct df_s390_hdr *hdr, u64 addr_max)
{
unsigned int i, lc_size;
lc_size = dfi_lc_size(df_s390_to_dfi_arch(hdr->arch));
for (i = 0; i < hdr->cpu_cnt; i++) {
if (hdr->lc_vec[i] + lc_size > addr_max)
return -1;
}
return 0;
}
/*
* Convert lowcore information into internal CPU representation
*/
int df_s390_cpu_info_add(struct df_s390_hdr *hdr, u64 addr_max)
{
unsigned int i;
int rc;
if (hdr->cpu_cnt == 0) {
/* No Prefix registers in header */
dfi_cpu_info_init(DFI_CPU_CONTENT_NONE);
return 0;
}
if (check_addr_max(hdr, addr_max) != 0) {
/* Only lowcore pointers available */
dfi_cpu_info_init(DFI_CPU_CONTENT_LC);
} else {
/* All register info available */
dfi_cpu_info_init(DFI_CPU_CONTENT_ALL);
}
for (i = 0; i < hdr->cpu_cnt; i++) {
rc = dfi_cpu_add_from_lc(hdr->lc_vec[i]);
if (rc)
return rc;
}
return 0;
}
/*
* Convert s390 TOD clock into timeval structure
*/
static void tod2timeval(struct timeval *xtime, u64 todval)
{
/* adjust todclock to 1970 */
todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
todval >>= 12;
xtime->tv_sec = todval / 1000000;
xtime->tv_usec = todval % 1000000;
}
/*
* Convert s390 header information into internal representation
*/
void df_s390_hdr_add(struct df_s390_hdr *hdr)
{
struct timeval timeval;
if (hdr->tod) {
tod2timeval(&timeval, hdr->tod);
dfi_attr_time_set(&timeval);
}
dfi_attr_version_set(hdr->version);
dfi_arch_set(df_s390_to_dfi_arch(hdr->arch));
if (hdr->cpu_id)
dfi_attr_cpu_id_set(hdr->cpu_id);
if (hdr->build_arch)
dfi_attr_build_arch_set(df_s390_to_dfi_arch(hdr->build_arch));
if (hdr->mem_size_real)
dfi_attr_mem_size_real_set(hdr->mem_size_real);
if (hdr->real_cpu_cnt)
dfi_attr_real_cpu_cnt_set(hdr->real_cpu_cnt);
if (!hdr->mvdump && hdr->zlib_version_s390 && hdr->zlib_entry_size)
dfi_attr_zlib_info_set(hdr->zlib_version_s390, hdr->zlib_entry_size);
}
/*
* Add end marker information to internal representation
*/
void df_s390_em_add(struct df_s390_em *em)
{
struct timeval timeval;
if (em->tod) {
tod2timeval(&timeval, em->tod);
dfi_attr_time_end_set(&timeval);
}
}
/*
* Verify end marker
*/
int df_s390_em_verify(struct df_s390_em *em, struct df_s390_hdr *hdr)
{
if (strncmp(em->str, DF_S390_EM_STR, strlen(DF_S390_EM_STR)) != 0)
return -EINVAL;
if (hdr->tod > em->tod)
return -EINVAL;
return 0;
}
/*
* Read s390 dump tool from DASD with given block size
*/
int df_s390_dumper_read(struct zg_fh *fh, int blk_size,
struct df_s390_dumper *dumper)
{
int bytes_to_read, offset = DF_S390_MAGIC_BLK_ECKD * blk_size;
/*
* First read 2 fields at the start of the dumper. The magic number
* and the version.
*/
bytes_to_read = offsetof(struct df_s390_dumper, size);
zg_seek(fh, offset, ZG_CHECK);
zg_read(fh, dumper, bytes_to_read, ZG_CHECK);
dumper->size = 0;
switch (dumper->version) {
/*
* Versions 1 and 2 refer to the newer extended DASD dumpers
* while version 5 refers to the old (non-extended) DASD dump-tools
* we still support (either single-volume or multi-volume).
* Magic numbers for SV and MV dumpers apply as well.
* Pick a dumper size based on the Version and Magic combination.
*/
case 1:
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT,
DF_S390_DUMPER_MAGIC_SIZE) == 0 ||
strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_MV_EXT,
DF_S390_DUMPER_MAGIC_SIZE) == 0)
dumper->size = STAGE2_DUMPER_SIZE_SV;
break;
case 2:
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT,
DF_S390_DUMPER_MAGIC_SIZE) == 0)
dumper->size = STAGE2_DUMPER_SIZE_SV_ZLIB;
else if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_MV_EXT,
DF_S390_DUMPER_MAGIC_SIZE) == 0)
dumper->size = STAGE2_DUMPER_SIZE_MV;
break;
}
if (dumper->size == 0)
return -1;
/* Read force and mem fields in the end of the dumper */
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
offset += dumper->size - bytes_to_read;
zg_seek(fh, offset, ZG_CHECK);
zg_read(fh, &dumper->force, bytes_to_read, ZG_CHECK);
return 0;
}