Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:Update
s390-tools.18705
s390-tools-sles15-Allow-multiple-device-argumen...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles15-Allow-multiple-device-arguments.patch of Package s390-tools.18705
From d6582bbaf0f3986a42f562046dc0caa9de89c75e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke <hare@suse.de> Date: Fri, 6 Oct 2017 08:58:17 +0200 Subject: [PATCH] dasdfmt: Allow multiple device arguments Allow the user to specify several devices as arguments to dasdfmt. Signed-off-by: Hannes Reinecke <hare@suse.com> --- dasdfmt/dasdfmt.8 | 5 +- dasdfmt/dasdfmt.c | 175 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 100 insertions(+), 80 deletions(-) diff --git a/dasdfmt/dasdfmt.8 b/dasdfmt/dasdfmt.8 index 99da9ed..e7fc501 100644 --- a/dasdfmt/dasdfmt.8 +++ b/dasdfmt/dasdfmt.8 @@ -11,14 +11,15 @@ dasdfmt \- formatting of DASD (ECKD) disk drives. .br [-r \fIcylinder\fR] [-b \fIblksize\fR] [-l \fIvolser\fR] [-d \fIlayout\fR] .br - [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR + [-L] [-V] [-F] [-k] [-C] [-M \fImode\fR] \fIdevice\fR [\fIdevice\fR] .SH DESCRIPTION -\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it +\fBdasdfmt\fR formats one or several DASD (ECKD) disk drive to prepare it for usage with Linux for S/390. The \fIdevice\fR is the node of the device (e.g. '/dev/dasda'). Any device node created by udev for kernel 2.6 can be used (e.g. '/dev/dasd/0.0.b100/disc'). +It is possible to specify up to 512 devices. .br \fBWARNING\fR: Careless usage of \fBdasdfmt\fR can result in diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c index b79cff0..607fd1c 100644 --- a/dasdfmt/dasdfmt.c +++ b/dasdfmt/dasdfmt.c @@ -23,6 +23,7 @@ #include "dasdfmt.h" +#define MAX_DEVICES 512 #define BUSIDSIZE 8 #define SEC_PER_DAY (60 * 60 * 24) #define SEC_PER_HOUR (60 * 60) @@ -463,44 +464,40 @@ static void program_interrupt_signal(int sig) /* * check given device name for blanks and some special characters */ -static void get_device_name(char *devname, - int optind, int argc, char *argv[]) +static void get_device_name(char **devname, int numdev, + char argv[]) { struct util_proc_dev_entry dev_entry; struct stat dev_stat; - if (optind + 1 < argc) - ERRMSG_EXIT(EXIT_MISUSE, - "%s: More than one device specified!\n", prog_name); - - if (optind >= argc) - ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", - prog_name); - - if (strlen(argv[optind]) >= PATH_MAX) + if (strlen(argv) >= PATH_MAX) ERRMSG_EXIT(EXIT_MISUSE, "%s: device name too long!\n", prog_name); - strcpy(devname, argv[optind]); - if (stat(devname, &dev_stat) != 0) - ERRMSG_EXIT(EXIT_MISUSE, "%s: Could not get information for " - "device node %s: %s\n", prog_name, devname, - strerror(errno)); + devname[numdev] = argv; + if (stat(devname[numdev], &dev_stat) != 0) + ERRMSG_EXIT(EXIT_MISUSE, + "%s: Could not get information for " + "device node %s: %s\n", prog_name, + devname[numdev], strerror(errno)); if (minor(dev_stat.st_rdev) & PARTN_MASK) { - ERRMSG_EXIT(EXIT_MISUSE, "%s: Unable to format partition %s. " + ERRMSG_EXIT(EXIT_MISUSE, + "%s: Unable to format partition %s. " "Please specify a device.\n", prog_name, - devname); + devname[numdev]); } - if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, &dev_entry) == 0) { + if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, + &dev_entry) == 0) { if (strncmp(dev_entry.name, "dasd", 4) != 0) ERRMSG_EXIT(EXIT_MISUSE, "%s: Unsupported device type '%s'.\n", prog_name, dev_entry.name); } else { - printf("%s WARNING: Unable to get driver name for device node %s", - prog_name, devname); + printf("%s WARNING: Unable to get driver name" + " for device node %s", + prog_name, devname[numdev]); } } @@ -518,7 +515,7 @@ static void get_blocksize(const char *de /* * Check whether a specified blocksize matches the blocksize of the device */ -static void check_blocksize(dasdfmt_info_t *info, unsigned int blksize) +static void check_blocksize(dasdfmt_info_t *info, char *dev_filename, unsigned int blksize) { unsigned int dev_blksize; @@ -756,7 +753,7 @@ static void check_hashmarks(dasdfmt_info * This function checks whether a range of tracks is in regular format * with the specified block size. */ -static format_check_t check_track_format(dasdfmt_info_t *info, format_data_t *p) +static format_check_t check_track_format(dasdfmt_info_t *info, char *dev_filename, format_data_t *p) { format_check_t cdata = { .expect = { @@ -812,7 +809,7 @@ static int process_tracks(dasdfmt_info_t step.stop_unit = cur_trk + step_value - 1; if (info->check) { - cdata = check_track_format(info, &step); + cdata = check_track_format(info, dev_filename, &step); if (cdata.result) { cyl = cur_trk / heads + 1; draw_progress(info, cyl, cylinders, 1); @@ -858,7 +855,7 @@ static void check_disk_format(dasdfmt_in return; } - check_blocksize(info, check_params->blksize); + check_blocksize(info, dev_filename, check_params->blksize); check_layout(info, check_params->intensity); /* @@ -1188,7 +1185,7 @@ static void dasdfmt_write_labels(dasdfmt * that the device is formatted to a certain extent. Otherwise the * process is terminated. */ -static void dasdfmt_find_start(dasdfmt_info_t *info, unsigned int cylinders, +static void dasdfmt_find_start(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, unsigned heads, format_data_t *format_params) { format_check_t cdata; @@ -1197,11 +1194,11 @@ static void dasdfmt_find_start(dasdfmt_i unsigned int right = (cylinders * heads) - 1; unsigned int first = left; - check_blocksize(info, format_params->blksize); + check_blocksize(info, dev_filename, format_params->blksize); format_params->start_unit = 0; format_params->stop_unit = 4; - cdata = check_track_format(info, format_params); + cdata = check_track_format(info, dev_filename, format_params); if (cdata.result) { evaluate_format_error(info, &cdata, heads); @@ -1217,7 +1214,7 @@ static void dasdfmt_find_start(dasdfmt_i format_params->start_unit = middle; format_params->stop_unit = middle; - cdata = check_track_format(info, format_params); + cdata = check_track_format(info, dev_filename, format_params); if (cdata.blksize != format_params->blksize) { first = middle; right = middle - 1; @@ -1266,6 +1263,7 @@ static void dasdfmt_release_space(dasdfm } static void dasdfmt_prepare_and_format(dasdfmt_info_t *info, + char *dev_filename, unsigned int cylinders, unsigned int heads, format_data_t *p) { @@ -1324,7 +1322,7 @@ static void dasdfmt_prepare_and_format(d /* * This function will start the expand format process. */ -static void dasdfmt_expand_format(dasdfmt_info_t *info, unsigned int cylinders, +static void dasdfmt_expand_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, unsigned int heads, format_data_t *p) { if (!(info->withoutprompt && (info->verbosity < 1))) @@ -1351,7 +1349,7 @@ static void dasdfmt_expand_format(dasdfm * 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, +static void dasdfmt_quick_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders, unsigned int heads, format_data_t *p) { format_check_t cdata = { .expect = {0}, 0 }; @@ -1363,18 +1361,18 @@ static void dasdfmt_quick_format(dasdfmt } else if (info->ese) { printf("Skipping format check due to thin-provisioned device.\n"); } else { - check_blocksize(info, p->blksize); + check_blocksize(info, dev_filename, 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(info, &tmp); + cdata = check_track_format(info, dev_filename, &tmp); if (!cdata.result) { tmp.start_unit = (cylinders * heads) - 3; tmp.stop_unit = (cylinders * heads) - 1; - cdata = check_track_format(info, &tmp); + cdata = check_track_format(info, dev_filename, &tmp); } if (cdata.result) { evaluate_format_error(info, &cdata, heads); @@ -1419,7 +1417,7 @@ static void do_format_dasd(dasdfmt_info_ p->stop_unit = 1; break; case EXPAND: /* only the end of the disk */ - dasdfmt_find_start(info, cylinders, heads, p); + dasdfmt_find_start(info, devname, cylinders, heads, p); p->stop_unit = (cylinders * heads) - 1; break; } @@ -1468,24 +1466,24 @@ static void do_format_dasd(dasdfmt_info_ switch (mode) { case FULL: - dasdfmt_prepare_and_format(info, cylinders, heads, p); + dasdfmt_prepare_and_format(info, devname, cylinders, heads, p); break; case QUICK: dasdfmt_release_space(info); - dasdfmt_quick_format(info, cylinders, heads, p); + dasdfmt_quick_format(info, devname, cylinders, heads, p); break; case EXPAND: - dasdfmt_expand_format(info, cylinders, heads, p); + dasdfmt_expand_format(info, devname, cylinders, heads, p); break; } printf("Finished formatting the device.\n"); if (!(info->writenolabel || mode == EXPAND)) - dasdfmt_write_labels(info, vlabel, cylinders, heads); + dasdfmt_write_labels(info, devname, vlabel, cylinders, heads); printf("Rereading the partition table... "); - err = dasd_reread_partition_table(dev_filename, 5); + err = dasd_reread_partition_table(devname, 5); if (err != 0) { ERRMSG("%s: error during rereading the partition " "table: %s.\n", prog_name, strerror(err)); @@ -1508,23 +1506,91 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname, mode = info->ese ? QUICK : FULL; } +void do_dasdfmt(char *dev_filename, dasdfmt_info_t info, + volume_label_t *orig_vlabel, format_data_t format_params) +{ + volume_label_t vlabel; + char old_volser[7]; + char str[ERR_LENGTH]; + unsigned int cylinders, heads; int rc; + + filedes = open(dev_filename, O_RDWR); + if (filedes == -1) + ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n", + prog_name, dev_filename, strerror(errno)); + close(filedes); + + rc = dasd_get_info(dev_filename, &info.dasd_info); + if (rc != 0) + ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve " + "device information for %s failed (%s).\n", + prog_name, dev_filename, strerror(rc)); + + info.ese = dasd_sys_ese(dev_filename); + eval_format_mode(&info); + + memcpy(&vlabel, orig_vlabel, sizeof(vlabel)); + /* 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) + || info.check) + get_blocksize(dev_filename, &format_params.blksize); + else + format_params = ask_user_for_blksize(format_params); + } + + if (info.keep_volser) { + if (info.labelspec) { + ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options " + "are mutually exclusive\n", prog_name); + } + if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) { + printf("WARNING: VOLSER cannot be kept " + "when using the ldl format!\n"); + exit(1); + } + + if (dasdfmt_get_volser(dev_filename, + &info.dasd_info, old_volser) == 0) + vtoc_volume_label_set_volser(&vlabel, old_volser); + else + ERRMSG_EXIT(EXIT_FAILURE, + "%s: VOLSER not found on device %s\n", + prog_name, dev_filename); + } + + check_disk(&info, dev_filename); + + if (check_param(str, ERR_LENGTH, &format_params) < 0) + ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); + + set_geo(&info, &cylinders, &heads); + set_label(&info, &vlabel, &format_params, cylinders); + + if (info.check) + check_disk_format(&info, cylinders, heads, &format_params); + else + do_format_dasd(&info, dev_filename, &vlabel, + &format_params, cylinders, heads); + +} + int main(int argc, char *argv[]) { dasdfmt_info_t info = { .dasd_info = {0}, }; volume_label_t vlabel; - char old_volser[7]; - char str[ERR_LENGTH]; + char *dev_filename[MAX_DEVICES]; char buf[7]; char *blksize_param_str = NULL; char *reqsize_param_str = NULL; char *hashstep_str = NULL; - int rc; - unsigned int cylinders, heads; + int rc, numdev = 0, i; /* Establish a handler for interrupt signals. */ signal(SIGTERM, program_interrupt_signal); @@ -1686,59 +1751,21 @@ int main(int argc, char *argv[]) if (info.print_hashmarks) PARSE_PARAM_INTO(info.hashstep, hashstep_str, 10, "hashstep"); - get_device_name(dev_filename, optind, argc, argv); - - rc = dasd_get_info(dev_filename, &info.dasd_info); - if (rc != 0) - ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve " - "device information failed (%s).\n", - prog_name, strerror(rc)); - - info.ese = dasd_sys_ese(dev_filename); - eval_format_mode(&info); - - /* 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) || info.check) - get_blocksize(dev_filename, &format_params.blksize); - else - format_params = ask_user_for_blksize(format_params); - } - - if (info.keep_volser) { - if (info.labelspec) { - ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options " - "are mutually exclusive\n", prog_name); - } - if (!(format_params.intensity & DASD_FMT_INT_COMPAT)) { - printf("WARNING: VOLSER cannot be kept " - "when using the ldl format!\n"); - exit(1); - } - - if (dasdfmt_get_volser(dev_filename, - &info.dasd_info, old_volser) == 0) - vtoc_volume_label_set_volser(&vlabel, old_volser); - else - ERRMSG_EXIT(EXIT_FAILURE, - "%s: VOLSER not found on device %s\n", - prog_name, dev_filename); + while (optind < argc) { + if (optind >= argc) + ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", + prog_name); + + get_device_name(dev_filename, numdev, argv[optind]); + optind++; + numdev++; } - check_disk(&info, dev_filename); - - if (check_param(str, ERR_LENGTH, &format_params) < 0) - ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); - - set_geo(&info, &cylinders, &heads); - set_label(&info, &vlabel, &format_params, cylinders); - - if (info.check) - check_disk_format(&info, cylinders, heads, &format_params); - else - do_format_dasd(&info, dev_filename, &vlabel, - &format_params, cylinders, heads); + if (!numdev) + ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n", + prog_name); + for (i = 0; i < numdev; i++) + do_dasdfmt(dev_filename[i], info, &vlabel, format_params); return 0; } -- 1.7.12.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor