SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-sles12-pardasdfmt.patch
2017-02-21 11:14:26 +00:00

527 lines
16 KiB
Diff

--- s390-tools-1.34.0/dasdfmt/dasdfmt.8 2016-04-14 16:43:51.000000000 -0400
+++ s390-tools-1.34.0/dasdfmt/dasdfmt.8 2016-04-14 16:35:01.000000000 -0400
@@ -3,11 +3,11 @@
dasdfmt \- formatting of DASD (ECKD) disk drives.
.SH SYNOPSIS
-\fBdasdfmt\fR [-h] [-t] [-v] [-y] [-p] [-P] [-m \fIstep\fR]
+\fBdasdfmt\fR [-h] [-t] [-v] [-y] [-p] [-Q] [-m \fIstep\fR]
.br
- [-r \fIcylinder\fR] [-b \fIblksize\fR] [-l \fIvolser\fR] [-d \fIlayout\fR]
+ [-r \fIcylinder\fR] [-b \fIblksize\fR] [-l \fIvolser\fR] [-d \fIlayout\fR] [-P maxpar]
.br
- [-L] [-V] [-F] [-k] [-C] \fIdevice\fR
+ [-L] [-V] [-F] [-k] [-C] \fIdevice\fR ...
.SH DESCRIPTION
\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it
@@ -91,7 +91,7 @@
running in background or redirecting the output to a file.
.TP
-\fB-P\fR or \fB--percentage\fR
+\fB-Q\fR or \fB--percentage\fR
Print one line for each formatted cylinder showing the number of the
cylinder and percentage of formatting process.
Intended to be used by higher level interfaces.
@@ -123,6 +123,20 @@
and always be a power of two. The recommended blocksize is 4096 bytes.
.TP
+\fB-P\fR \fInumdisks\fR or \fB--max_parallel\fR=\fInumdisks\fR
+Specify the number of disks to be formatted in
+parallel. \FInumdisks\fR specifies the number of formatting processes
+which is independent of the overall number of disks to be formatted as
+specified on the commandline. The maximum value for \fInumdisks\fR is
+1024. Default is 1.
+.br
+Using this option can
+decrease overall processing time when formatting several disks.
+Please note that the I/O throughput will dramatically increase when
+using this option. Use with care.
+.br
+
+.TP
\fB-l\fR \fIvolser\fR or \fB--label\fR=\fIvolser\fR
Specify the volume serial number or volume identifier to be written
to disk after formatting. If no label is specified, a sensible default
--- s390-tools-1.34.0/dasdfmt/dasdfmt.h 2016-04-14 16:43:51.000000000 -0400
+++ s390-tools-1.34.0/dasdfmt/dasdfmt.h 2016-04-14 16:35:01.000000000 -0400
@@ -195,6 +195,7 @@
#define LABEL_LENGTH 14
#define VLABEL_CHARS 84
#define LINE_LENGTH 80
+#define MAX_DEVICES 1024
#define ERR_LENGTH 90
#define DEFAULT_BLOCKSIZE 4096
@@ -214,7 +215,7 @@
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:hpPLtyvVFkC"
+#define dasdfmt_getopt_string "b:n:l:f:d:m:r:hpQLtyvVFkCYP:"
static struct option dasdfmt_getopt_long_options[]=
{
@@ -225,12 +226,14 @@
{ "force", 0, 0, 'F'},
{ "progressbar", 0, 0, 'p'},
{ "hashmarks", 1, 0, 'm'},
- { "percentage", 0, 0, 'P'},
+ { "percentage", 0, 0, 'Q'},
{ "label", 1, 0, 'l'},
{ "device", 1, 0, 'f'},
{ "blocksize", 1, 0, 'b'},
{ "requestsize", 1, 0, 'r'},
{ "help", 0, 0, 'h'},
+ { "max_parallel",1, 0, 'P'},
+ { "yast_mode", 0, 0, 'Y'},
{ "keep_volser", 0, 0, 'k'},
{ "norecordzero", 0, 0, 'z'},
{ "check_host_count", 0, 0, 'C'},
@@ -267,6 +270,8 @@
int device_id;
int keep_volser;
int force_host;
+ int yast_mode;
+ int procnum;
} dasdfmt_info_t;
--- s390-tools-1.34.0/dasdfmt/dasdfmt.c 2016-04-14 16:43:51.000000000 -0400
+++ s390-tools-1.34.0/dasdfmt/dasdfmt.c 2016-04-14 16:35:01.000000000 -0400
@@ -17,6 +17,7 @@
#include "vtoc.h"
#include "util_proc.h"
#include "dasd_sys.h"
+#include <sys/wait.h>
#define BUSIDSIZE 8
@@ -48,7 +49,7 @@
*/
static void exit_usage(int exitcode)
{
- printf("Usage: %s [-htvypPLVFkC]\n"
+ printf("Usage: %s [-htvypQLVFkC]\n"
" [-l <volser> | --label=<volser>]\n"
" [-b <blocksize> | --blocksize=<blocksize>]\n"
" [-d <disk layout> | --disk_layout=<disk layout>]\n"
@@ -59,7 +60,7 @@
" -V or --version means print version\n"
" -L or --no_label means don't write disk label\n"
" -p or --progressbar means show a progress bar\n"
- " -P or --percentage means show a progress in percent\n"
+ " -Q or --percentage means show a progress in percent\n"
" -m x or --hashmarks=x means show a hashmark every x "
"cylinders\n"
" -r x or --requestsize=x means use x cylinders in one "
@@ -143,22 +144,33 @@
/*
* check given device name for blanks and some special characters
*/
-static void get_device_name(dasdfmt_info_t *info, char *name, int argc, char * argv[])
+static char* getdev(char* sysfs_path)
{
- struct util_proc_dev_entry dev_entry;
- struct stat dev_stat;
-
- if (info->node_specified && (info->device_id < argc))
- ERRMSG_EXIT(EXIT_MISUSE,"%s: Device can only specified once!\n",
- prog_name);
+ DIR* d;
+ struct dirent* de;
+
+ d = opendir(sysfs_path);
+ if(!d) ERRMSG_EXIT(EXIT_FAILURE,"%s: Could not open directory %s.\n",prog_name,sysfs_path);
+ while((de = readdir(d)))
+ {
+ if(strncmp(de->d_name,"block:",6) == 0)
+ {
+ closedir(d);
+ return de->d_name+6;
+ }
+ }
+ return 0;
+}
- if (!info->node_specified && (info->device_id >= argc))
- ERRMSG_EXIT(EXIT_MISUSE,"%s: No device specified!\n",
- prog_name);
+static void get_device_name(dasdfmt_info_t *info, char *name)
+{
+ struct util_proc_dev_entry dev_entry;
+ struct stat dev_stat;
+ char buf[PATH_MAX];
+ char devno[9];
+ char* device;
+ int i;
- if (info->device_id < argc) {
- strcpy(info->devname, argv[info->device_id]);
- } else {
if ((strchr(name, ' ') != NULL)||(strchr(name, '#') != NULL)||
(strchr(name, '[') != NULL)||(strchr(name, ']') != NULL)||
(strchr(name, '!') != NULL)||(strchr(name, '>') != NULL)||
@@ -169,9 +181,38 @@
"blanks or special characters!\n",
prog_name);
- strncpy(info->devname, name, PATH_MAX - 1);
+ if (isxdigit(name[0]) && name[1] == '.' && isxdigit(name[2]) && name[3] == '.' && strlen(name) == 8)
+ { /* x.x.xxxx format */
+ for(i=0; i<8; i++)
+ devno[i] = tolower(name[i]);
+ devno[8] = 0;
+ sprintf(buf,"/sys/bus/ccw/devices/%s",devno);
+ device = getdev(buf);
+ if(device)
+ {
+ strcpy(info->devname,"/dev/");
+ strcat(info->devname,device);
+ }
+ else ERRMSG_EXIT(EXIT_FAILURE,"%s: Could not find device file for device no. %s\n",prog_name,name);
+ }
+ else if (isxdigit(name[0]) && isxdigit(name[1]) && isxdigit(name[2]) && isxdigit(name[3]))
+ { /* xxxx format */
+ for(i=0; i<4; i++)
+ devno[i] = tolower(name[i]);
+ devno[4] = 0;
+ sprintf(buf,"/sys/bus/ccw/devices/0.0.%s",devno);
+ device = getdev(buf);
+ if(device)
+ {
+ strcpy(info->devname,"/dev/");
+ strcat(info->devname,device);
+ }
+ else ERRMSG_EXIT(EXIT_FAILURE,"%s: Could not find device file for device no. %s\n",prog_name,name);
+ }
+ else
+ strncpy(info->devname, name, PATH_MAX - 1);
+
info->devname[PATH_MAX - 1] = '\0';
- }
if (stat(info->devname, &dev_stat) != 0)
ERRMSG_EXIT(EXIT_MISUSE,
@@ -217,8 +258,9 @@
info->reqsize_specified = 0;
info->node_specified = 0;
info->device_id = 0;
- info->keep_volser = 0;
+ info->keep_volser = 0;
info->force_host = 0;
+ info->yast_mode = 0;
}
@@ -271,7 +313,6 @@
}
-
/*
* check the volume serial for special
* characters and move blanks to the end
@@ -640,7 +681,7 @@
info->hashstep = 10;
}
- printf("Printing hashmark every %d cylinders.\n",
+ if(!info->yast_mode) printf("Printing hashmark every %d cylinders.\n",
info->hashstep);
}
@@ -649,7 +690,7 @@
k = 0;
cyl = 1;
- if (info->print_progressbar || info->print_hashmarks)
+ if ((info->print_progressbar || info->print_hashmarks) && !info->yast_mode)
printf("\n");
while (1) {
@@ -688,7 +729,7 @@
if (info->print_hashmarks)
if ((cyl / info->hashstep - hashcount) != 0) {
- printf("#");
+ printf("%d|",info->procnum);
fflush(stdout);
hashcount++;
}
@@ -709,7 +750,7 @@
break;
}
- if (info->print_progressbar || info->print_hashmarks)
+ if ((info->print_progressbar || info->print_hashmarks) && !info->yast_mode)
printf("\n\n");
}
@@ -884,17 +925,21 @@
dasdfmt_prepare_and_format(info, cylinders, heads, p);
- printf("Finished formatting the device.\n");
+ if (!info->yast_mode)
+ printf("Finished formatting the device.\n");
if (!info->writenolabel)
dasdfmt_write_labels(info, vlabel, cylinders, heads);
- printf("Rereading the partition table... ");
+ if (!info->yast_mode)
+ printf("Rereading the partition table... ");
if (reread_partition_table()) {
ERRMSG("%s: error during rereading the partition "
"table: %s.\n", prog_name, strerror(errno));
- } else
- printf("ok\n");
+ } else {
+ if (!info->yast_mode)
+ printf("ok\n");
+ }
}
}
@@ -905,7 +950,8 @@
volume_label_t vlabel;
char old_volser[7];
- char dev_filename[PATH_MAX];
+ char* dev_filename[MAX_DEVICES];
+ int dev_count=0;
char str[ERR_LENGTH];
char buf[7];
@@ -913,7 +959,10 @@
char *reqsize_param_str = NULL;
char *hashstep_str = NULL;
- int rc, index;
+ int rc, index, i;
+
+ int max_parallel=1;
+ int running=0;
/* Establish a handler for interrupt signals. */
signal (SIGTERM, program_interrupt_signal);
@@ -990,7 +1039,7 @@
}
break;
- case 'P':
+ case 'Q':
if (!(info.print_hashmarks || info.print_progressbar))
info.print_percentage = 1;
break;
@@ -1034,9 +1083,18 @@
info.reqsize_specified = 1;
break;
case 'f' :
- strncpy(dev_filename, optarg, PATH_MAX);
+ if(dev_count>=MAX_DEVICES)
+ ERRMSG_EXIT(EXIT_MISUSE,"%s: too many devices specified.\n",
+ prog_name);
+ dev_filename[dev_count++]=strdup(optarg);
info.node_specified=1;
break;
+ case 'Y' : /* YaST mode */
+ info.yast_mode=1;
+ break;
+ case 'P' : /* max parallel formatting processes */
+ max_parallel=atoi(optarg);
+ break;
case 'k' :
info.keep_volser=1;
break;
@@ -1059,58 +1117,147 @@
CHECK_SPEC_MAX_ONCE(info.labelspec, "label");
CHECK_SPEC_MAX_ONCE(info.writenolabel, "omit-label-writing flag");
- if (info.blksize_specified)
- PARSE_PARAM_INTO(format_params.blksize,blksize_param_str,10,
- "blocksize");
- if (info.reqsize_specified) {
- PARSE_PARAM_INTO(reqsize, reqsize_param_str, 10, "requestsize");
- if (reqsize < 1 || reqsize > 255)
- ERRMSG_EXIT(EXIT_FAILURE,
- "invalid requestsize %d specified\n",
- reqsize);
- } else
- reqsize = DEFAULT_REQUESTSIZE;
- if (info.print_hashmarks)
- PARSE_PARAM_INTO(info.hashstep, hashstep_str,10,"hashstep");
-
- get_device_name(&info, dev_filename, argc, argv);
+ while(info.device_id < argc) { /* devices specified at the end of cmdline */
+ if(dev_count>=MAX_DEVICES)
+ ERRMSG_EXIT(EXIT_MISUSE,"%s: too many devices specified.\n",
+ prog_name);
+ dev_filename[dev_count++]=strdup(argv[info.device_id]);
+ info.node_specified=1;
+ info.device_id++;
+ }
- if (!info.blksize_specified)
- format_params = ask_user_for_blksize(format_params);
+ if (info.node_specified == 0)
+ ERRMSG_EXIT(EXIT_MISUSE,"%s: No device specified!\n",
+ prog_name);
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 (info.labelspec && max_parallel > 1) {
+ ERRMSG_EXIT(EXIT_MISUSE,"%s: The -l option cannot be used with parallel formatting\n",
+ prog_name);
+ }
+
+ if(info.yast_mode) {
+ for(i=0;i<dev_count;i++) {
+ dasd_information_t dasd_info;
+ struct dasd_eckd_characteristics *characteristics;
+ unsigned int cylinders;
+
+ get_device_name(&info, dev_filename[i]);
+ if ((filedes = open(info.devname, O_RDWR)) == -1) {
+ ERRMSG("%s: Unable to open device %s: %s\n",
+ prog_name, info.devname, strerror(errno));
+ free(dev_filename[i]);
+ dev_filename[i]=(char*)-1; /* ignore device */
+ continue;
+ }
+ if (ioctl(filedes, BIODASDINFO, &dasd_info) != 0) {
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: (retrieving disk information) "
+ "IOCTL BIODASDINFO failed (%s).\n",
+ prog_name, strerror(errno));
+ free(dev_filename[i]);
+ dev_filename[i]=(char*)-1; /* ignore device */
+ close(filedes);
+ continue;
+ }
+
+ characteristics =
+ (struct dasd_eckd_characteristics *) &dasd_info.characteristics;
+ if (characteristics->no_cyl == LV_COMPAT_CYL &&
+ characteristics->long_no_cyl)
+ cylinders = characteristics->long_no_cyl;
+ else
+ cylinders = characteristics->no_cyl;
+
+ printf("%d\n", cylinders);
+ close(filedes);
}
-
- if(dasdfmt_get_volser(info.devname, 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, info.devname);
-
+ fflush(stdout);
}
- if ((filedes = open(info.devname, O_RDWR)) == -1)
- ERRMSG_EXIT(EXIT_FAILURE,"%s: Unable to open device %s: %s\n",
- prog_name, info.devname, strerror(errno));
+ /* fork one formatting process for each device */
+ rc = 0;
+ for(i=0;i<dev_count;i++) {
+ int chpid; /* child process ID */
+ int tmp;
- check_disk(&info);
+ if(dev_filename[i]==(char*)-1) continue; /* ignore device */
- if (check_param(str, ERR_LENGTH, &format_params) < 0)
- ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
+ chpid=fork();
+ if(chpid==-1)
+ ERRMSG_EXIT(EXIT_FAILURE,"%s: Unable to create child process: %s\n",
+ prog_name, strerror(errno));
- do_format_dasd(&info, &format_params, &vlabel);
+ if(!chpid) {
+ info.procnum=i;
+ if (info.blksize_specified)
+ PARSE_PARAM_INTO(format_params.blksize,blksize_param_str,10,
+ "blocksize");
+ if (info.reqsize_specified) {
+ PARSE_PARAM_INTO(reqsize, reqsize_param_str, 10, "requestsize");
+ if (reqsize < 1 || reqsize > 255)
+ ERRMSG_EXIT(EXIT_FAILURE,
+ "invalid requestsize %d specified\n",
+ reqsize);
+ } else
+ reqsize = DEFAULT_REQUESTSIZE;
+ if (info.print_hashmarks)
+ PARSE_PARAM_INTO(info.hashstep, hashstep_str,10,"hashstep");
+
+ get_device_name(&info, dev_filename[i]);
+
+ if (!info.blksize_specified)
+ format_params = ask_user_for_blksize(format_params);
+
+ if (info.keep_volser) {
+ if(format_params.intensity == 0x00) {
+ printf("WARNING: VOLSER cannot be kept " \
+ "when using the ldl format!\n");
+ exit(1);
+ }
- if (close(filedes) != 0)
- ERRMSG("%s: error during close: %s\ncontinuing...\n",
- prog_name, strerror(errno));
+ if(dasdfmt_get_volser(info.devname, 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, info.devname);
- return 0;
+ }
+
+ if ((filedes = open(info.devname, O_RDWR)) == -1)
+ ERRMSG_EXIT(EXIT_FAILURE,"%s: Unable to open device %s: %s\n",
+ prog_name, info.devname, strerror(errno));
+
+ check_disk(&info);
+
+ if (check_param(str, ERR_LENGTH, &format_params) < 0)
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
+
+ do_format_dasd(&info, &format_params, &vlabel);
+
+ if (close(filedes) != 0)
+ ERRMSG("%s: error during close: %s\ncontinuing...\n",
+ prog_name, strerror(errno));
+
+ exit(0);
+ } else {
+ running++;
+ if(running>=max_parallel) {
+ if(wait(&tmp) > 0 && WEXITSTATUS(tmp))
+ rc = WEXITSTATUS(tmp);
+ running--;
+ }
+ }
+ }
+
+ /* wait until all formatting children have finished */
+ while(wait(&i) > 0)
+ if (WEXITSTATUS(i)) rc = WEXITSTATUS(i);
+
+ return rc;
}