Marcus Meissner
9b729e2acc
New package per "Factory first" policy. Please list me as bug owner and maintainer, if possible. OBS-URL: https://build.opensuse.org/request/show/459343 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=1
556 lines
18 KiB
Diff
556 lines
18 KiB
Diff
Subject: [PATCH] [FEAT LS1501] dasdfmt: Add new formatting modes
|
|
From: Jan Höppner <hoeppner@linux.vnet.ibm.com>
|
|
|
|
Summary: dasdfmt: Add new formatting modes
|
|
Description: Introduce new formatting modes 'quick' and 'expand' to either
|
|
format an earlier formatted DASD that could potentially be
|
|
re-initialized very easily or format unformatted tracks at the
|
|
end of a device that was previously extended.
|
|
|
|
Also add the command line argument --check to provide a function
|
|
that checks a DASD volume for correct formatting.
|
|
Upstream-ID: -
|
|
Problem-ID: LS1501
|
|
|
|
Upstream-Description:
|
|
|
|
dasdfmt: Add quick format support
|
|
|
|
On occasion, a DASD device might have been formatted earlier and could
|
|
potentially be re-initialized very easily. For device initalization it
|
|
is necessary to write disk information (i.e. volume label (CDL or LDL)
|
|
and VTOC) to the first two tracks. Currently you'd need to format the
|
|
entire disk, which can take a long time and is totally unnecessary.
|
|
|
|
Therefore, add a quick format mode which formats only the first two
|
|
tracks and fills them with data accordingly.
|
|
Before any formatting is done, several checks regarding the
|
|
expected device format are performed.
|
|
|
|
The mode can be specified with the new command line switch -M (--mode)
|
|
<mode>. Where 'mode' can be either 'full' (default) or 'quick'.
|
|
|
|
Document the switch -M (--mode) and its options full and quick in the
|
|
man page.
|
|
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
|
|
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
|
|
|
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
|
|
---
|
|
dasdfmt/dasdfmt.8 | 15 ++
|
|
dasdfmt/dasdfmt.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
dasdfmt/dasdfmt.h | 51 +++++++++
|
|
3 files changed, 344 insertions(+), 12 deletions(-)
|
|
|
|
--- a/dasdfmt/dasdfmt.8
|
|
+++ b/dasdfmt/dasdfmt.8
|
|
@@ -67,7 +67,7 @@ Print version number and exit.
|
|
|
|
.TP
|
|
\fB-F\fR or \fB--force\fR
|
|
-Formats the device without checking, if the device is in use.
|
|
+Formats the device without performing sanity checking.
|
|
|
|
.TP
|
|
\fB-C\fR or \fB--check_host_count\fR
|
|
@@ -108,6 +108,19 @@ The value will be at least as big as the
|
|
.br
|
|
|
|
.TP
|
|
+\fB-M\fR \fImode\fR or \fB--mode\fR=\fImode\fR
|
|
+Specify the \fImode\fR to be used to format the device. Valid modes are:
|
|
+.RS
|
|
+.IP full
|
|
+Format the entire disk with the specified blocksize. (default)
|
|
+.IP quick
|
|
+Format the first two tracks and write label and partition information. Only use
|
|
+this option if you are sure that the target DASD already contains a regular
|
|
+format with the specified blocksize. A blocksize can optionally be specified
|
|
+using \fB-b\fR (\fB--blocksize\fR).
|
|
+.RE
|
|
+
|
|
+.TP
|
|
\fB-r\fR \fIcylindercount\fR or \fB--requestsize\fR=\fIcylindercount\fR
|
|
Number of cylinders to be processed in one formatting step.
|
|
The value must be an integer in the range 1 - 255.
|
|
--- a/dasdfmt/dasdfmt.c
|
|
+++ b/dasdfmt/dasdfmt.c
|
|
@@ -30,6 +30,7 @@ static const char copyright_notice[] = "
|
|
static int filedes;
|
|
static int disk_disabled;
|
|
static format_data_t format_params;
|
|
+static format_mode_t mode;
|
|
char *prog_name;
|
|
volatile sig_atomic_t program_interrupt_in_progress;
|
|
int reqsize;
|
|
@@ -53,6 +54,7 @@ static void exit_usage(int exitcode)
|
|
" [-b <blocksize> | --blocksize=<blocksize>]\n"
|
|
" [-d <disk layout> | --disk_layout=<disk layout>]\n"
|
|
" [-r <cylinder> | --requestsize=<cylinder>]\n"
|
|
+ " [-M <mode> | --mode=<mode>]\n"
|
|
" <device>\n\n", prog_name);
|
|
|
|
printf(" -t or --test means testmode\n"
|
|
@@ -65,7 +67,7 @@ static void exit_usage(int exitcode)
|
|
" -r x or --requestsize=x means use x cylinders in one "
|
|
"format step\n"
|
|
" -v means verbose mode\n"
|
|
- " -F means don't check if the device is in use\n"
|
|
+ " -F means format without performing sanity checking\n"
|
|
" -k means keep volume serial\n"
|
|
" -C or --check_host_count means force dasdfmt to check\n"
|
|
" the host access open count to ensure the device\n"
|
|
@@ -79,7 +81,10 @@ static void exit_usage(int exitcode)
|
|
" <disk layout> is either\n"
|
|
" 'cdl' for compatible disk layout (default) or\n"
|
|
" 'ldl' for linux disk layout\n"
|
|
- " <device> device node of the device to format\n");
|
|
+ " <device> device node of the device to format\n"
|
|
+ " <mode> is either\n"
|
|
+ " 'full' to fully format the device (default)\n"
|
|
+ " 'quick' to format only the first two tracks\n");
|
|
exit(exitcode);
|
|
}
|
|
|
|
@@ -102,6 +107,131 @@ static int reread_partition_table(void)
|
|
}
|
|
|
|
/*
|
|
+ * Helper function for recs_per_track.
|
|
+ */
|
|
+static inline unsigned int ceil_quot(unsigned int d1, unsigned int d2)
|
|
+{
|
|
+ return (d1 + (d2 - 1)) / d2;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Calculate records per track depending on the device characteristics.
|
|
+ */
|
|
+static unsigned int recs_per_track(struct dasd_eckd_characteristics *rdc,
|
|
+ unsigned int kl, unsigned int dl)
|
|
+{
|
|
+ int dn, kn;
|
|
+
|
|
+ switch (rdc->dev_type) {
|
|
+ case 0x3380:
|
|
+ if (kl)
|
|
+ return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +
|
|
+ ceil_quot(dl + 12, 32));
|
|
+ else
|
|
+ return 1499 / (15 + ceil_quot(dl + 12, 32));
|
|
+ case 0x3390:
|
|
+ dn = ceil_quot(dl + 6, 232) + 1;
|
|
+ if (kl) {
|
|
+ kn = ceil_quot(kl + 6, 232) + 1;
|
|
+ return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
|
|
+ 9 + ceil_quot(dl + 6 * dn, 34));
|
|
+ } else
|
|
+ return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
|
|
+ case 0x9345:
|
|
+ dn = ceil_quot(dl + 6, 232) + 1;
|
|
+ if (kl) {
|
|
+ kn = ceil_quot(kl + 6, 232) + 1;
|
|
+ return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +
|
|
+ ceil_quot(dl + 6 * dn, 34));
|
|
+ } else
|
|
+ return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Evaluate errors recognized by format checks and print appropriate error
|
|
+ * messages depending on the content of cdata.
|
|
+ */
|
|
+static void evaluate_format_error(dasdfmt_info_t *info, format_check_t *cdata,
|
|
+ unsigned int heads)
|
|
+{
|
|
+ struct dasd_eckd_characteristics *rdc;
|
|
+ /* Special blocksize values of the first 3 records of trk 0 of cyl 0 */
|
|
+ const int blksizes_trk0[] = { 24, 144, 80 };
|
|
+ /* Special blocksize value of trk 1 cyl 0 */
|
|
+ const int blksize_trk1 = 96;
|
|
+ unsigned int cyl;
|
|
+ unsigned int head;
|
|
+ unsigned int rpt;
|
|
+ unsigned int kl = 0;
|
|
+ int blksize = cdata->expect.blksize;
|
|
+
|
|
+ /*
|
|
+ * Reading record zero will never happen. If the record in error is 0
|
|
+ * nonetheless, the device is not formatted at all!
|
|
+ */
|
|
+ if (cdata->rec == 0) {
|
|
+ ERRMSG("WARNING: The specified device is not "
|
|
+ "formatted at all.\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ cyl = cdata->unit / heads;
|
|
+ head = cyl >> 16;
|
|
+ head <<= 4;
|
|
+ head |= cdata->unit % heads;
|
|
+
|
|
+ /*
|
|
+ * Set special expected values for the first 3 records of trk 0 of cyl 0
|
|
+ * and trk 1 of cyl 0 when checking a CDL formatted device.
|
|
+ */
|
|
+ if ((cdata->expect.intensity & DASD_FMT_INT_COMPAT) &&
|
|
+ cyl == 0 && head == 0 && cdata->rec < 4) {
|
|
+ kl = 4;
|
|
+ blksize = blksizes_trk0[cdata->rec - 1];
|
|
+ }
|
|
+ if ((cdata->expect.intensity & DASD_FMT_INT_COMPAT) &&
|
|
+ cyl == 0 && head == 1) {
|
|
+ kl = 44;
|
|
+ blksize = blksize_trk1;
|
|
+ }
|
|
+
|
|
+ rdc = (struct dasd_eckd_characteristics *)
|
|
+ &info->dasd_info.characteristics;
|
|
+
|
|
+ rpt = recs_per_track(rdc, kl, cdata->expect.blksize);
|
|
+
|
|
+ ERRMSG("WARNING: The specified device is not formatted as expected.\n");
|
|
+ switch (cdata->result) {
|
|
+ case DASD_FMT_ERR_TOO_FEW_RECORDS:
|
|
+ ERRMSG("Too few records (found %d, expected %d) "
|
|
+ "at cyl: %d trk: %d rec: %d.\n",
|
|
+ cdata->num_records, rpt, cyl, head, cdata->rec);
|
|
+ break;
|
|
+ case DASD_FMT_ERR_TOO_MANY_RECORDS:
|
|
+ ERRMSG("Too many records (found %d, expected %d) "
|
|
+ "at cyl: %d trk: %d rec: %d.\n",
|
|
+ cdata->num_records, rpt, cyl, head, cdata->rec);
|
|
+ break;
|
|
+ case DASD_FMT_ERR_BLKSIZE:
|
|
+ ERRMSG("Invalid blocksize (found %d, expected %d) "
|
|
+ "at cyl: %d trk: %d rec: %d.\n",
|
|
+ cdata->blksize, blksize, cyl, head, cdata->rec);
|
|
+ break;
|
|
+ case DASD_FMT_ERR_RECORD_ID:
|
|
+ ERRMSG("Invalid record ID at cyl: %d trk: %d rec: %d.\n",
|
|
+ cyl, head, cdata->rec);
|
|
+ break;
|
|
+ case DASD_FMT_ERR_KEY_LENGTH:
|
|
+ ERRMSG("Invalid key length (found %d, expected %d) "
|
|
+ "at cyl: %d trk: %d rec: %d.\n",
|
|
+ cdata->key_length, kl, cyl, head, cdata->rec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
* signal handler:
|
|
* enables the disk again in case of SIGTERM, SIGINT and SIGQUIT
|
|
*/
|
|
@@ -263,6 +393,25 @@ static void get_blocksize(unsigned int *
|
|
}
|
|
|
|
/*
|
|
+ * Check whether a specified blocksize matches the blocksize of the device
|
|
+ */
|
|
+static void check_blocksize(dasdfmt_info_t *info, unsigned int blksize)
|
|
+{
|
|
+ unsigned int dev_blksize;
|
|
+
|
|
+ if (!info->blksize_specified ||
|
|
+ info->dasd_info.format == DASD_FORMAT_NONE)
|
|
+ return;
|
|
+
|
|
+ get_blocksize(&dev_blksize);
|
|
+ if (dev_blksize != blksize) {
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "WARNING: Device is formatted with a "
|
|
+ "different blocksize (%d).\nUse --mode=full to "
|
|
+ "perform a clean format.\n", dev_blksize);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
* check for disk type and set some variables (e.g. usage count)
|
|
*/
|
|
static void check_disk(dasdfmt_info_t *info)
|
|
@@ -449,6 +598,35 @@ static void set_label(dasdfmt_info_t *in
|
|
}
|
|
|
|
/*
|
|
+ * This function checks whether a range of tracks is in regular format
|
|
+ * with the specified block size.
|
|
+ */
|
|
+static format_check_t check_track_format(format_data_t *p)
|
|
+{
|
|
+ format_check_t cdata = {
|
|
+ .expect = {
|
|
+ .blksize = p->blksize,
|
|
+ .intensity = p->intensity,
|
|
+ .start_unit = p->start_unit,
|
|
+ .stop_unit = p->stop_unit
|
|
+ }, 0
|
|
+ };
|
|
+
|
|
+ if (ioctl(filedes, BIODASDCHECKFMT, &cdata)) {
|
|
+ if (errno == ENOTTY) {
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: Missing kernel support "
|
|
+ "for format checking (--force to "
|
|
+ "override)\n", prog_name);
|
|
+ }
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: Could no check format: %s\n",
|
|
+ prog_name, strerror(errno));
|
|
+ }
|
|
+
|
|
+ return cdata;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
* ask the user to specify a blocksize
|
|
*/
|
|
static format_data_t ask_user_for_blksize(format_data_t params)
|
|
@@ -511,6 +689,8 @@ static void dasdfmt_print_info(dasdfmt_i
|
|
printf(" Compatible Disk Layout : %s\n",
|
|
(p->intensity & DASD_FMT_INT_COMPAT) ? "yes" : "no");
|
|
printf(" Blocksize : %d\n", p->blksize);
|
|
+ printf(" Mode : %s\n",
|
|
+ (mode == FULL) ? "Full" : "Quick");
|
|
|
|
if (info->testmode)
|
|
printf("Test mode active, omitting ioctl.\n");
|
|
@@ -869,6 +1049,62 @@ static void dasdfmt_prepare_and_format(d
|
|
disk_disabled = 0;
|
|
}
|
|
|
|
+/*
|
|
+ * This function will only format the first two tracks of a DASD.
|
|
+ * The rest of the DASD is untouched and left as is.
|
|
+ */
|
|
+static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
|
|
+ unsigned int heads, format_data_t *p)
|
|
+{
|
|
+ format_check_t cdata = { .expect = {0}, 0 };
|
|
+ format_data_t tmp = *p;
|
|
+
|
|
+ if (info->force) {
|
|
+ printf("Skipping format check due to --force.\n");
|
|
+ } else {
|
|
+ check_blocksize(info, p->blksize);
|
|
+
|
|
+ printf("Checking the format of selected tracks...\n");
|
|
+
|
|
+ /* Check device format on the first and last 3 regular tracks */
|
|
+ tmp.start_unit = 2;
|
|
+ tmp.stop_unit = 4;
|
|
+ cdata = check_track_format(&tmp);
|
|
+ if (!cdata.result) {
|
|
+ tmp.start_unit = (cylinders * heads) - 3;
|
|
+ tmp.stop_unit = (cylinders * heads) - 1;
|
|
+ cdata = check_track_format(&tmp);
|
|
+ }
|
|
+ if (cdata.result) {
|
|
+ evaluate_format_error(info, &cdata, heads);
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "Use --mode=full to perform "
|
|
+ "a clean format.\n");
|
|
+ } else {
|
|
+ printf("Done. Disk seems fine.\n");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!((info->withoutprompt) && (info->verbosity < 1)))
|
|
+ printf("Formatting the first two tracks of the device.\n");
|
|
+
|
|
+ /* Disable the device before we do anything */
|
|
+ if (ioctl(filedes, BIODASDDISABLE, p))
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl to disable the device "
|
|
+ "failed. (%s)\n", prog_name, strerror(errno));
|
|
+ disk_disabled = 1;
|
|
+
|
|
+ /* Now do the actual formatting of our first two tracks */
|
|
+ if (ioctl(filedes, BIODASDFMT, p))
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl to format the device "
|
|
+ "failed. (%s)\n", prog_name, strerror(errno));
|
|
+
|
|
+ /* Re-Enable the device so that we can continue working with it */
|
|
+ if (ioctl(filedes, BIODASDENABLE, p))
|
|
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl to enable the device "
|
|
+ "failed. (%s)\n", prog_name, strerror(errno));
|
|
+ disk_disabled = 0;
|
|
+}
|
|
+
|
|
static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
|
format_data_t *p, unsigned int cylinders,
|
|
unsigned int heads)
|
|
@@ -877,7 +1113,15 @@ static void do_format_dasd(dasdfmt_info_
|
|
int count;
|
|
|
|
p->start_unit = 0;
|
|
- p->stop_unit = (cylinders * heads) - 1;
|
|
+
|
|
+ switch (mode) {
|
|
+ case FULL: /* all tracks */
|
|
+ p->stop_unit = (cylinders * heads) - 1;
|
|
+ break;
|
|
+ case QUICK: /* just the first two */
|
|
+ p->stop_unit = 1;
|
|
+ break;
|
|
+ }
|
|
|
|
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
|
|
dasdfmt_print_info(info, vlabel, cylinders, heads, p);
|
|
@@ -919,11 +1163,17 @@ static void do_format_dasd(dasdfmt_info_
|
|
}
|
|
}
|
|
|
|
- if (!((info->withoutprompt) && (info->verbosity < 1)))
|
|
- printf("Formatting the device. This may take a "
|
|
- "while (get yourself a coffee).\n");
|
|
-
|
|
- dasdfmt_prepare_and_format(info, cylinders, heads, p);
|
|
+ switch (mode) {
|
|
+ case FULL:
|
|
+ if (!((info->withoutprompt) && (info->verbosity < 1)))
|
|
+ printf("Formatting the device. This may take a "
|
|
+ "while (get yourself a coffee).\n");
|
|
+ dasdfmt_prepare_and_format(info, cylinders, heads, p);
|
|
+ break;
|
|
+ case QUICK:
|
|
+ dasdfmt_quick_format(info, cylinders, heads, p);
|
|
+ break;
|
|
+ }
|
|
|
|
if (!info->yast_mode)
|
|
printf("Finished formatting the device.\n");
|
|
@@ -981,6 +1231,8 @@ int main(int argc, char *argv[])
|
|
format_params.blksize = DEFAULT_BLOCKSIZE;
|
|
format_params.intensity = DASD_FMT_INT_COMPAT;
|
|
|
|
+ mode = FULL;
|
|
+
|
|
/*************** parse parameters **********************/
|
|
|
|
while (1) {
|
|
@@ -1082,6 +1334,18 @@ int main(int argc, char *argv[])
|
|
case 'C':
|
|
info.force_host = 1;
|
|
break;
|
|
+ case 'M':
|
|
+ if (strcasecmp(optarg, "full") == 0)
|
|
+ mode = FULL;
|
|
+ else if (strcasecmp(optarg, "quick") == 0)
|
|
+ mode = QUICK;
|
|
+ else
|
|
+ ERRMSG_EXIT(EXIT_FAILURE,
|
|
+ "%s: The specified mode '%s' is "
|
|
+ "invalid. Consult the man page for "
|
|
+ "more information.\n",
|
|
+ prog_name, optarg);
|
|
+ break;
|
|
case -1:
|
|
/* End of options string - start of devices list */
|
|
info.device_id = optind;
|
|
@@ -1194,8 +1458,14 @@ int main(int argc, char *argv[])
|
|
|
|
get_device_info(&info);
|
|
|
|
- if (!info.blksize_specified)
|
|
- format_params = ask_user_for_blksize(format_params);
|
|
+ /* Either let the user specify the blksize or get it from the kernel */
|
|
+ if (!info.blksize_specified) {
|
|
+ if (!(mode == FULL ||
|
|
+ info.dasd_info.format == DASD_FORMAT_NONE))
|
|
+ get_blocksize(&format_params.blksize);
|
|
+ else
|
|
+ format_params = ask_user_for_blksize(format_params);
|
|
+ }
|
|
|
|
if (info.keep_volser) {
|
|
if (format_params.intensity == 0x00) {
|
|
--- a/dasdfmt/dasdfmt.h
|
|
+++ b/dasdfmt/dasdfmt.h
|
|
@@ -143,6 +143,14 @@ struct dasd_eckd_characteristics {
|
|
unsigned int long_no_cyl;
|
|
} __attribute__ ((packed));
|
|
|
|
+/*
|
|
+ * Represents possible format modes that can be specified when formatting
|
|
+ * a DASD.
|
|
+ */
|
|
+typedef enum format_mode_t {
|
|
+ FULL, /* default mode */
|
|
+ QUICK, /* format only the first 2 tracks */
|
|
+} format_mode_t;
|
|
|
|
/*
|
|
* struct format_data_t
|
|
@@ -168,6 +176,43 @@ typedef struct format_data_t {
|
|
#define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */
|
|
#define DASD_FMT_INT_FMT_NOR0 16 /* remove permission to write record zero */
|
|
|
|
+/*
|
|
+ * struct format_check_t
|
|
+ * represents all data necessary to evaluate the format of
|
|
+ * different tracks of a dasd
|
|
+ */
|
|
+typedef struct format_check_t {
|
|
+ /* Input */
|
|
+ struct format_data_t expect;
|
|
+
|
|
+ /* Output */
|
|
+ unsigned int result; /* Error indication (DASD_FMT_ERR_*) */
|
|
+ unsigned int unit; /* Track that is in error */
|
|
+ unsigned int rec; /* Record that is in error */
|
|
+ unsigned int num_records; /* Records in the track in error */
|
|
+ unsigned int blksize; /* Block-size of first record in error */
|
|
+ unsigned int key_length; /* Key length of first record in error */
|
|
+} format_check_t;
|
|
+
|
|
+/*
|
|
+ * values to be used in format_check_t for indicating
|
|
+ * possible format errors
|
|
+ */
|
|
+#define DASD_FMT_ERR_TOO_FEW_RECORDS 1
|
|
+#define DASD_FMT_ERR_TOO_MANY_RECORDS 2
|
|
+#define DASD_FMT_ERR_BLKSIZE 3
|
|
+#define DASD_FMT_ERR_RECORD_ID 4
|
|
+#define DASD_FMT_ERR_KEY_LENGTH 5
|
|
+
|
|
+/*
|
|
+ * values to be used for dasd_information2_t.format
|
|
+ * 0x00: NOT formatted
|
|
+ * 0x01: Linux disc layout
|
|
+ * 0x02: Common disc layout
|
|
+ */
|
|
+#define DASD_FORMAT_NONE 0
|
|
+#define DASD_FORMAT_LDL 1
|
|
+#define DASD_FORMAT_CDL 2
|
|
|
|
/* Disable the volume (for Linux) */
|
|
#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0)
|
|
@@ -180,6 +225,9 @@ typedef struct format_data_t {
|
|
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
|
#define BIODASDFMT _IOW(DASD_IOCTL_LETTER,1,format_data_t)
|
|
|
|
+/* Check device format according to format_data_t */
|
|
+#define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t)
|
|
+
|
|
/****************************************************************************
|
|
* SECTION: Further IOCTL Definitions (see fs.h and hdreq.h ) *
|
|
****************************************************************************/
|
|
@@ -225,7 +273,7 @@ typedef struct format_data_t {
|
|
if (*endptr) ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \
|
|
"is in invalid format\n",prog_name);}
|
|
|
|
-#define dasdfmt_getopt_string "b:n:l:f:d:m:r:hpQLtyvVFkCYP:"
|
|
+#define dasdfmt_getopt_string "b:n:l:f:d:m:M:r:hpQLtyvVFkCYP:"
|
|
|
|
static struct option dasdfmt_getopt_long_options[]=
|
|
{
|
|
@@ -247,6 +295,7 @@ static struct option dasdfmt_getopt_long
|
|
{ "keep_volser", 0, 0, 'k'},
|
|
{ "norecordzero", 0, 0, 'z'},
|
|
{ "check_host_count", 0, 0, 'C'},
|
|
+ { "mode", 1, 0, 'M'},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|