mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Reading DASD specific sysfs attributes should be collected in one library. Move get_host_access_count() to libdasd/dasd_sys. Remove the old implementation and update any user accordingly. Also, fix the build order for zdsfs. Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2389 lines
68 KiB
C
2389 lines
68 KiB
C
/*
|
|
* dasdview - Display DASD and VTOC information or dump the contents of a DASD
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#define _LARGEFILE64_SOURCE /* needed for unistd.h */
|
|
#define _FILE_OFFSET_BITS 64 /* needed for unistd.h */
|
|
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <getopt.h>
|
|
#include <linux/version.h>
|
|
#include <malloc.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/utsname.h>
|
|
#include <unistd.h>
|
|
|
|
#include "lib/dasd_base.h"
|
|
#include "lib/dasd_sys.h"
|
|
#include "lib/libzds.h"
|
|
#include "lib/util_base.h"
|
|
#include "lib/util_opt.h"
|
|
#include "lib/util_prg.h"
|
|
#include "lib/util_sys.h"
|
|
#include "lib/vtoc.h"
|
|
#include "lib/zt_common.h"
|
|
|
|
#include "dasdview.h"
|
|
|
|
/* Characters per line */
|
|
#define DASDVIEW_CPL 16
|
|
|
|
static const struct util_prg prg = {
|
|
.desc = "Display DASD and VTOC information and dump the content of "
|
|
"a DASD to the console.\n"
|
|
"DEVICE is the node of the device (e.g. '/dev/dasda').",
|
|
.args = "DEVICE",
|
|
.copyright_vec = {
|
|
{
|
|
.owner = "IBM Corp.",
|
|
.pub_first = 2001,
|
|
.pub_last = 2006,
|
|
},
|
|
UTIL_PRG_COPYRIGHT_END
|
|
}
|
|
};
|
|
|
|
static struct util_opt opt_vec[] = {
|
|
UTIL_OPT_SECTION("DUMP OPTIONS"),
|
|
{
|
|
.option = { NULL, no_argument, NULL, '1' },
|
|
.desc = "Show DASD content in short Hex/EBCDIC/ASCII format",
|
|
.flags = UTIL_OPT_FLAG_NOLONG,
|
|
},
|
|
{
|
|
.option = { NULL, no_argument, NULL, '2' },
|
|
.desc = "Show DASD content in detailed Hex/EBCDIC/ASCII format",
|
|
.flags = UTIL_OPT_FLAG_NOLONG,
|
|
},
|
|
{
|
|
.option = { "begin", required_argument, NULL, 'b' },
|
|
.argument = "BEGIN",
|
|
.desc = "Specify start of dump in kilobytes (suffix k), "
|
|
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
|
|
},
|
|
{
|
|
.option = { "size", required_argument, NULL, 's' },
|
|
.argument = "SIZE",
|
|
.desc = "Specify size of dump in kilobytes (suffix k), "
|
|
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
|
|
},
|
|
UTIL_OPT_SECTION("MISC"),
|
|
{
|
|
.option = { "characteristic", no_argument, NULL, 'c' },
|
|
.desc = "Print the characteristics of a device",
|
|
},
|
|
{
|
|
.option = { "info", no_argument, NULL, 'i' },
|
|
.desc = "Print general DASD information and geometry",
|
|
},
|
|
{
|
|
.option = { "volser", no_argument, NULL, 'j' },
|
|
.desc = "Print the volume serial number",
|
|
},
|
|
{
|
|
.option = { "label", no_argument, NULL, 'l' },
|
|
.desc = "Print information about the volume label",
|
|
},
|
|
{
|
|
.option = { "vtoc", required_argument, NULL, 't' },
|
|
.argument = "SPEC",
|
|
.desc = "Print the table of content (VTOC)",
|
|
},
|
|
{
|
|
.option = { "extended", no_argument, NULL, 'x' },
|
|
.desc = "Print extended DASD information",
|
|
},
|
|
UTIL_OPT_HELP,
|
|
UTIL_OPT_VERSION,
|
|
UTIL_OPT_END
|
|
};
|
|
|
|
/*
|
|
* Generate and print an error message based on the formatted
|
|
* text string FMT and a variable amount of extra arguments.
|
|
*/
|
|
static void zt_error_print(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(error_str, ERROR_STRING_SIZE, fmt, args);
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "Error: %s\n", error_str);
|
|
}
|
|
|
|
/*
|
|
* replace special characters with dots and question marks
|
|
*/
|
|
static void dot(char label[])
|
|
{
|
|
int i;
|
|
char c;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
c = label[i];
|
|
if (c <= 0x20)
|
|
label[i] = '?';
|
|
if (c == 0x00)
|
|
label[i] = '.';
|
|
if (c == 0x60)
|
|
label[i] = '?';
|
|
if (c >= 0x7f)
|
|
label[i] = '?';
|
|
}
|
|
}
|
|
|
|
static void
|
|
dasdview_get_info(dasdview_info_t *info)
|
|
{
|
|
struct dasd_eckd_characteristics *characteristics;
|
|
int err;
|
|
|
|
err = dasd_get_geo(info->device, &info->geo);
|
|
if (err != 0) {
|
|
/* Test for unknown device in the first call to libdasd to avoid
|
|
* spitting out two different error messages to the user
|
|
*/
|
|
if (err != EBADF)
|
|
zt_error_print("dasdview: "
|
|
"Could not retrieve geo information!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (dasd_get_blocksize(info->device, &info->blksize) != 0) {
|
|
zt_error_print("dasdview: "
|
|
"Could not retrieve blocksize information!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (dasd_get_info(info->device, &info->dasd_info) != 0) {
|
|
zt_error_print("dasdview: "
|
|
"Could not retrieve disk information!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
characteristics = (struct dasd_eckd_characteristics *)
|
|
&info->dasd_info.characteristics;
|
|
if (characteristics->no_cyl == LV_COMPAT_CYL &&
|
|
characteristics->long_no_cyl)
|
|
info->hw_cylinders = characteristics->long_no_cyl;
|
|
else
|
|
info->hw_cylinders = characteristics->no_cyl;
|
|
|
|
if (util_sys_get_dev_addr(info->device, info->busid) != 0)
|
|
info->busid_valid = 0;
|
|
else
|
|
info->busid_valid = 1;
|
|
|
|
info->raw_track_access = dasd_sys_raw_track_access(info->device);
|
|
}
|
|
|
|
static void
|
|
dasdview_parse_input(unsigned long long *p, dasdview_info_t *info, char *s)
|
|
{
|
|
unsigned long long l;
|
|
char *endp;
|
|
char suffix;
|
|
|
|
l = strtoull(s, &endp, 0);
|
|
if ((endp == s) || ((l + 1) == 0))
|
|
goto error;
|
|
|
|
if (*endp) {
|
|
if (!strchr("kmtbcKMTBC", *endp) || *(endp + 1))
|
|
goto error;
|
|
suffix = tolower(*endp);
|
|
} else {
|
|
suffix = 0;
|
|
}
|
|
if (info->raw_track_access) {
|
|
switch (suffix) {
|
|
case 't':
|
|
l *= RAWTRACKSIZE;
|
|
break;
|
|
case 'c':
|
|
l *= (unsigned long long)info->geo.heads * RAWTRACKSIZE;
|
|
break;
|
|
case 0:
|
|
if (l % RAWTRACKSIZE) {
|
|
zt_error_print("dasdview: only full tracks can"
|
|
" be accessd on devices with "
|
|
" raw_track_access enabled.\n", s);
|
|
goto error;
|
|
}
|
|
break;
|
|
default:
|
|
zt_error_print("dasdview: only types t and c are"
|
|
" allowed for devices with"
|
|
" raw_track_access enabled.\n", s);
|
|
goto error;
|
|
}
|
|
} else {
|
|
switch (suffix) {
|
|
case 'k':
|
|
l *= 1024LL;
|
|
break;
|
|
case 'm':
|
|
l *= 1024LL * 1024LL;
|
|
break;
|
|
case 't':
|
|
l *= (unsigned long long)info->blksize *
|
|
(unsigned long long)info->geo.sectors;
|
|
break;
|
|
case 'b':
|
|
l *= (unsigned long long)info->blksize;
|
|
break;
|
|
case 'c':
|
|
l *= (unsigned long long)info->blksize *
|
|
(unsigned long long)info->geo.sectors *
|
|
(unsigned long long)info->geo.heads;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
*p = l;
|
|
|
|
return;
|
|
error:
|
|
zt_error_print("dasdview: usage error\n"
|
|
"%s is not a valid begin/size value!", s);
|
|
exit(-1);
|
|
}
|
|
|
|
/*
|
|
* Print general DASD information.
|
|
*/
|
|
static void
|
|
dasdview_print_general_info(dasdview_info_t *info)
|
|
{
|
|
printf("\n--- general DASD information -----------------"
|
|
"---------------------------------\n");
|
|
printf("device node : %s\n", info->device);
|
|
#ifdef SYSFS
|
|
struct utsname buf;
|
|
unsigned char a, b, c;
|
|
char suffix[sizeof(buf.release)];
|
|
int rc;
|
|
|
|
rc = uname(&buf);
|
|
if (!rc) {
|
|
sscanf(buf.release, "%c.%c.%c-%s", &a, &b, &c, suffix);
|
|
if (KERNEL_VERSION(2, 5, 0) <= KERNEL_VERSION(a, b, c)) {
|
|
if (info->busid_valid)
|
|
printf("busid : %s\n",
|
|
info->busid);
|
|
else
|
|
printf("busid :"
|
|
" <not found>\n");
|
|
} else {
|
|
#endif
|
|
printf("device number : hex %x \tdec %d\n",
|
|
info->dasd_info.devno,
|
|
info->dasd_info.devno);
|
|
#ifdef SYSFS
|
|
}
|
|
}
|
|
#endif
|
|
printf("type : %4s\n", info->dasd_info.type);
|
|
printf("device type : hex %x \tdec %d\n",
|
|
info->dasd_info.dev_type,
|
|
info->dasd_info.dev_type);
|
|
printf("\n--- DASD geometry ----------------------------"
|
|
"---------------------------------\n");
|
|
printf("number of cylinders : hex %x \tdec %d\n",
|
|
info->hw_cylinders,
|
|
info->hw_cylinders);
|
|
printf("tracks per cylinder : hex %x \tdec %d\n",
|
|
info->geo.heads,
|
|
info->geo.heads);
|
|
printf("blocks per track : hex %x \tdec %d\n",
|
|
info->geo.sectors,
|
|
info->geo.sectors);
|
|
printf("blocksize : hex %x \tdec %d\n",
|
|
info->blksize,
|
|
info->blksize);
|
|
}
|
|
|
|
/*
|
|
* Loop over the given character array and HEXdump the content.
|
|
*/
|
|
static inline void
|
|
dasdview_dump_array(char *name, int size, unsigned char *addr)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if (i % DASDVIEW_CPL == 0) {
|
|
if (i == 0)
|
|
printf("%-23.23s: ", name);
|
|
else
|
|
printf("\n%25s", "");
|
|
} else {
|
|
if (i % 8 == 0)
|
|
printf(" ");
|
|
if (i % 4 == 0)
|
|
printf(" ");
|
|
}
|
|
printf("%02x", addr[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
/*
|
|
* Print extended DASD information.
|
|
*/
|
|
static void
|
|
dasdview_print_extended_info(dasdview_info_t *info)
|
|
{
|
|
unsigned int i;
|
|
struct dasd_information2_t *dasd_info;
|
|
struct {
|
|
unsigned int mask;
|
|
char *name;
|
|
} flist[2] = { {DASD_FEATURE_READONLY, "ro" },
|
|
{DASD_FEATURE_USEDIAG, "diag"} };
|
|
|
|
dasd_info = &info->dasd_info;
|
|
printf("\n--- extended DASD information ----------------"
|
|
"---------------------------------\n");
|
|
printf("real device number : hex %x \tdec %d\n",
|
|
dasd_info->real_devno, dasd_info->real_devno);
|
|
printf("subchannel identifier : hex %x \tdec %d\n",
|
|
dasd_info->schid, dasd_info->schid);
|
|
printf("CU type (SenseID) : hex %x \tdec %d\n",
|
|
dasd_info->cu_type, dasd_info->cu_type);
|
|
printf("CU model (SenseID) : hex %x \tdec %d\n",
|
|
dasd_info->cu_model, dasd_info->cu_model);
|
|
printf("device type (SenseID) : hex %x \tdec %d\n",
|
|
dasd_info->dev_type, dasd_info->dev_type);
|
|
printf("device model (SenseID) : hex %x \tdec %d\n",
|
|
dasd_info->dev_model, dasd_info->dev_model);
|
|
printf("open count : hex %x \tdec %d\n",
|
|
dasd_info->open_count, dasd_info->open_count);
|
|
printf("req_queue_len : hex %x \tdec %d\n",
|
|
dasd_info->req_queue_len, dasd_info->req_queue_len);
|
|
printf("chanq_len : hex %x \tdec %d\n",
|
|
dasd_info->chanq_len, dasd_info->chanq_len);
|
|
printf("status : hex %x \tdec %d\n",
|
|
dasd_info->status, dasd_info->status);
|
|
printf("label_block : hex %x \tdec %d\n",
|
|
dasd_info->label_block, dasd_info->label_block);
|
|
printf("FBA_layout : hex %x \tdec %d\n",
|
|
dasd_info->FBA_layout, dasd_info->FBA_layout);
|
|
printf("characteristics_size : hex %x \tdec %d\n",
|
|
dasd_info->characteristics_size,
|
|
dasd_info->characteristics_size);
|
|
printf("confdata_size : hex %x \tdec %d\n",
|
|
dasd_info->confdata_size, dasd_info->confdata_size);
|
|
|
|
printf("format : hex %x \tdec %d \t%s\n",
|
|
dasd_info->format, dasd_info->format,
|
|
dasd_info->format == DASD_FORMAT_NONE ?
|
|
"NOT formatted" :
|
|
dasd_info->format == DASD_FORMAT_LDL ?
|
|
"LDL formatted" :
|
|
dasd_info->format == DASD_FORMAT_CDL ?
|
|
"CDL formatted" : "unknown format");
|
|
|
|
printf("features : hex %x \tdec %d \t",
|
|
dasd_info->features, dasd_info->features);
|
|
if (dasd_info->features == DASD_FEATURE_DEFAULT) {
|
|
printf("default\n");
|
|
} else {
|
|
for (i = 0; i < UTIL_ARRAY_SIZE(flist); i++)
|
|
if (dasd_info->features & flist[i].mask)
|
|
printf("%s ", flist[i].name);
|
|
printf("\n");
|
|
}
|
|
printf("\n");
|
|
dasdview_dump_array("characteristics",
|
|
dasd_info->characteristics_size,
|
|
dasd_info->characteristics);
|
|
printf("\n");
|
|
dasdview_dump_array("configuration_data",
|
|
dasd_info->confdata_size,
|
|
dasd_info->configuration_data);
|
|
}
|
|
|
|
static void
|
|
dasdview_read_vlabel(dasdview_info_t *info, volume_label_t *vlabel)
|
|
{
|
|
volume_label_t tmp;
|
|
unsigned long pos;
|
|
|
|
pos = info->dasd_info.label_block * info->blksize;
|
|
|
|
bzero(vlabel, sizeof(volume_label_t));
|
|
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
|
!info->dasd_info.FBA_layout) {
|
|
/* OS/390 and zOS compatible disk layout */
|
|
vtoc_read_volume_label(info->device, pos, vlabel);
|
|
} else {
|
|
/* standard LINUX disk layout */
|
|
vtoc_read_volume_label(info->device, pos, &tmp);
|
|
memcpy(vlabel->vollbl, &tmp, sizeof(tmp) - 4);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dasdview_print_vlabel(dasdview_info_t *info)
|
|
{
|
|
volume_label_t vlabel;
|
|
volume_label_t *tmpvlabel;
|
|
int rc;
|
|
unsigned char s4[5], t4[5], s5[6], t5[6], s6[7], t6[7];
|
|
char s14[15], t14[15], s29[30], t29[30];
|
|
int i;
|
|
|
|
if (info->raw_track_access) {
|
|
rc = lzds_dasd_read_vlabel(info->dasd);
|
|
if (rc) {
|
|
zt_error_print("error when reading label from device:"
|
|
" rc=%d\n", rc);
|
|
exit(-1);
|
|
}
|
|
lzds_dasd_get_vlabel(info->dasd, &tmpvlabel);
|
|
memcpy(&vlabel, tmpvlabel, sizeof(vlabel));
|
|
} else {
|
|
dasdview_read_vlabel(info, &vlabel);
|
|
}
|
|
|
|
printf("\n--- volume label -----------------------------"
|
|
"---------------------------------\n");
|
|
|
|
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.volkey, 4);
|
|
printf("volume label key : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s4, 5); bzero(s4, 5); strncpy((char *)s4, vlabel.vollbl, 4);
|
|
printf("\n\nvolume label identifier : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s6, 7); bzero(t6, 7); strncpy((char *)s6, vlabel.volid, 6);
|
|
printf("\n\nvolume identifier : ascii '%6s'\n", s6);
|
|
vtoc_ebcdic_dec((char *)s6, (char *)t6, 6);
|
|
printf(" : ebcdic '%6s'\n", t6);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 6; i++)
|
|
printf("%02x", s6[i]);
|
|
|
|
printf("\n\nsecurity byte : hex %02x\n", vlabel.security);
|
|
|
|
printf("\n\nVTOC pointer : hex %04x%04x%02x ",
|
|
vlabel.vtoc.cc, vlabel.vtoc.hh, vlabel.vtoc.b);
|
|
if ((vlabel.vtoc.cc == 0x4040) && (vlabel.vtoc.hh == 0x4040) &&
|
|
(vlabel.vtoc.b == 0x40))
|
|
printf("\n");
|
|
else
|
|
printf("\n "
|
|
"(cyl %d, trk %d, blk %d)\n\n",
|
|
vtoc_get_cyl_from_cchhb(&vlabel.vtoc),
|
|
vtoc_get_head_from_cchhb(&vlabel.vtoc), vlabel.vtoc.b);
|
|
|
|
bzero(s5, 6); bzero(t5, 6); strncpy((char *)s5, vlabel.res1, 5);
|
|
printf("reserved : ascii '%5s'\n", s5);
|
|
vtoc_ebcdic_dec((char *)s5, (char *)t5, 5);
|
|
printf(" : ebcdic '%5s'\n", t5);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 5; i++)
|
|
printf("%02x", s5[i]);
|
|
|
|
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.cisize, 4);
|
|
printf("\n\nCI size for FBA : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.blkperci, 4);
|
|
printf("\n\nblocks per CI (FBA) : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.labperci, 4);
|
|
printf("\n\nlabels per CI (FBA) : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.res2, 4);
|
|
printf("\n\nreserved : ascii '%4s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
|
printf(" : ebcdic '%4s'\n", t4);
|
|
printf(" : hex ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", s4[i]);
|
|
|
|
bzero(s14, 15); bzero(t14, 15); strncpy(s14, vlabel.lvtoc, 14);
|
|
printf("\n\nowner code for VTOC : ascii '%14s'\n", s14);
|
|
vtoc_ebcdic_dec(s14, t14, 14);
|
|
printf(" ebcdic '%14s'\n", t14);
|
|
printf(" hex ");
|
|
for (i = 0; i < 14; i++) {
|
|
printf("%02x", s14[i]);
|
|
if ((i + 1) % 4 == 0)
|
|
printf(" ");
|
|
if ((i + 1) % 8 == 0)
|
|
printf(" ");
|
|
}
|
|
|
|
bzero(s29, 30); strncpy(s29, vlabel.res3, 28);
|
|
printf("\n\nreserved : ascii '%28s'\n", s29);
|
|
bzero(t29, 30);
|
|
vtoc_ebcdic_dec(s29, t29, 28);
|
|
printf(" ebcdic '%28s'\n", t29);
|
|
printf(" hex ");
|
|
for (i = 0; i < 28; i++) {
|
|
printf("%02x", s29[i]);
|
|
if ((i + 1) % 4 == 0)
|
|
printf(" ");
|
|
if ((i + 1) % 8 == 0)
|
|
printf(" ");
|
|
if ((i + 1) % 16 == 0)
|
|
printf("\n "
|
|
" ");
|
|
}
|
|
|
|
bzero(s4, 5); bzero(t4, 5); s4[0] = vlabel.ldl_version;
|
|
printf("\n\nldl_version : ascii '%1s'\n", s4);
|
|
vtoc_ebcdic_dec((char *)s4, (char *)t4, 1);
|
|
printf(" : ebcdic '%1s'\n", t4);
|
|
printf(" : hex %02x", s4[0]);
|
|
|
|
printf("\n\nformatted_blocks : dec %llu",
|
|
vlabel.formatted_blocks);
|
|
printf("\n : hex %016llx",
|
|
vlabel.formatted_blocks);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
static void
|
|
dasdview_print_volser(dasdview_info_t *info)
|
|
{
|
|
volume_label_t vlabel;
|
|
volume_label_t *tmpvlabel;
|
|
char volser[7];
|
|
char vollbl[5];
|
|
int rc;
|
|
|
|
if (info->raw_track_access) {
|
|
rc = lzds_dasd_read_vlabel(info->dasd);
|
|
if (rc) {
|
|
zt_error_print("error when reading label from device:"
|
|
" rc=%d\n", rc);
|
|
exit(-1);
|
|
}
|
|
lzds_dasd_get_vlabel(info->dasd, &tmpvlabel);
|
|
memcpy(&vlabel, tmpvlabel, sizeof(vlabel));
|
|
} else {
|
|
dasdview_read_vlabel(info, &vlabel);
|
|
}
|
|
|
|
bzero(vollbl, 5);
|
|
bzero(volser, 7);
|
|
strncpy(vollbl, vlabel.vollbl, 4);
|
|
vtoc_ebcdic_dec(vollbl, vollbl, 4);
|
|
|
|
if ((strncmp(vollbl, "VOL1", 4) == 0) ||
|
|
(strncmp(vollbl, "LNX1", 4) == 0)) {
|
|
strncpy(volser, vlabel.volid, 6);
|
|
vtoc_ebcdic_dec(volser, volser, 6);
|
|
} else {
|
|
memcpy(volser, " ", 6);
|
|
}
|
|
|
|
printf("%6.6s\n", volser);
|
|
}
|
|
|
|
static void
|
|
dasdview_read_vtoc(dasdview_info_t *info)
|
|
{
|
|
volume_label_t vlabel;
|
|
format1_label_t tmp;
|
|
unsigned long maxblk, pos;
|
|
u_int64_t vtocblk;
|
|
int i;
|
|
|
|
pos = info->dasd_info.label_block * info->blksize;
|
|
|
|
bzero(&vlabel, sizeof(vlabel));
|
|
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
|
!info->dasd_info.FBA_layout) {
|
|
/* OS/390 and zOS compatible disk layout */
|
|
vtoc_read_volume_label(info->device, pos, &vlabel);
|
|
} else {
|
|
zt_error_print("dasdview: disk layout error\n"
|
|
"%s is not formatted with the z/OS "
|
|
"compatible disk layout!\n", info->device);
|
|
exit(-1);
|
|
}
|
|
|
|
vtocblk = (u_int64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
|
|
info->geo.heads * info->geo.sectors +
|
|
vtoc_get_head_from_cchhb(&vlabel.vtoc) * info->geo.sectors +
|
|
vlabel.vtoc.b;
|
|
|
|
/*
|
|
* geo.cylinders is the minimum of hw_cylinders and LV_COMPAT_CYL
|
|
* Actually the vtoc should be located in in the first 65k-1 tracks
|
|
* so this check could be even more restrictive, but it doesn't
|
|
* hurt the way it is. Linux cdl format restricts the vtoc to
|
|
* the first two tracks anyway.
|
|
*/
|
|
maxblk = info->geo.cylinders * info->geo.heads * info->geo.sectors;
|
|
|
|
if ((vtocblk <= 0) || (vtocblk > maxblk)) {
|
|
zt_error_print("dasdview: VTOC error\n"
|
|
"Volume label VTOC pointer is not valid!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
vtoc_read_label(info->device, (vtocblk - 1) * info->blksize,
|
|
NULL, &info->f4, NULL, NULL);
|
|
|
|
if ((info->f4.DS4KEYCD[0] != 0x04) ||
|
|
(info->f4.DS4KEYCD[43] != 0x04) ||
|
|
(info->f4.DS4IDFMT != 0xf4)) {
|
|
/* format4 DSCB is invalid */
|
|
zt_error_print("dasdview: VTOC error\n"
|
|
"Format 4 DSCB is invalid!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
info->f4c++;
|
|
pos = (vtocblk - 1) * info->blksize;
|
|
|
|
for (i = 1; i < info->geo.sectors; i++) {
|
|
pos += info->blksize;
|
|
vtoc_read_label(info->device, pos, &tmp, NULL, NULL, NULL);
|
|
|
|
switch (tmp.DS1FMTID) {
|
|
case 0xf1:
|
|
memcpy(&info->f1[info->f1c], &tmp,
|
|
sizeof(format1_label_t));
|
|
info->f1c++;
|
|
break;
|
|
case 0xf4:
|
|
info->f4c++;
|
|
break;
|
|
case 0xf5:
|
|
memcpy(&info->f5, &tmp, sizeof(format1_label_t));
|
|
info->f5c++;
|
|
break;
|
|
case 0xf7:
|
|
memcpy(&info->f7, &tmp, sizeof(format1_label_t));
|
|
info->f7c++;
|
|
break;
|
|
case 0xf8:
|
|
memcpy(&info->f8[info->f8c], &tmp,
|
|
sizeof(format1_label_t));
|
|
info->f8c++;
|
|
break;
|
|
case 0xf9:
|
|
memcpy(&info->f9[info->f9c], &tmp,
|
|
sizeof(format1_label_t));
|
|
info->f9c++;
|
|
break;
|
|
case 0x00:
|
|
break;
|
|
default:
|
|
printf("Unknown label in VTOC detected (id=%x)\n",
|
|
tmp.DS1FMTID);
|
|
}
|
|
}
|
|
|
|
if (info->f4c > 1) {
|
|
zt_error_print("dasdview: VTOC error\n"
|
|
"More than one FMT4 DSCB!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (info->f5c > 1) {
|
|
zt_error_print("dasdview: VTOC error\n"
|
|
"More than one FMT5 DSCB!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (info->f7c > 1) {
|
|
zt_error_print("dasdview: VTOC error\n"
|
|
"More than one FMT7 DSCB!\n");
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_format1_8_short_info(format1_label_t *f1,
|
|
struct hd_geometry *geo)
|
|
{
|
|
char s6[7], s13[14], s44[45];
|
|
unsigned long track_low, track_up;
|
|
|
|
bzero(s44, 45);
|
|
strncpy(s44, f1->DS1DSNAM, 44);
|
|
vtoc_ebcdic_dec(s44, s44, 44);
|
|
bzero(s6, 7);
|
|
strncpy(s6, (char *)f1->DS1DSSN, 6);
|
|
vtoc_ebcdic_dec(s6, s6, 6);
|
|
bzero(s13, 14);
|
|
strncpy(s13, (char *)f1->DS1SYSCD, 13);
|
|
vtoc_ebcdic_dec(s13, s13, 13);
|
|
|
|
track_low = cchh2trk(&f1->DS1EXT1.llimit, geo);
|
|
track_up = cchh2trk(&f1->DS1EXT1.ulimit, geo);
|
|
|
|
printf(" | %44s | trk | trk |\n",
|
|
s44);
|
|
printf(" | data set serial number :"
|
|
" '%6s' |"
|
|
" %12ld | %12ld |\n", s6, track_low, track_up);
|
|
printf(" | system code :"
|
|
" '%13s' |"
|
|
" cyl/trk | cyl/trk |\n", s13);
|
|
printf(" | creation date :"
|
|
" year %4d, day %3d |"
|
|
" %8d/%3d | %8d/%3d |\n",
|
|
f1->DS1CREDT.year + 1900,
|
|
f1->DS1CREDT.day,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT1.llimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT1.llimit),
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT1.ulimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT1.ulimit));
|
|
printf(" +-----------------------------------------"
|
|
"-----+--------------+--------------+\n");
|
|
}
|
|
|
|
static void dasdview_print_vtoc_info(dasdview_info_t *info)
|
|
{
|
|
int i;
|
|
|
|
printf("--- VTOC info --------------------------------"
|
|
"---------------------------------\n");
|
|
printf("The VTOC contains:\n");
|
|
printf(" %d format 1 label(s)\n", info->f1c);
|
|
printf(" %d format 4 label(s)\n", info->f4c);
|
|
printf(" %d format 5 label(s)\n", info->f5c);
|
|
printf(" %d format 7 label(s)\n", info->f7c);
|
|
printf(" %d format 8 label(s)\n", info->f8c);
|
|
printf(" %d format 9 label(s)\n", info->f9c);
|
|
|
|
if ((info->f1c < 1) && (info->f8c < 1)) {
|
|
printf("There are no partitions defined.\n");
|
|
} else {
|
|
printf("Other mainframe operating systems would see "
|
|
"the following data sets:\n");
|
|
printf(" +----------------------------------------------+"
|
|
"--------------+--------------+\n");
|
|
printf(" | data set |"
|
|
" start | end |\n");
|
|
printf(" +----------------------------------------------+"
|
|
"--------------+--------------+\n");
|
|
|
|
for (i = 0; i < info->f1c; i++)
|
|
dasdview_print_format1_8_short_info(&info->f1[i],
|
|
&info->geo);
|
|
for (i = 0; i < info->f8c; i++)
|
|
dasdview_print_format1_8_short_info(&info->f8[i],
|
|
&info->geo);
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_short_info_extent_raw(extent_t *ext)
|
|
{
|
|
if (ext->typeind > 0x00)
|
|
printf(" %3d (%5d,%5d) (%5d,%5d)\n",
|
|
ext->seqno,
|
|
vtoc_get_cyl_from_cchh(&ext->llimit),
|
|
vtoc_get_head_from_cchh(&ext->llimit),
|
|
vtoc_get_cyl_from_cchh(&ext->ulimit),
|
|
vtoc_get_head_from_cchh(&ext->ulimit));
|
|
}
|
|
|
|
static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
|
|
dasdview_info_t *info)
|
|
{
|
|
char s6[7], s13[14], s44[45];
|
|
unsigned long long j;
|
|
format3_label_t *f3;
|
|
format9_label_t *f9;
|
|
struct dscb *dscb;
|
|
int rc;
|
|
|
|
bzero(s44, 45);
|
|
strncpy(s44, f1->DS1DSNAM, 44);
|
|
vtoc_ebcdic_dec(s44, s44, 44);
|
|
bzero(s6, 7);
|
|
strncpy(s6, (char *)f1->DS1DSSN, 6);
|
|
vtoc_ebcdic_dec(s6, s6, 6);
|
|
bzero(s13, 14);
|
|
strncpy(s13, (char *)f1->DS1SYSCD, 13);
|
|
vtoc_ebcdic_dec(s13, s13, 13);
|
|
|
|
printf("data set name : '%44s'\n", s44);
|
|
printf("data set serial number : '%6s'\n", s6);
|
|
printf("system code : '%13s'\n", s13);
|
|
printf("creation date : year %4d, day %3d\n",
|
|
f1->DS1CREDT.year + 1900, f1->DS1CREDT.day);
|
|
|
|
printf("flags : ");
|
|
if (f1->DS1FLAG1 & 0x80)
|
|
printf("DS1COMPR ");
|
|
if (f1->DS1FLAG1 & 0x40)
|
|
printf("DS1CPOIT ");
|
|
if (f1->DS1FLAG1 & 0x20)
|
|
printf("DS1EXPBY ");
|
|
if (f1->DS1FLAG1 & 0x10)
|
|
printf("DS1RECAL ");
|
|
if (f1->DS1FLAG1 & 0x08)
|
|
printf("DS1LARGE ");
|
|
if (f1->DS1FLAG1 & 0x04)
|
|
printf("unknown ");
|
|
if ((f1->DS1FLAG1 & 0x01) && (f1->DS1FLAG1 & 0x02))
|
|
printf("DS1EATTR=not used ");
|
|
if (!(f1->DS1FLAG1 & 0x01) && (f1->DS1FLAG1 & 0x02))
|
|
printf("DS1EATTR=optional ");
|
|
if ((f1->DS1FLAG1 & 0x01) && !(f1->DS1FLAG1 & 0x02))
|
|
printf("DS1EATTR=no ");
|
|
if (f1->DS1FLAG1 & 0x00)
|
|
printf("DS1EATTR=default ");
|
|
printf("\n");
|
|
|
|
printf("SMS flags : ");
|
|
if (f1->DS1SMSFG & 0x80)
|
|
printf("DS1SMSDS ");
|
|
if (f1->DS1SMSFG & 0x40)
|
|
printf("DS1SMSUC ");
|
|
if (f1->DS1SMSFG & 0x20)
|
|
printf("DS1REBLK ");
|
|
if (f1->DS1SMSFG & 0x10)
|
|
printf("DS1CRSDB ");
|
|
if (f1->DS1SMSFG & 0x08)
|
|
printf("DS1PDSE ");
|
|
if (f1->DS1SMSFG & 0x04)
|
|
printf("DS1STRP ");
|
|
if (f1->DS1SMSFG & 0x02)
|
|
printf("DS1PDSEX ");
|
|
if (f1->DS1SMSFG & 0x01)
|
|
printf("DS1DSAE ");
|
|
printf("\n");
|
|
|
|
printf("organisation : ");
|
|
if (f1->DS1DSRG1 & 0x80)
|
|
printf("DS1DSGIS ");
|
|
if (f1->DS1DSRG1 & 0x40)
|
|
printf("DS1DSGPS ");
|
|
if (f1->DS1DSRG1 & 0x20)
|
|
printf("DS1DSGDA ");
|
|
if (f1->DS1DSRG1 & 0x10)
|
|
printf("DS1DSGCX ");
|
|
if (f1->DS1DSRG1 & 0x08)
|
|
printf("reserved ");
|
|
if (f1->DS1DSRG1 & 0x04)
|
|
printf("reserved ");
|
|
if (f1->DS1DSRG1 & 0x02)
|
|
printf("DS1DSGPO ");
|
|
if (f1->DS1DSRG1 & 0x01)
|
|
printf("DS1DSGU ");
|
|
if (f1->DS1DSRG2 & 0x80)
|
|
printf("DS1DSGGS ");
|
|
if (f1->DS1DSRG2 & 0x40)
|
|
printf("DS1DSGTX ");
|
|
if (f1->DS1DSRG2 & 0x20)
|
|
printf("DS1DSGTQ ");
|
|
if (f1->DS1DSRG2 & 0x10)
|
|
printf("reserved ");
|
|
if (f1->DS1DSRG2 & 0x08)
|
|
printf("DS1ACBM ");
|
|
if (f1->DS1DSRG2 & 0x04)
|
|
printf("DS1DSGTR ");
|
|
if (f1->DS1DSRG2 & 0x02)
|
|
printf("reserved ");
|
|
if (f1->DS1DSRG2 & 0x01)
|
|
printf("reserved");
|
|
printf("\n");
|
|
|
|
printf("record format : ");
|
|
if ((f1->DS1RECFM & 0x80) && !(f1->DS1RECFM & 0x40))
|
|
printf("DS1RECFF ");
|
|
if (!(f1->DS1RECFM & 0x80) && (f1->DS1RECFM & 0x40))
|
|
printf("DS1RECFV ");
|
|
if ((f1->DS1RECFM & 0x80) && (f1->DS1RECFM & 0x40))
|
|
printf("DS1RECFU ");
|
|
if (f1->DS1RECFM & 0x20)
|
|
printf("DS1RECFT ");
|
|
if (f1->DS1RECFM & 0x10)
|
|
printf("DS1RECFB ");
|
|
if (f1->DS1RECFM & 0x08)
|
|
printf("DS1RECFS ");
|
|
if (f1->DS1RECFM & 0x04)
|
|
printf("DS1RECFA ");
|
|
if (f1->DS1RECFM & 0x02)
|
|
printf("DS1RECMC ");
|
|
if (f1->DS1RECFM & 0x01)
|
|
printf("reserved");
|
|
printf("\n");
|
|
|
|
printf("(max) block length : %u\n", f1->DS1BLKL);
|
|
printf("logical record length : %u\n", f1->DS1LRECL);
|
|
|
|
printf("extents belonging to this dataset:\n");
|
|
printf(" seqno llimit (cyl, trk) ulimit (cyl, trk)\n");
|
|
|
|
/* The format 1 label can point to a chain of f3 labels
|
|
* The format 8 label points to a (chain of) f9 labels
|
|
* The format 9 label may contain several format 3 labels, but as
|
|
* far as I know, it is still OK to follow the 'next dscb' chain.
|
|
* So for a format 9 label I have to follow this chain until I
|
|
* find the first format 3 dscb and then I can follow the format 3
|
|
* dscbs to the end of the chain.
|
|
*/
|
|
rc = lzds_raw_vtoc_get_dscb_from_cchhb(info->rawvtoc, &f1->DS1PTRDS,
|
|
&dscb);
|
|
/* The first f9 label contains extra data that we may want to print here
|
|
*/
|
|
while (!rc && dscb && dscb->fmtid == 0xf9) {
|
|
f9 = (format9_label_t *)dscb;
|
|
rc = lzds_raw_vtoc_get_dscb_from_cchhb(info->rawvtoc,
|
|
&f9->DS9PTRDS, &dscb);
|
|
}
|
|
if (rc) {
|
|
zt_error_print("dasdview: Broken format 3 DSCB chain \n");
|
|
exit(-1);
|
|
}
|
|
f3 = (dscb && dscb->fmtid == 0xf3) ? (format3_label_t *)dscb : NULL;
|
|
|
|
/* first print the extents that are part of the f1/f8 label itself */
|
|
dasdview_print_short_info_extent_raw(&f1->DS1EXT1);
|
|
dasdview_print_short_info_extent_raw(&f1->DS1EXT2);
|
|
dasdview_print_short_info_extent_raw(&f1->DS1EXT3);
|
|
|
|
/* now follow the f3 chain into the rabbit hole */
|
|
while (f3) {
|
|
/* sanity check */
|
|
if (f3->DS3FMTID != 0xf3) {
|
|
zt_error_print("dasdview: Broken format 3 DSCB"
|
|
" chain \n");
|
|
exit(-1);
|
|
}
|
|
for (j = 0; j < 4; ++j)
|
|
dasdview_print_short_info_extent_raw(&f3->DS3EXTNT[j]);
|
|
for (j = 0; j < 9; ++j)
|
|
dasdview_print_short_info_extent_raw(&f3->DS3ADEXT[j]);
|
|
rc = lzds_raw_vtoc_get_dscb_from_cchhb(info->rawvtoc,
|
|
&f3->DS3PTRDS,
|
|
(struct dscb **)&f3);
|
|
if (rc) {
|
|
zt_error_print("dasdview: Broken format 3 DSCB"
|
|
" chain \n");
|
|
exit(-1);
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
static void dasdview_print_vtoc_info_raw(dasdview_info_t *info)
|
|
{
|
|
struct dscbiterator *it;
|
|
struct dscb *dscb;
|
|
int rc;
|
|
int f1c, f3c, f4c, f5c, f7c, f8c, f9c;
|
|
|
|
f1c = 0;
|
|
f3c = 0;
|
|
f4c = 0;
|
|
f5c = 0;
|
|
f7c = 0;
|
|
f8c = 0;
|
|
f9c = 0;
|
|
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
|
|
if (rc) {
|
|
zt_error_print("dasdview: could not allocate DSCB iterator \n");
|
|
exit(-1);
|
|
}
|
|
while (!lzds_dscbiterator_get_next_dscb(it, &dscb)) {
|
|
if (dscb->fmtid == 0xf1)
|
|
++f1c;
|
|
else if (dscb->fmtid == 0xf3)
|
|
++f3c;
|
|
else if (dscb->fmtid == 0xf4)
|
|
++f4c;
|
|
else if (dscb->fmtid == 0xf5)
|
|
++f5c;
|
|
else if (dscb->fmtid == 0xf7)
|
|
++f7c;
|
|
else if (dscb->fmtid == 0xf8)
|
|
++f8c;
|
|
else if (dscb->fmtid == 0xf9)
|
|
++f9c;
|
|
}
|
|
lzds_dscbiterator_free(it);
|
|
printf("--- VTOC info --------------------------------"
|
|
"---------------------------------\n");
|
|
printf("The VTOC contains:\n");
|
|
printf(" %d format 1 label(s)\n", f1c);
|
|
printf(" %d format 3 label(s)\n", f3c);
|
|
printf(" %d format 4 label(s)\n", f4c);
|
|
printf(" %d format 5 label(s)\n", f5c);
|
|
printf(" %d format 7 label(s)\n", f7c);
|
|
printf(" %d format 8 label(s)\n", f8c);
|
|
printf(" %d format 9 label(s)\n", f9c);
|
|
|
|
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
|
|
if (rc) {
|
|
zt_error_print("dasdview: could not allocate DSCB iterator \n");
|
|
exit(-1);
|
|
}
|
|
while (!lzds_dscbiterator_get_next_dscb(it, &dscb)) {
|
|
if (dscb->fmtid == 0xf1 || dscb->fmtid == 0xf8)
|
|
dasdview_print_format1_8_short_info_raw(
|
|
(format1_label_t *)dscb, info);
|
|
}
|
|
lzds_dscbiterator_free(it);
|
|
}
|
|
|
|
/*
|
|
* Note: the explicit cylinder/head conversion for large volume
|
|
* adresses should not be necessary for entries that point to
|
|
* vtoc labels, as those must be located in the first 65K-1 tracks,
|
|
* but we do it anyway to be on the safe side.
|
|
*/
|
|
static void dasdview_print_format1_8_no_head(format1_label_t *f1)
|
|
{
|
|
char s6[7], s13[14], s44[45];
|
|
int i;
|
|
|
|
bzero(s6, 7);
|
|
bzero(s13, 14);
|
|
bzero(s44, 45);
|
|
|
|
strncpy(s44, f1->DS1DSNAM, 44);
|
|
printf("DS1DSNAM : ascii '%44s'\n", s44);
|
|
vtoc_ebcdic_dec(s44, s44, 44);
|
|
printf(" ebcdic '%44s'\n", s44);
|
|
printf("DS1FMTID : dec %d, hex %02x\n",
|
|
f1->DS1FMTID, f1->DS1FMTID);
|
|
printf("DS1DSSN : hex ");
|
|
for (i = 0; i < 6; i++)
|
|
printf("%02x", f1->DS1DSSN[i]);
|
|
strncpy(s6, (char *)f1->DS1DSSN, 6);
|
|
printf("\n ascii '%6s'\n", s6);
|
|
vtoc_ebcdic_dec(s6, s6, 6);
|
|
printf(" ebcdic '%6s'\n", s6);
|
|
printf("DS1VOLSQ : dec %d, hex %04x\n",
|
|
f1->DS1VOLSQ, f1->DS1VOLSQ);
|
|
printf("DS1CREDT : hex %02x%04x "
|
|
"(year %d, day %d)\n",
|
|
f1->DS1CREDT.year, f1->DS1CREDT.day,
|
|
f1->DS1CREDT.year + 1900,
|
|
f1->DS1CREDT.day);
|
|
printf("DS1EXPDT : hex %02x%04x "
|
|
"(year %d, day %d)\n",
|
|
f1->DS1EXPDT.year, f1->DS1EXPDT.day,
|
|
f1->DS1EXPDT.year + 1900,
|
|
f1->DS1EXPDT.day);
|
|
printf("DS1NOEPV : dec %d, hex %02x\n",
|
|
f1->DS1NOEPV, f1->DS1NOEPV);
|
|
printf("DS1NOBDB : dec %d, hex %02x\n",
|
|
f1->DS1NOBDB, f1->DS1NOBDB);
|
|
printf("DS1FLAG1 : dec %d, hex %02x\n",
|
|
f1->DS1FLAG1, f1->DS1FLAG1);
|
|
printf("DS1SYSCD : hex ");
|
|
for (i = 0; i < 13; i++)
|
|
printf("%02x", f1->DS1SYSCD[i]);
|
|
strncpy(s13, (char *)f1->DS1SYSCD, 13);
|
|
printf("\n ascii '%13s'\n", s13);
|
|
vtoc_ebcdic_dec(s13, s13, 13);
|
|
printf(" ebcdic '%13s'\n", s13);
|
|
printf("DS1REFD : hex %02x%04x "
|
|
"(year %d, day %d)\n",
|
|
f1->DS1REFD.year, f1->DS1REFD.day,
|
|
f1->DS1REFD.year + 1900,
|
|
f1->DS1REFD.day);
|
|
printf("DS1SMSFG : dec %d, hex %02x\n",
|
|
f1->DS1SMSFG, f1->DS1SMSFG);
|
|
printf("DS1SCXTF : dec %d, hex %02x\n",
|
|
f1->DS1SCXTF, f1->DS1SCXTF);
|
|
printf("DS1SCXTV : dec %d, hex %04x\n",
|
|
f1->DS1SCXTV, f1->DS1SCXTV);
|
|
printf("DS1DSRG1 : dec %d, hex %02x\n",
|
|
f1->DS1DSRG1, f1->DS1DSRG1);
|
|
printf("DS1DSRG2 : dec %d, hex %02x\n",
|
|
f1->DS1DSRG2, f1->DS1DSRG2);
|
|
printf("DS1RECFM : dec %d, hex %02x\n",
|
|
f1->DS1RECFM, f1->DS1RECFM);
|
|
printf("DS1OPTCD : dec %d, hex %02x\n",
|
|
f1->DS1OPTCD, f1->DS1OPTCD);
|
|
printf("DS1BLKL : dec %d, hex %04x\n",
|
|
f1->DS1BLKL, f1->DS1BLKL);
|
|
printf("DS1LRECL : dec %d, hex %04x\n",
|
|
f1->DS1LRECL, f1->DS1LRECL);
|
|
printf("DS1KEYL : dec %d, hex %02x\n",
|
|
f1->DS1KEYL, f1->DS1KEYL);
|
|
printf("DS1RKP : dec %d, hex %04x\n",
|
|
f1->DS1RKP, f1->DS1RKP);
|
|
printf("DS1DSIND : dec %d, hex %02x\n",
|
|
f1->DS1DSIND, f1->DS1DSIND);
|
|
printf("DS1SCAL1 : dec %d, hex %02x\n",
|
|
f1->DS1SCAL1, f1->DS1SCAL1);
|
|
printf("DS1SCAL3 : hex ");
|
|
for (i = 0; i < 3; i++)
|
|
printf("%02x", f1->DS1SCAL3[i]);
|
|
printf("\nDS1LSTAR : hex %04x%02x "
|
|
"(trk %d, blk %d)\n",
|
|
f1->DS1LSTAR.tt, f1->DS1LSTAR.r,
|
|
f1->DS1LSTAR.tt, f1->DS1LSTAR.r);
|
|
printf("DS1TRBAL : dec %d, hex %04x\n",
|
|
f1->DS1TRBAL, f1->DS1TRBAL);
|
|
printf("reserved : dec %d, hex %04x\n",
|
|
f1->res1, f1->res1);
|
|
printf("DS1EXT1 : hex %02x%02x%04x%04x%04x%04x\n",
|
|
f1->DS1EXT1.typeind,
|
|
f1->DS1EXT1.seqno,
|
|
f1->DS1EXT1.llimit.cc,
|
|
f1->DS1EXT1.llimit.hh,
|
|
f1->DS1EXT1.ulimit.cc,
|
|
f1->DS1EXT1.ulimit.hh);
|
|
printf(" typeind : dec %d, hex %02x\n",
|
|
f1->DS1EXT1.typeind,
|
|
f1->DS1EXT1.typeind);
|
|
printf(" seqno : dec %d, hex %02x\n",
|
|
f1->DS1EXT1.seqno, f1->DS1EXT1.seqno);
|
|
printf(" llimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT1.llimit.cc,
|
|
f1->DS1EXT1.llimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT1.llimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT1.llimit));
|
|
printf(" ulimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT1.ulimit.cc,
|
|
f1->DS1EXT1.ulimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT1.ulimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT1.ulimit));
|
|
printf("DS1EXT2 : hex %02x%02x%04x%04x%04x%04x\n",
|
|
f1->DS1EXT2.typeind,
|
|
f1->DS1EXT2.seqno,
|
|
f1->DS1EXT2.llimit.cc,
|
|
f1->DS1EXT2.llimit.hh,
|
|
f1->DS1EXT2.ulimit.cc,
|
|
f1->DS1EXT2.ulimit.hh);
|
|
printf(" typeind : dec %d, hex %02x\n",
|
|
f1->DS1EXT2.typeind,
|
|
f1->DS1EXT2.typeind);
|
|
printf(" seqno : dec %d, hex %02x\n",
|
|
f1->DS1EXT2.seqno, f1->DS1EXT2.seqno);
|
|
printf(" llimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT2.llimit.cc,
|
|
f1->DS1EXT2.llimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT2.llimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT2.llimit));
|
|
printf(" ulimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT2.ulimit.cc,
|
|
f1->DS1EXT2.ulimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT2.ulimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT2.ulimit));
|
|
printf("DS1EXT3 : hex %02x%02x%04x%04x%04x%04x\n",
|
|
f1->DS1EXT3.typeind,
|
|
f1->DS1EXT3.seqno,
|
|
f1->DS1EXT3.llimit.cc,
|
|
f1->DS1EXT3.llimit.hh,
|
|
f1->DS1EXT3.ulimit.cc,
|
|
f1->DS1EXT3.ulimit.hh);
|
|
printf(" typeind : dec %d, hex %02x\n",
|
|
f1->DS1EXT3.typeind,
|
|
f1->DS1EXT3.typeind);
|
|
printf(" seqno : dec %d, hex %02x\n",
|
|
f1->DS1EXT3.seqno, f1->DS1EXT3.seqno);
|
|
printf(" llimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT3.llimit.cc,
|
|
f1->DS1EXT3.llimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT3.llimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT3.llimit));
|
|
printf(" ulimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
f1->DS1EXT3.ulimit.cc,
|
|
f1->DS1EXT3.ulimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f1->DS1EXT3.ulimit),
|
|
vtoc_get_head_from_cchh(&f1->DS1EXT3.ulimit));
|
|
printf("DS1PTRDS : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f1->DS1PTRDS.cc, f1->DS1PTRDS.hh,
|
|
f1->DS1PTRDS.b,
|
|
vtoc_get_cyl_from_cchhb(&f1->DS1PTRDS),
|
|
vtoc_get_head_from_cchhb(&f1->DS1PTRDS),
|
|
f1->DS1PTRDS.b);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f1_raw(format1_label_t *f1)
|
|
{
|
|
printf("\n--- VTOC format 1 label -----------------------"
|
|
"---------------------------------\n");
|
|
dasdview_print_format1_8_no_head(f1);
|
|
}
|
|
|
|
/* Note: A format 8 label uses the same type as format 1 */
|
|
static void dasdview_print_vtoc_f8_raw(format1_label_t *f8)
|
|
{
|
|
printf("\n--- VTOC format 8 label -----------------------"
|
|
"---------------------------------\n");
|
|
dasdview_print_format1_8_no_head(f8);
|
|
}
|
|
|
|
static void dasdview_print_extent(extent_t *ext, char *name, int index)
|
|
{
|
|
printf("%s[%d] : hex %02x%02x%04x%04x%04x%04x\n",
|
|
name,
|
|
index,
|
|
ext->typeind,
|
|
ext->seqno,
|
|
ext->llimit.cc,
|
|
ext->llimit.hh,
|
|
ext->ulimit.cc,
|
|
ext->ulimit.hh);
|
|
printf(" typeind : dec %d, hex %02x\n",
|
|
ext->typeind,
|
|
ext->typeind);
|
|
printf(" seqno : dec %d, hex %02x\n",
|
|
ext->seqno, ext->seqno);
|
|
printf(" llimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
ext->llimit.cc,
|
|
ext->llimit.hh,
|
|
vtoc_get_cyl_from_cchh(&ext->llimit),
|
|
vtoc_get_head_from_cchh(&ext->llimit));
|
|
printf(" ulimit : hex %04x%04x "
|
|
"(cyl %d, trk %d)\n",
|
|
ext->ulimit.cc,
|
|
ext->ulimit.hh,
|
|
vtoc_get_cyl_from_cchh(&ext->ulimit),
|
|
vtoc_get_head_from_cchh(&ext->ulimit));
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f3_raw(format3_label_t *f3)
|
|
{
|
|
int i;
|
|
|
|
printf("\n--- VTOC format 3 label ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
printf("DS3KEYID : ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", f3->DS3KEYID[i]);
|
|
printf("\n");
|
|
|
|
for (i = 0; i < 4; ++i)
|
|
dasdview_print_extent(&f3->DS3EXTNT[i], "DS3EXTNT", i);
|
|
|
|
printf("DS3FMTID : dec %d, hex %02x\n",
|
|
f3->DS3FMTID, f3->DS3FMTID);
|
|
|
|
for (i = 0; i < 9; ++i)
|
|
dasdview_print_extent(&f3->DS3ADEXT[i], "DS3ADEXT", i);
|
|
|
|
printf("DS3PTRDS : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f3->DS3PTRDS.cc, f3->DS3PTRDS.hh,
|
|
f3->DS3PTRDS.b,
|
|
vtoc_get_cyl_from_cchhb(&f3->DS3PTRDS),
|
|
vtoc_get_head_from_cchhb(&f3->DS3PTRDS),
|
|
f3->DS3PTRDS.b);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f4_raw(format4_label_t *f4)
|
|
{
|
|
int i;
|
|
|
|
printf("\n--- VTOC format 4 label ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
printf("DS4KEYCD : ");
|
|
for (i = 0; i < 44; i++)
|
|
printf("%02x", f4->DS4KEYCD[i]);
|
|
printf("\nDS4IDFMT : dec %d, hex %02x\n",
|
|
f4->DS4IDFMT, f4->DS4IDFMT);
|
|
printf("DS4HPCHR : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f4->DS4HPCHR.cc, f4->DS4HPCHR.hh,
|
|
f4->DS4HPCHR.b,
|
|
vtoc_get_cyl_from_cchhb(&f4->DS4HPCHR),
|
|
vtoc_get_head_from_cchhb(&f4->DS4HPCHR),
|
|
f4->DS4HPCHR.b);
|
|
printf("DS4DSREC : dec %d, hex %04x\n",
|
|
f4->DS4DSREC, f4->DS4DSREC);
|
|
printf("DS4HCCHH : %04x%04x (cyl %d, trk %d)\n",
|
|
f4->DS4HCCHH.cc, f4->DS4HCCHH.hh,
|
|
vtoc_get_cyl_from_cchh(&f4->DS4HCCHH),
|
|
vtoc_get_head_from_cchh(&f4->DS4HCCHH));
|
|
printf("DS4NOATK : dec %d, hex %04x\n",
|
|
f4->DS4NOATK, f4->DS4NOATK);
|
|
printf("DS4VTOCI : dec %d, hex %02x\n",
|
|
f4->DS4VTOCI, f4->DS4VTOCI);
|
|
printf("DS4NOEXT : dec %d, hex %02x\n",
|
|
f4->DS4NOEXT, f4->DS4NOEXT);
|
|
printf("DS4SMSFG : dec %d, hex %02x\n",
|
|
f4->DS4SMSFG, f4->DS4SMSFG);
|
|
printf("DS4DEVAC : dec %d, hex %02x\n",
|
|
f4->DS4DEVAC, f4->DS4DEVAC);
|
|
printf("DS4DSCYL : dec %d, hex %04x\n",
|
|
f4->DS4DEVCT.DS4DSCYL, f4->DS4DEVCT.DS4DSCYL);
|
|
printf("DS4DSTRK : dec %d, hex %04x\n",
|
|
f4->DS4DEVCT.DS4DSTRK, f4->DS4DEVCT.DS4DSTRK);
|
|
printf("DS4DEVTK : dec %d, hex %04x\n",
|
|
f4->DS4DEVCT.DS4DEVTK, f4->DS4DEVCT.DS4DEVTK);
|
|
printf("DS4DEVI : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVI, f4->DS4DEVCT.DS4DEVI);
|
|
printf("DS4DEVL : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVL, f4->DS4DEVCT.DS4DEVL);
|
|
printf("DS4DEVK : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVK, f4->DS4DEVCT.DS4DEVK);
|
|
printf("DS4DEVFG : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVFG, f4->DS4DEVCT.DS4DEVFG);
|
|
printf("DS4DEVTL : dec %d, hex %04x\n",
|
|
f4->DS4DEVCT.DS4DEVTL, f4->DS4DEVCT.DS4DEVTL);
|
|
printf("DS4DEVDT : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVDT, f4->DS4DEVCT.DS4DEVDT);
|
|
printf("DS4DEVDB : dec %d, hex %02x\n",
|
|
f4->DS4DEVCT.DS4DEVDB, f4->DS4DEVCT.DS4DEVDB);
|
|
printf("DS4AMTIM : hex ");
|
|
for (i = 0; i < 8; i++)
|
|
printf("%02x", f4->DS4AMTIM[i]);
|
|
printf("\nDS4AMCAT : hex ");
|
|
for (i = 0; i < 3; i++)
|
|
printf("%02x", f4->DS4AMCAT[i]);
|
|
printf("\nDS4R2TIM : hex ");
|
|
for (i = 0; i < 8; i++)
|
|
printf("%02x", f4->DS4R2TIM[i]);
|
|
printf("\nres1 : hex ");
|
|
for (i = 0; i < 5; i++)
|
|
printf("%02x", f4->res1[i]);
|
|
printf("\nDS4F6PTR : hex ");
|
|
for (i = 0; i < 5; i++)
|
|
printf("%02x", f4->DS4F6PTR[i]);
|
|
printf("\nDS4VTOCE : hex %02x%02x%04x%04x%04x%04x\n",
|
|
f4->DS4VTOCE.typeind, f4->DS4VTOCE.seqno,
|
|
f4->DS4VTOCE.llimit.cc, f4->DS4VTOCE.llimit.hh,
|
|
f4->DS4VTOCE.ulimit.cc, f4->DS4VTOCE.ulimit.hh);
|
|
printf(" typeind : dec %d, hex %02x\n",
|
|
f4->DS4VTOCE.typeind, f4->DS4VTOCE.typeind);
|
|
printf(" seqno : dec %d, hex %02x\n",
|
|
f4->DS4VTOCE.seqno, f4->DS4VTOCE.seqno);
|
|
printf(" llimit : hex %04x%04x (cyl %d, trk %d)\n",
|
|
f4->DS4VTOCE.llimit.cc, f4->DS4VTOCE.llimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f4->DS4VTOCE.llimit),
|
|
vtoc_get_head_from_cchh(&f4->DS4VTOCE.llimit));
|
|
printf(" ulimit : hex %04x%04x (cyl %d, trk %d)\n",
|
|
f4->DS4VTOCE.ulimit.cc, f4->DS4VTOCE.ulimit.hh,
|
|
vtoc_get_cyl_from_cchh(&f4->DS4VTOCE.ulimit),
|
|
vtoc_get_head_from_cchh(&f4->DS4VTOCE.ulimit));
|
|
printf("res2 : hex ");
|
|
for (i = 0; i < 10; i++)
|
|
printf("%02x", f4->res2[i]);
|
|
printf("\nDS4EFLVL : dec %d, hex %02x\n",
|
|
f4->DS4EFLVL, f4->DS4EFLVL);
|
|
printf("DS4EFPTR : hex %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f4->DS4EFPTR.cc, f4->DS4EFPTR.hh,
|
|
f4->DS4EFPTR.b,
|
|
vtoc_get_cyl_from_cchhb(&f4->DS4EFPTR),
|
|
vtoc_get_head_from_cchhb(&f4->DS4EFPTR),
|
|
f4->DS4EFPTR.b);
|
|
printf("res3 : hex %02x\n", f4->res3);
|
|
printf("DS4DCYL : dec %d, hex %08x\n",
|
|
f4->DS4DCYL, f4->DS4DCYL);
|
|
printf("res4 : hex ");
|
|
for (i = 0; i < 2; i++)
|
|
printf("%02x", f4->res4[i]);
|
|
printf("\nDS4DEVF2 : dec %d, hex %02x\n",
|
|
f4->DS4DEVF2, f4->DS4DEVF2);
|
|
printf("res5 : hex %02x\n", f4->res5);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f5_raw(format5_label_t *f5)
|
|
{
|
|
int i;
|
|
|
|
printf("\n--- VTOC format 5 label ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
printf("key identifier\n DS5KEYID : ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", f5->DS5KEYID[i]);
|
|
printf("\nfirst extent description\n");
|
|
printf(" DS5AVEXT : %04x%04x%02x "
|
|
"(start trk: %d, length: %d cyl, %d trk)\n",
|
|
f5->DS5AVEXT.t, f5->DS5AVEXT.fc,
|
|
f5->DS5AVEXT.ft, f5->DS5AVEXT.t,
|
|
f5->DS5AVEXT.fc, f5->DS5AVEXT.ft);
|
|
printf("next 7 extent descriptions\n");
|
|
for (i = 0; i < 7; i++) {
|
|
printf(" DS5EXTAV[%d] : %04x%04x%02x "
|
|
"(start trk: %d, length: %d cyl, %d trk)\n", i + 2,
|
|
f5->DS5EXTAV[i].t, f5->DS5EXTAV[i].fc,
|
|
f5->DS5EXTAV[i].ft, f5->DS5EXTAV[i].t,
|
|
f5->DS5EXTAV[i].fc, f5->DS5EXTAV[i].ft);
|
|
}
|
|
printf("format identifier\n"
|
|
" DS5FMTID : dec %d, hex %02x\n",
|
|
f5->DS5FMTID, f5->DS5FMTID);
|
|
printf("next 18 extent descriptions\n");
|
|
for (i = 0; i < 18; i++) {
|
|
printf(" DS5MAVET[%d] : %04x%04x%02x "
|
|
"(start trk: %d, length: %d cyl, %d trk)\n", i + 9,
|
|
f5->DS5MAVET[i].t, f5->DS5MAVET[i].fc,
|
|
f5->DS5MAVET[i].ft, f5->DS5MAVET[i].t,
|
|
f5->DS5MAVET[i].fc, f5->DS5MAVET[i].ft);
|
|
}
|
|
printf("pointer to next format 5 label\n"
|
|
" DS5PTRDS : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f5->DS5PTRDS.cc, f5->DS5PTRDS.hh,
|
|
f5->DS5PTRDS.b,
|
|
vtoc_get_cyl_from_cchhb(&f5->DS5PTRDS),
|
|
vtoc_get_head_from_cchhb(&f5->DS5PTRDS),
|
|
f5->DS5PTRDS.b);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f7_raw(format7_label_t *f7)
|
|
{
|
|
int i;
|
|
|
|
printf("\n--- VTOC format 7 label ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
printf("key identifier\n DS7KEYID : ");
|
|
for (i = 0; i < 4; i++)
|
|
printf("%02x", f7->DS7KEYID[i]);
|
|
printf("\nfirst 5 extent descriptions\n");
|
|
for (i = 0; i < 5; i++) {
|
|
printf(" DS7EXTNT[%d] : %08x %08x "
|
|
"(start trk %d, end trk %d)\n", i + 1,
|
|
f7->DS7EXTNT[i].a, f7->DS7EXTNT[i].b,
|
|
f7->DS7EXTNT[i].a, f7->DS7EXTNT[i].b);
|
|
}
|
|
printf("format identifier\n"
|
|
" DS7FMTID : dec %d, hex %02x\n",
|
|
f7->DS7FMTID, f7->DS7FMTID);
|
|
printf("next 11 extent descriptions\n");
|
|
for (i = 0; i < 11; i++) {
|
|
printf(" DS7ADEXT[%d] : %08x %08x "
|
|
"(start trk %d, end trk %d)\n", i + 6,
|
|
f7->DS7ADEXT[i].a, f7->DS7ADEXT[i].b,
|
|
f7->DS7ADEXT[i].a, f7->DS7ADEXT[i].b);
|
|
}
|
|
printf("reserved field\n res1 : ");
|
|
for (i = 0; i < 2; i++)
|
|
printf("%02x", f7->res1[i]);
|
|
printf("\npointer to next format 7 label\n"
|
|
" DS7PTRDS : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f7->DS7PTRDS.cc, f7->DS7PTRDS.hh,
|
|
f7->DS7PTRDS.b,
|
|
vtoc_get_cyl_from_cchhb(&f7->DS7PTRDS),
|
|
vtoc_get_head_from_cchhb(&f7->DS7PTRDS),
|
|
f7->DS7PTRDS.b);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f9_nohead(format9_label_t *f9)
|
|
{
|
|
unsigned int i;
|
|
|
|
printf("DS9KEYID : dec %d, hex %02x\n",
|
|
f9->DS9KEYID, f9->DS9KEYID);
|
|
printf("DS9SUBTY : dec %d, hex %02x\n",
|
|
f9->DS9SUBTY, f9->DS9SUBTY);
|
|
printf("DS9NUMF9 : dec %d, hex %02x\n",
|
|
f9->DS9NUMF9, f9->DS9NUMF9);
|
|
|
|
printf("res1 : hex ");
|
|
for (i = 0; i < sizeof(f9->res1); i++) {
|
|
if ((i > 0) && (i % 16 == 0))
|
|
printf("\n ");
|
|
printf("%02x", f9->res1[i]);
|
|
if ((i + 9) % 16 == 0)
|
|
printf(" ");
|
|
}
|
|
printf("\n");
|
|
|
|
printf("DS9FMTID : dec %d, hex %02x\n",
|
|
f9->DS9FMTID, f9->DS9FMTID);
|
|
|
|
printf("res2 : hex ");
|
|
for (i = 0; i < sizeof(f9->res2); i++) {
|
|
if ((i > 0) && (i % 16 == 0))
|
|
printf("\n ");
|
|
printf("%02x", f9->res2[i]);
|
|
if ((i + 9) % 16 == 0)
|
|
printf(" ");
|
|
}
|
|
printf("\n");
|
|
printf("pointer to next format 9 label\n"
|
|
" DS9PTRDS : %04x%04x%02x "
|
|
"(cyl %d, trk %d, blk %d)\n",
|
|
f9->DS9PTRDS.cc, f9->DS9PTRDS.hh,
|
|
f9->DS9PTRDS.b,
|
|
vtoc_get_cyl_from_cchhb(&f9->DS9PTRDS),
|
|
vtoc_get_head_from_cchhb(&f9->DS9PTRDS),
|
|
f9->DS9PTRDS.b);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f9_raw(format9_label_t *f9)
|
|
{
|
|
printf("\n--- VTOC format 9 label ----------------------"
|
|
"---------------------------------\n");
|
|
dasdview_print_vtoc_f9_nohead(f9);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_dscb(dasdview_info_t *info, void *dscb)
|
|
{
|
|
format1_label_t *tmp = dscb;
|
|
|
|
switch (tmp->DS1FMTID) {
|
|
case 0x00:
|
|
break;
|
|
case 0xf1:
|
|
if (info->vtoc_f1 || info->vtoc_all)
|
|
dasdview_print_vtoc_f1_raw(dscb);
|
|
break;
|
|
case 0xf3:
|
|
if (info->vtoc_f3 || info->vtoc_all)
|
|
dasdview_print_vtoc_f3_raw(dscb);
|
|
break;
|
|
case 0xf4:
|
|
if (info->vtoc_f4 || info->vtoc_all)
|
|
dasdview_print_vtoc_f4_raw(dscb);
|
|
break;
|
|
case 0xf5:
|
|
if (info->vtoc_f5 || info->vtoc_all)
|
|
dasdview_print_vtoc_f5_raw(dscb);
|
|
break;
|
|
case 0xf7:
|
|
if (info->vtoc_f7 || info->vtoc_all)
|
|
dasdview_print_vtoc_f7_raw(dscb);
|
|
break;
|
|
case 0xf8:
|
|
if (info->vtoc_f8 || info->vtoc_all)
|
|
dasdview_print_vtoc_f8_raw(dscb);
|
|
break;
|
|
case 0xf9:
|
|
if (info->vtoc_f9 || info->vtoc_all)
|
|
dasdview_print_vtoc_f9_raw(dscb);
|
|
break;
|
|
default:
|
|
printf("unrecognized DSCB of type: %x \n\n", tmp->DS1FMTID);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f1(dasdview_info_t *info)
|
|
{
|
|
int j;
|
|
|
|
printf("--- VTOC format 1 labels ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
if (info->f1c < 1) {
|
|
printf("This VTOC doesn't contain a format 1 label.\n");
|
|
return;
|
|
}
|
|
|
|
for (j = 0; j < info->f1c; j++) {
|
|
printf("\n--- format 1 DSCB number %d ---\n", j + 1);
|
|
dasdview_print_format1_8_no_head(&info->f1[j]);
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f8(dasdview_info_t *info)
|
|
{
|
|
int j;
|
|
|
|
printf("--- VTOC format 8 labels ----------------------"
|
|
"---------------------------------\n");
|
|
|
|
if (info->f8c < 1) {
|
|
printf("This VTOC doesn't contain a format 8 label.\n");
|
|
return;
|
|
}
|
|
|
|
for (j = 0; j < info->f8c; j++) {
|
|
printf("\n--- format 8 DSCB number %d ---\n", j + 1);
|
|
dasdview_print_format1_8_no_head(&info->f8[j]);
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f4(dasdview_info_t *info)
|
|
{
|
|
if (info->f4c < 1) {
|
|
printf("\n--- VTOC format 4 label ----------------------"
|
|
"---------------------------------\n");
|
|
printf("This VTOC doesn't contain a format 4 label.\n");
|
|
return;
|
|
}
|
|
dasdview_print_vtoc_f4_raw(&info->f4);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f5(dasdview_info_t *info)
|
|
{
|
|
if (info->f5c < 1) {
|
|
printf("\n--- VTOC format 5 label ----------------------"
|
|
"---------------------------------\n");
|
|
printf("This VTOC doesn't contain a format 5 label.\n");
|
|
return;
|
|
}
|
|
dasdview_print_vtoc_f5_raw(&info->f5);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f7(dasdview_info_t *info)
|
|
{
|
|
if (info->f7c < 1) {
|
|
printf("\n--- VTOC format 7 label ----------------------"
|
|
"---------------------------------\n");
|
|
printf("This VTOC doesn't contain a format 7 label.\n");
|
|
return;
|
|
}
|
|
dasdview_print_vtoc_f7_raw(&info->f7);
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f9(dasdview_info_t *info)
|
|
{
|
|
int j;
|
|
|
|
printf("\n--- VTOC format 9 label ----------------------"
|
|
"---------------------------------\n");
|
|
if (info->f9c < 1) {
|
|
printf("This VTOC doesn't contain a format 9 label.\n");
|
|
return;
|
|
}
|
|
for (j = 0; j < info->f9c; j++) {
|
|
printf("\n--- format 9 DSCB number %d ---\n", j + 1);
|
|
dasdview_print_vtoc_f9_nohead(&info->f9[j]);
|
|
}
|
|
}
|
|
|
|
static void dasdview_print_vtoc_f3(void)
|
|
{
|
|
/* dasdfmt formatted DASD devices have no format3 labels, but since the
|
|
* option exists for raw DASDs, we need to have some sensible message
|
|
*/
|
|
printf("\n--- VTOC format 3 label ----------------------"
|
|
"---------------------------------\n");
|
|
printf("This VTOC doesn't contain a format 3 label.\n");
|
|
}
|
|
|
|
static void dasdview_print_vtoc_standard(dasdview_info_t *info)
|
|
{
|
|
dasdview_read_vtoc(info);
|
|
|
|
if (info->vtoc_info || info->vtoc_all)
|
|
dasdview_print_vtoc_info(info);
|
|
|
|
if (info->vtoc_f4 || info->vtoc_all)
|
|
dasdview_print_vtoc_f4(info);
|
|
|
|
if (info->vtoc_f5 || info->vtoc_all)
|
|
dasdview_print_vtoc_f5(info);
|
|
|
|
if (info->vtoc_f7 || info->vtoc_all)
|
|
dasdview_print_vtoc_f7(info);
|
|
|
|
if (info->vtoc_f1 || info->vtoc_all)
|
|
dasdview_print_vtoc_f1(info);
|
|
|
|
if (info->vtoc_f8 || info->vtoc_all)
|
|
dasdview_print_vtoc_f8(info);
|
|
|
|
if (info->vtoc_f9 || info->vtoc_all)
|
|
dasdview_print_vtoc_f9(info);
|
|
|
|
if (info->vtoc_f3 || info->vtoc_all)
|
|
dasdview_print_vtoc_f3();
|
|
}
|
|
|
|
/* a simple routine to print all records in the vtoc */
|
|
static void dasdview_print_vtoc_raw(dasdview_info_t *info)
|
|
{
|
|
struct dscbiterator *it;
|
|
struct dscb *record;
|
|
int rc;
|
|
|
|
rc = lzds_dasd_read_vlabel(info->dasd);
|
|
if (rc) {
|
|
zt_error_print("error when reading label from device:"
|
|
" rc=%d\n", rc);
|
|
exit(-1);
|
|
}
|
|
rc = lzds_dasd_alloc_rawvtoc(info->dasd);
|
|
if (rc == EINVAL) {
|
|
zt_error_print("dasdview: Cannot read VTOC because disk does"
|
|
" not contain valid VOL1 label.\n",
|
|
info->device);
|
|
exit(-1);
|
|
} else if (rc) {
|
|
zt_error_print("error when reading vtoc from device:"
|
|
" rc=%d\n", rc);
|
|
exit(-1);
|
|
}
|
|
rc = lzds_dasd_get_rawvtoc(info->dasd, &info->rawvtoc);
|
|
if (rc || !info->rawvtoc) {
|
|
zt_error_print("dasdview: libvtoc could not read vtoc\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (info->vtoc_info || info->vtoc_all)
|
|
dasdview_print_vtoc_info_raw(info);
|
|
|
|
rc = lzds_raw_vtoc_alloc_dscbiterator(info->rawvtoc, &it);
|
|
if (rc) {
|
|
zt_error_print("dasdview: could not allocate DSCB iterator\n");
|
|
exit(-1);
|
|
}
|
|
while (!lzds_dscbiterator_get_next_dscb(it, &record))
|
|
dasdview_print_vtoc_dscb(info, record);
|
|
lzds_dscbiterator_free(it);
|
|
}
|
|
|
|
static void dasdview_print_vtoc(dasdview_info_t *info)
|
|
{
|
|
if (info->raw_track_access)
|
|
dasdview_print_vtoc_raw(info);
|
|
else
|
|
dasdview_print_vtoc_standard(info);
|
|
}
|
|
|
|
static int
|
|
dasdview_print_format1(unsigned int size, unsigned char *dumpstr)
|
|
{
|
|
unsigned int i;
|
|
char asc[17], ebc[17];
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if ((i / 16) * 16 == i) {
|
|
printf("\n| ");
|
|
strncpy(asc, (char *)dumpstr + i, 16);
|
|
strncpy(ebc, (char *)dumpstr + i, 16);
|
|
asc[16] = '\0';
|
|
ebc[16] = '\0';
|
|
}
|
|
printf("%02X", dumpstr[i]);
|
|
if (((i + 1) / 4) * 4 == i + 1)
|
|
printf(" ");
|
|
if (((i + 1) / 8) * 8 == i + 1)
|
|
printf(" ");
|
|
if (((i + 1) / 16) * 16 == i + 1) {
|
|
vtoc_ebcdic_dec(asc, asc, 16);
|
|
dot(asc);
|
|
dot(ebc);
|
|
printf("| %16.16s | %16.16s |", asc, ebc);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
dasdview_print_format2(unsigned int size, unsigned char *dumpstr,
|
|
unsigned long long begin)
|
|
{
|
|
unsigned int i;
|
|
char asc[17], ebc[17];
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if ((i / 8) * 8 == i) {
|
|
printf("\n | %13llu | %13llX | ",
|
|
begin + (unsigned long long)i,
|
|
begin + (unsigned long long)i);
|
|
|
|
strncpy(asc, (char *)dumpstr + i, 8);
|
|
strncpy(ebc, (char *)dumpstr + i, 8);
|
|
}
|
|
printf("%02X", dumpstr[i]);
|
|
if (((i + 1) / 4) * 4 == i + 1)
|
|
printf(" ");
|
|
if (((i + 1) / 8) * 8 == i + 1) {
|
|
vtoc_ebcdic_dec(asc, asc, 8);
|
|
dot(asc);
|
|
dot(ebc);
|
|
printf("| %8.8s | %8.8s |", asc, ebc);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void dasdview_view_standard(dasdview_info_t *info)
|
|
{
|
|
unsigned char dumpstr[DUMP_STRING_SIZE];
|
|
unsigned long long i = 0, j = 0, k = 0, count = 0;
|
|
int fd, rc;
|
|
|
|
unsigned long long a = 0;
|
|
int b = 0;
|
|
|
|
k = ((info->size) % 16LL);
|
|
|
|
if (k != 0)
|
|
info->size += (16LL - k);
|
|
|
|
fd = open(info->device, O_RDONLY);
|
|
if (fd == -1) {
|
|
zt_error_print("dasdview: open error\n"
|
|
"Unable to open device %s in read-only mode!\n",
|
|
info->device);
|
|
exit(-1);
|
|
}
|
|
|
|
j = (info->begin / SEEK_STEP);
|
|
k = (info->begin % SEEK_STEP);
|
|
|
|
/* seek in SEEK_STEP steps */
|
|
for (i = 1; i <= j; i++) {
|
|
rc = lseek64(fd, SEEK_STEP, SEEK_CUR);
|
|
if (rc == -1) {
|
|
printf("*** rc: %d (%d) ***\n", rc, errno);
|
|
printf("*** j: %llu ***\n", j);
|
|
printf("*** k: %llu ***\n", k);
|
|
printf("*** a: %llu ***\n", a);
|
|
printf("*** b: %d ***\n", b);
|
|
close(fd);
|
|
zt_error_print("dasdview: seek error\n"
|
|
"Unable to seek in device %s!\n",
|
|
info->device);
|
|
exit(-1);
|
|
}
|
|
b++;
|
|
a += SEEK_STEP;
|
|
}
|
|
|
|
if (k > 0) {
|
|
rc = lseek(fd, k, SEEK_CUR);
|
|
if (rc == -1) {
|
|
close(fd);
|
|
zt_error_print("dasdview: seek error\n"
|
|
"Unable to seek in device %s!\n",
|
|
info->device);
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
j = info->size / DUMP_STRING_SIZE;
|
|
k = info->size % DUMP_STRING_SIZE;
|
|
|
|
if (info->format1) {
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+\n");
|
|
printf("| HEXADECIMAL |"
|
|
" EBCDIC | ASCII |\n");
|
|
printf("| 01....04 05....08 09....12 13....16 |"
|
|
" 1.............16 | 1.............16 |\n");
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+");
|
|
} else if (info->format2) {
|
|
printf(" +---------------+---------------+----------------"
|
|
"------+----------+----------+\n");
|
|
printf(" | BYTE | BYTE | HEXADECIMAL"
|
|
" | EBCDIC | ASCII |\n");
|
|
printf(" | DECIMAL | HEXADECIMAL | 1 2 3 4 5 6 "
|
|
"7 8 | 12345678 | 12345678 |\n");
|
|
printf(" +---------------+---------------+----------------"
|
|
"------+----------+----------+");
|
|
}
|
|
|
|
count = info->begin;
|
|
for (i = 1; i <= j; i++) {
|
|
bzero(dumpstr, DUMP_STRING_SIZE);
|
|
rc = read(fd, &dumpstr, DUMP_STRING_SIZE);
|
|
if (rc != DUMP_STRING_SIZE) {
|
|
close(fd);
|
|
zt_error_print("dasdview: read error\n"
|
|
"Unable to read from device %s!\n",
|
|
info->device);
|
|
exit(-1);
|
|
}
|
|
|
|
if (info->format1)
|
|
dasdview_print_format1(DUMP_STRING_SIZE, dumpstr);
|
|
else if (info->format2)
|
|
dasdview_print_format2(DUMP_STRING_SIZE, dumpstr,
|
|
count);
|
|
count += DUMP_STRING_SIZE;
|
|
}
|
|
|
|
if (k > 0) {
|
|
bzero(dumpstr, DUMP_STRING_SIZE);
|
|
rc = read(fd, &dumpstr, k);
|
|
if (rc != (int)k) {
|
|
close(fd);
|
|
zt_error_print("dasdview: read error\n"
|
|
"Unable to read from device %s!\n",
|
|
info->device);
|
|
exit(-1);
|
|
}
|
|
|
|
if (info->format1)
|
|
dasdview_print_format1((unsigned int)k, dumpstr);
|
|
else if (info->format2)
|
|
dasdview_print_format2((unsigned int)k, dumpstr,
|
|
count);
|
|
}
|
|
|
|
close(fd);
|
|
|
|
if (info->format1)
|
|
printf("\n+----------------------------------------+"
|
|
"------------------+------------------+\n\n");
|
|
else if (info->format2)
|
|
printf("\n +---------------+---------------+----------------"
|
|
"------+----------+----------+\n\n");
|
|
}
|
|
|
|
static void dasdview_print_format_raw(unsigned int size, char *dumpstr)
|
|
{
|
|
unsigned int i;
|
|
char asc[17], ebc[17];
|
|
unsigned int residual, count;
|
|
char *data;
|
|
|
|
data = dumpstr;
|
|
residual = size;
|
|
while (residual) {
|
|
/* we handle at most 16 bytes per line */
|
|
count = MIN(residual, 16u);
|
|
bzero(asc, 17);
|
|
bzero(ebc, 17);
|
|
printf("|");
|
|
memcpy(asc, data, count);
|
|
memcpy(ebc, data, count);
|
|
|
|
for (i = 0; i < 16; ++i) {
|
|
if ((i % 4) == 0)
|
|
printf(" ");
|
|
if ((i % 8) == 0)
|
|
printf(" ");
|
|
if (i < count)
|
|
printf("%02X", data[i]);
|
|
else
|
|
printf(" ");
|
|
}
|
|
vtoc_ebcdic_dec(asc, asc, count);
|
|
dot(asc);
|
|
dot(ebc);
|
|
printf(" | %16.16s | %16.16s |\n", asc, ebc);
|
|
data += count;
|
|
residual -= count;
|
|
}
|
|
}
|
|
|
|
/* gets the pointer to an eckd record structure in memory and
|
|
* prints a hex/ascii/ebcdic dump for it
|
|
*/
|
|
static void dasdview_print_raw_record(char *rec)
|
|
{
|
|
struct eckd_count *ecount;
|
|
unsigned int cyl, head;
|
|
|
|
ecount = (struct eckd_count *)rec;
|
|
/* Note: the first 5 bytes of the count area are the
|
|
* record ID and by convention these bytes are interpreted
|
|
* as CCHHR (or ccccCCChR for large volumes)
|
|
*/
|
|
cyl = vtoc_get_cyl_from_cchhb(&ecount->recid);
|
|
head = vtoc_get_head_from_cchhb(&ecount->recid);
|
|
printf("+-----------------------------------------"
|
|
"-------------------------------------+\n");
|
|
printf("| count area: "
|
|
" |\n");
|
|
printf("| hex: %016llX "
|
|
" |\n",
|
|
*((unsigned long long *)ecount));
|
|
printf("| cylinder: %9d "
|
|
" |\n", cyl);
|
|
printf("| head: %9d "
|
|
" |\n", head);
|
|
printf("| record: %9d "
|
|
" |\n", ecount->recid.b);
|
|
printf("| key length: %9d "
|
|
" |\n", ecount->kl);
|
|
printf("| data length: %9d "
|
|
" |\n", ecount->dl);
|
|
printf("+-----------------------------------------"
|
|
"-------------------------------------+\n");
|
|
printf("| key area: "
|
|
" |\n");
|
|
printf("| HEXADECIMAL |"
|
|
" EBCDIC | ASCII |\n");
|
|
printf("| 01....04 05....08 09....12 13....16 |"
|
|
" 1.............16 | 1.............16 |\n");
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+\n");
|
|
dasdview_print_format_raw(ecount->kl, rec + sizeof(*ecount));
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+\n");
|
|
printf("| data area: "
|
|
" |\n");
|
|
printf("| HEXADECIMAL |"
|
|
" EBCDIC | ASCII |\n");
|
|
printf("| 01....04 05....08 09....12 13....16 |"
|
|
" 1.............16 | 1.............16 |\n");
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+\n");
|
|
dasdview_print_format_raw(ecount->dl,
|
|
rec + sizeof(*ecount) + ecount->kl);
|
|
printf("+----------------------------------------+"
|
|
"------------------+------------------+\n");
|
|
}
|
|
|
|
static void dasdview_print_raw_track(char *trackdata,
|
|
unsigned int cyl,
|
|
unsigned int head)
|
|
{
|
|
struct eckd_count *ecount;
|
|
char *data;
|
|
u_int32_t record;
|
|
|
|
record = 0;
|
|
data = trackdata;
|
|
|
|
do {
|
|
printf("cylinder %u, head %u, record %u\n",
|
|
cyl, head, record);
|
|
dasdview_print_raw_record(data);
|
|
printf("\n");
|
|
|
|
ecount = (struct eckd_count *)data;
|
|
data += sizeof(*ecount) + ecount->kl + ecount->dl;
|
|
++record;
|
|
|
|
if ((*(unsigned long long *)data) == ENDTOKEN)
|
|
break;
|
|
if ((unsigned long)data >=
|
|
(unsigned long)trackdata + RAWTRACKSIZE)
|
|
break;
|
|
} while (1);
|
|
}
|
|
|
|
static void dasdview_view_raw(dasdview_info_t *info)
|
|
{
|
|
u_int64_t residual, trckstart, trckend, track, trckbuffsize;
|
|
u_int64_t tracks_to_read, trckcount, i;
|
|
char *trackdata;
|
|
char *data;
|
|
int rc;
|
|
struct dasdhandle *dasdh;
|
|
|
|
trckstart = info->begin / RAWTRACKSIZE;
|
|
tracks_to_read = info->size / RAWTRACKSIZE;
|
|
|
|
/* TODO: how large should we make our buffer?
|
|
* The DASD device driver cannot read more than 16 tracks at once
|
|
* but we can read a larger blob and the block layer will split up
|
|
* the requests for us.
|
|
*/
|
|
trckbuffsize = MIN(tracks_to_read, 16u);
|
|
/* track data must be page aligned for O_DIRECT */
|
|
trackdata = memalign(4096, trckbuffsize * RAWTRACKSIZE);
|
|
if (!trackdata) {
|
|
zt_error_print("failed to allocate memory\n");
|
|
exit(-1);
|
|
}
|
|
rc = lzds_dasd_alloc_dasdhandle(info->dasd, &dasdh);
|
|
if (rc) {
|
|
zt_error_print("failed to allocate memory\n");
|
|
exit(-1);
|
|
}
|
|
rc = lzds_dasdhandle_open(dasdh);
|
|
if (rc) {
|
|
lzds_dasdhandle_free(dasdh);
|
|
zt_error_print("failed to open device\n");
|
|
exit(-1);
|
|
}
|
|
/* residual is the number of tracks we still have to read */
|
|
residual = tracks_to_read;
|
|
track = trckstart;
|
|
while (residual) {
|
|
trckcount = MIN(trckbuffsize, residual);
|
|
trckend = track + trckcount - 1;
|
|
rc = lzds_dasdhandle_read_tracks_to_buffer(dasdh, track,
|
|
trckend, trackdata);
|
|
if (rc) {
|
|
perror("Error on read");
|
|
exit(-1);
|
|
}
|
|
data = trackdata;
|
|
for (i = 0; i < trckcount; ++i) {
|
|
dasdview_print_raw_track(data, track / info->geo.heads,
|
|
track % info->geo.heads);
|
|
data += RAWTRACKSIZE;
|
|
++track;
|
|
}
|
|
residual -= trckcount;
|
|
}
|
|
|
|
free(trackdata);
|
|
|
|
rc = lzds_dasdhandle_close(dasdh);
|
|
lzds_dasdhandle_free(dasdh);
|
|
if (rc < 0) {
|
|
perror("Error on closing file");
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
static void dasdview_view(dasdview_info_t *info)
|
|
{
|
|
if (info->raw_track_access)
|
|
dasdview_view_raw(info);
|
|
else
|
|
dasdview_view_standard(info);
|
|
}
|
|
|
|
static void
|
|
dasdview_print_characteristic(dasdview_info_t *info)
|
|
{
|
|
dasd_information2_t dasd_info = info->dasd_info;
|
|
|
|
printf("encrypted disk : %s\n",
|
|
(dasd_info.characteristics[46] & 0x80) ? "yes" : "no");
|
|
printf("solid state device : %s\n",
|
|
(dasd_info.characteristics[46] & 0x40) ? "yes" : "no");
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
dasdview_info_t info;
|
|
int oc;
|
|
unsigned long long max = 0LL;
|
|
char *begin_param_str = NULL;
|
|
char *size_param_str = NULL;
|
|
int rc;
|
|
|
|
util_prg_init(&prg);
|
|
util_opt_init(opt_vec, NULL);
|
|
|
|
bzero(&info, sizeof(info));
|
|
while (1) {
|
|
oc = util_opt_getopt_long(argc, argv);
|
|
|
|
switch (oc) {
|
|
case 'h':
|
|
util_prg_print_help();
|
|
util_opt_print_help();
|
|
exit(EXIT_SUCCESS);
|
|
case 'v':
|
|
util_prg_print_version();
|
|
exit(EXIT_SUCCESS);
|
|
case 'b':
|
|
begin_param_str = optarg;
|
|
info.action_specified = 1;
|
|
info.begin_specified = 1;
|
|
break;
|
|
case 's':
|
|
size_param_str = optarg;
|
|
info.action_specified = 1;
|
|
info.size_specified = 1;
|
|
break;
|
|
case '1':
|
|
info.format1 = 1;
|
|
info.format2 = 0;
|
|
break;
|
|
case '2':
|
|
info.format1 = 0;
|
|
info.format2 = 1;
|
|
break;
|
|
case 'i': /* print general DASD information and geometry */
|
|
info.action_specified = 1;
|
|
info.general_info = 1;
|
|
break;
|
|
case 'x': /* print extended DASD information */
|
|
info.action_specified = 1;
|
|
info.extended_info = 1;
|
|
break;
|
|
case 'j':
|
|
info.action_specified = 1;
|
|
info.volser = 1;
|
|
break;
|
|
case 't':
|
|
if (strcmp(optarg, "info") == 0) {
|
|
info.vtoc_info = 1;
|
|
} else if (strcmp(optarg, "f1") == 0) {
|
|
info.vtoc_f1 = 1;
|
|
} else if (strcmp(optarg, "f3") == 0) {
|
|
info.vtoc_f3 = 1;
|
|
} else if (strcmp(optarg, "f4") == 0) {
|
|
info.vtoc_f4 = 1;
|
|
} else if (strcmp(optarg, "f5") == 0) {
|
|
info.vtoc_f5 = 1;
|
|
} else if (strcmp(optarg, "f7") == 0) {
|
|
info.vtoc_f7 = 1;
|
|
} else if (strcmp(optarg, "f8") == 0) {
|
|
info.vtoc_f8 = 1;
|
|
} else if (strcmp(optarg, "f9") == 0) {
|
|
info.vtoc_f9 = 1;
|
|
} else if (strcmp(optarg, "all") == 0) {
|
|
info.vtoc_all = 1;
|
|
} else {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"%s is no valid argument for"
|
|
" option -t/--vtoc\n", optarg);
|
|
exit(-1);
|
|
}
|
|
info.vtoc = 1;
|
|
info.action_specified = 1;
|
|
break;
|
|
case 'l':
|
|
info.action_specified = 1;
|
|
info.vlabel_info = 1;
|
|
break;
|
|
case 'c':
|
|
info.action_specified = 1;
|
|
info.characteristic_specified = 1;
|
|
break;
|
|
case -1:
|
|
/* End of options string - start of devices list */
|
|
info.device_id = optind;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Try 'dasdview --help' for more"
|
|
" information.\n");
|
|
exit(1);
|
|
}
|
|
if (oc == -1)
|
|
break;
|
|
}
|
|
|
|
/* do some tests */
|
|
if (info.device_id >= argc) {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"No device specified!");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (info.device_id + 1 < argc) {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"More than one device specified!");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (info.device_id < argc)
|
|
strcpy(info.device, argv[info.device_id]);
|
|
|
|
dasdview_get_info(&info);
|
|
|
|
if (info.raw_track_access) {
|
|
rc = lzds_zdsroot_alloc(&info.zdsroot);
|
|
if (rc) {
|
|
zt_error_print("Could not allocate index\n");
|
|
exit(-1);
|
|
}
|
|
rc = lzds_zdsroot_add_device(info.zdsroot, info.device,
|
|
&info.dasd);
|
|
if (rc) {
|
|
zt_error_print("Could not add device to index\n");
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
if (info.begin_specified)
|
|
dasdview_parse_input(&info.begin, &info, begin_param_str);
|
|
else
|
|
info.begin = DEFAULT_BEGIN;
|
|
|
|
if (info.raw_track_access)
|
|
max = (unsigned long long)info.hw_cylinders *
|
|
(unsigned long long)info.geo.heads * RAWTRACKSIZE;
|
|
else
|
|
max = (unsigned long long)info.hw_cylinders *
|
|
(unsigned long long)info.geo.heads *
|
|
(unsigned long long)info.geo.sectors *
|
|
(unsigned long long)info.blksize;
|
|
|
|
if (info.begin > max) {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"'begin' value is not within disk range!");
|
|
exit(-1);
|
|
}
|
|
|
|
if (info.size_specified)
|
|
dasdview_parse_input(&info.size, &info, size_param_str);
|
|
else if (info.raw_track_access)
|
|
info.size = RAWTRACKSIZE;
|
|
else
|
|
info.size = DEFAULT_SIZE;
|
|
|
|
if ((info.begin_specified || info.size_specified) &&
|
|
((info.begin + info.size) > max)) {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"'begin' + 'size' is not within "
|
|
"disk range!");
|
|
exit(-1);
|
|
}
|
|
|
|
if ((info.begin_specified || info.size_specified) &&
|
|
(!info.format1 && !info.format2))
|
|
info.format1 = 1;
|
|
|
|
if ((info.format1 || info.format2) &&
|
|
(!info.size_specified && !info.begin_specified)) {
|
|
zt_error_print("dasdview: usage error\n"
|
|
"Options -1 or -2 make only sense with "
|
|
"options -b or -s!");
|
|
exit(-1);
|
|
}
|
|
|
|
/* do the output */
|
|
|
|
if (info.begin_specified || info.size_specified)
|
|
dasdview_view(&info);
|
|
|
|
if (info.general_info || info.extended_info)
|
|
dasdview_print_general_info(&info);
|
|
|
|
if (info.extended_info)
|
|
dasdview_print_extended_info(&info);
|
|
|
|
if (info.volser)
|
|
dasdview_print_volser(&info);
|
|
|
|
if (info.vlabel_info)
|
|
dasdview_print_vlabel(&info);
|
|
|
|
if (info.vtoc)
|
|
dasdview_print_vtoc(&info);
|
|
|
|
if (!info.action_specified)
|
|
printf("No action specified.\n");
|
|
|
|
if (info.characteristic_specified)
|
|
dasdview_print_characteristic(&info);
|
|
|
|
return 0;
|
|
}
|