patch-2.4.2 linux/arch/s390/tools/dasdfmt/dasdfmt.c

Next file: linux/arch/s390/tools/silo/Makefile
Previous file: linux/arch/s390/tools/dasdfmt/dasdfmt.8
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.1/linux/arch/s390/tools/dasdfmt/dasdfmt.c linux/arch/s390/tools/dasdfmt/dasdfmt.c
@@ -12,6 +12,8 @@
  *   detect non-switch parameters ("dasdfmt -n 170 XY") and complain about them 
  */
 
+/* #define _LINUX_BLKDEV_H */
+
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -25,19 +27,25 @@
 #include <string.h>
 #include <dirent.h>
 #include <mntent.h>
-#include "../../../drivers/s390/block/dasd.h" /* uses DASD_PARTN_BITS */
 #define __KERNEL__ /* we want to use kdev_t and not have to define it */
 #include <linux/kdev_t.h>
 #undef __KERNEL__
 
+#include <linux/fs.h>
+#include <asm/dasd.h>
+#include <linux/hdreg.h>
+
 #define EXIT_MISUSE 1
 #define EXIT_BUSY 2
 #define TEMPFILENAME "/tmp/ddfXXXXXX"
 #define TEMPFILENAMECHARS 8  /* 8 characters are fixed in all temp filenames */
-#define IOCTL_COMMAND 'D' << 8
 #define SLASHDEV "/dev/"
 #define PROC_DASD_DEVICES "/proc/dasd/devices"
+/* _PATH_MOUNTED is /etc/mtab - /proc/mounts does not show root-fs correctly */
+#define PROC_MOUNTS _PATH_MOUNTED
+#define PROC_SWAPS "/proc/swaps"
 #define DASD_DRIVER_NAME "dasd"
+#define LABEL_LENGTH 10
 #define PROC_LINE_LENGTH 80
 #define ERR_LENGTH 80
 
@@ -66,24 +74,108 @@
 		ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \
 			"is in invalid format\n",prog_name);}
 
-typedef struct {
-	int start_unit;
-	int stop_unit;
-	int blksize;
-} format_data_t;
-
-char prog_name[]="dasd_format";
+char *prog_name;/*="dasdfmt";*/
 char tempfilename[]=TEMPFILENAME;
 
+__u8 _ascebc[256] =
+{
+ /*00 NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL */
+     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08  BS    HT    LF    VT    FF    CR    SO    SI */
+ /*              ->NL                               */
+     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB */
+     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CAN    EM   SUB   ESC    FS    GS    RS    US */
+ /*                               ->IGS ->IRS ->IUS */
+     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ /*20  SP     !     "     #     $     %     &     ' */
+     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28   (     )     *     +     ,     -    .      / */
+     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30   0     1     2     3     4     5     6     7 */
+     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38   8     9     :     ;     <     =     >     ? */
+     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40   @     A     B     C     D     E     F     G */
+     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48   H     I     J     K     L     M     N     O */
+     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50   P     Q     R     S     T     U     V     W */
+     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58   X     Y     Z     [     \     ]     ^     _ */
+     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ /*60   `     a     b     c     d     e     f     g */
+     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68   h     i     j     k     l     m     n     o */
+     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70   p     q     r     s     t     u     v     w */
+     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78   x     y     z     {     |     }     ~    DL */
+     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ /*80*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*88*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*90*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*98*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E0        sz						*/
+     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F8*/
+     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+void convert_label(char *str)
+{
+	int i;
+	for (i=0;i<LABEL_LENGTH;i++) str[i]=_ascebc[str[i]];
+}
+
 void
 exit_usage(int exitcode)
 {
-	printf("Usage: %s [-htvyV] [-b blocksize] <range> <diskspec>\n\n",
-	       prog_name);
-	printf("       where <range> is either\n");
-	printf("           -s start_track -e end_track\n");
+#ifdef RANGE_FORMATTING
+	printf("Usage: %s [-htvyLV] [-l <label>] [-b <blocksize>] [<range>] " \
+		"<diskspec>\n\n",prog_name);
+#else /* RANGE_FORMATTING */
+	printf("Usage: %s [-htvyLV] [-l <label>] [-b <blocksize>] " \
+		"<diskspec>\n\n",prog_name);
+#endif /* RANGE_FORMATTING */
+	printf("       -t means testmode\n");
+	printf("       -v means verbose mode\n");
+	printf("       -V means print version\n");
+	printf("       -L means don't write disk label\n");
+	printf("       <label> is a label which is converted to EBCDIC and " \
+		"written to disk\n");
+	printf("       <blocksize> has to be power of 2 and at least 512\n");
+#ifdef RANGE_FORMATTING
+	printf("       <range> is either\n");
+	printf("           -s <start_track> -e <end_track>\n");
 	printf("       or\n");
-	printf("           -r start_track-end_track\n");
+	printf("           -r <start_track>-<end_track>\n");
+#endif /* RANGE_FORMATTING */
 	printf("       and <diskspec> is either\n");
 	printf("           -f /dev/dasdX\n");
 	printf("       or\n");
@@ -106,9 +198,9 @@
 			PROC_DASD_DEVICES ": %s (do you have the /proc " \
 			"filesystem enabled?)\n",prog_name,strerror(errno));
 
-	fgets(line,sizeof(line),file); /* omit first line */
+	/*	fgets(line,sizeof(line),file); omit first line */ 
 	while (fgets(line,sizeof(line),file)!=NULL) {
-		rc=sscanf(line,"%X%d%d",&d,&ma_i,&mi_i);
+		rc=sscanf(line,"%X %*[(A-Z)] at (%d:%d)",&d,&ma_i,&mi_i);
 		ma=ma_i;
 		mi=mi_i;
 		if ( (rc==3) &&
@@ -253,6 +345,7 @@
 	char *str;
 	char output[60],o2[12];
 
+#ifdef RANGE_FORMATTING
 	i=params.start_unit;
 	do {
 		params.start_unit=i;
@@ -284,6 +377,7 @@
 			ASK_CHECK_PARAM(CHECK_END);
 		}
 	} while (rc!=1);
+#endif /* RANGE_FORMATTING */
 
 	i=params.blksize;
 	do {
@@ -320,8 +414,8 @@
 	/*
 	 * first, check filesystems
 	 */
-	if (!(f = fopen(_PATH_MOUNTED, "r")))
-		ERRMSG_EXIT(EXIT_FAILURE, "%s: %s\n", _PATH_MOUNTED,
+	if (!(f = fopen(PROC_MOUNTS, "r")))
+		ERRMSG_EXIT(EXIT_FAILURE, "%s: %s\n", PROC_MOUNTS,
 			strerror(errno));
 	while ((ment = getmntent(f))) {
 		if (stat(ment->mnt_fsname, &stbuf) == 0)
@@ -337,8 +431,8 @@
 	/*
 	 * second, check active swap spaces
 	 */
-	if (!(f = fopen("/proc/swaps", "r")))
-		ERRMSG_EXIT(EXIT_FAILURE, "/proc/swaps: %s", strerror(errno));
+	if (!(f = fopen(PROC_SWAPS, "r")))
+		ERRMSG_EXIT(EXIT_FAILURE, PROC_SWAPS " %s", strerror(errno));
 	/*
 	 * skip header line
 	 */
@@ -362,12 +456,15 @@
 
 void
 do_format_dasd(char *dev_name,format_data_t format_params,int testmode,
-	int verbosity,int withoutprompt)
+	int verbosity,int writenolabel,int labelspec,
+	char *label,int withoutprompt,int devno)
 {
 	int fd,rc;
 	struct stat stat_buf;
 	kdev_t minor_no,major_no;
-	int devno;
+	int new_blksize;
+	unsigned int label_position;
+	struct hd_geometry new_geometry;
 	char inp_buffer[5]; /* to contain yes */
 
 	fd=open(dev_name,O_RDWR);
@@ -390,6 +487,10 @@
 		minor_no=MINOR(stat_buf.st_rdev);
 	}
 	check_mounted(major_no, minor_no);
+
+	if ((!writenolabel) && (!labelspec)) {
+		sprintf(label,"LNX1 x%04x",devno);
+	}
 	
 	if ( ((withoutprompt)&&(verbosity>=1)) ||
 		(!withoutprompt) ) {
@@ -400,6 +501,11 @@
 		printf("   Device number of device : 0x%x\n",devno);
 		printf("   Major number of device  : %u\n",major_no);
 		printf("   Minor number of device  : %u\n",minor_no);
+		printf("   Labelling device        : %s\n",(writenolabel)?
+			"no":"yes");
+		if (!writenolabel)
+			printf("   Disk label              : %s\n",label);
+#ifdef RANGE_FORMATTING
 		printf("   Start track             : %d\n" \
 			,format_params.start_unit);
 		printf("   End track               : ");
@@ -407,6 +513,7 @@
 			printf("last track of disk\n");
 		else
 			printf("%d\n",format_params.stop_unit);
+#endif /* RANGE_FORMATTING */
 		printf("   Blocksize               : %d\n" \
 			,format_params.blksize);
 		if (testmode) printf("Test mode active, omitting ioctl.\n");
@@ -416,8 +523,8 @@
 		if (!withoutprompt) {
 			printf("\n--->> ATTENTION! <<---\n");
 			printf("All data in the specified range of that " \
-				"device will be lost.\nType yes to continue" \
-				", no will leave the disk untouched: ");
+				"device will be lost.\nType \"yes\" to " \
+				"continue, no will leave the disk untouched: ");
 			fgets(inp_buffer,sizeof(inp_buffer),stdin);
 			if (strcasecmp(inp_buffer,"yes") &&
 				strcasecmp(inp_buffer,"yes\n")) {
@@ -430,13 +537,70 @@
 		if ( !(  (withoutprompt)&&(verbosity<1) ))
 			printf("Formatting the device. This may take a " \
 				"while (get yourself a coffee).\n");
-		rc=ioctl(fd,IOCTL_COMMAND,format_params);
+		rc=ioctl(fd,BIODASDFORMAT,format_params);
 		if (rc)
 			ERRMSG_EXIT(EXIT_FAILURE,"%s: the dasd driver " \
 				"returned with the following error " \
 				"message:\n%s\n",prog_name,strerror(errno));
 		printf("Finished formatting the device.\n");
 
+		if (!writenolabel) {
+			if (verbosity>0)
+				printf("Retrieving disk geometry... ");
+
+			rc=ioctl(fd,HDIO_GETGEO,&new_geometry);
+			if (rc) {
+				ERRMSG("%s: the ioctl call to get geometry " \
+					"returned with the following error " \
+					"message:\n%s\n",prog_name,
+					strerror(errno));
+				goto reread;
+			}
+	
+
+			rc=ioctl(fd,BLKGETSIZE,&new_blksize);
+			if (rc) {
+				ERRMSG("%s: the ioctl call to get blocksize " \
+					"returned with the following error " \
+					"message:\n%s\n",prog_name,
+					strerror(errno));
+				goto reread;
+			}
+	
+			if (verbosity>0) printf("done\n");
+
+			label_position=new_geometry.start*new_blksize;
+	
+			if (verbosity>0) printf("Writing label... ");
+			convert_label(label);
+			rc=lseek(fd,label_position,SEEK_SET);
+			if (rc!=label_position) {
+				ERRMSG("%s: lseek on the device to %i " \
+					"failed with the following error " \
+					"message:\n%s\n",prog_name,
+					label_position,strerror(errno));
+				goto reread;
+			}
+			rc=write(fd,label,LABEL_LENGTH);
+			if (rc!=LABEL_LENGTH) {
+				ERRMSG("%s: writing the label only wrote %d " \
+					"bytes.\n",prog_name,rc);
+				goto reread;
+			}
+
+			sync();
+			sync();
+
+			if (verbosity>0) printf("done\n");
+		}
+ reread:
+		printf("Rereading the partition table... ");
+		rc=ioctl(fd,BLKRRPART,NULL);
+		if (rc) {
+			ERRMSG("%s: error during rereading the partition " \
+			       "table: %s.\n",prog_name,strerror(errno));
+		} else printf("done.\n");
+
 		break;
 	}
 
@@ -452,11 +616,13 @@
 	int verbosity;
 	int testmode;
 	int withoutprompt;
+	int writenolabel,labelspec;
 
 	char *dev_name;
 	int devno;
 	char *dev_filename,*devno_param_str,*range_param_str;
 	char *start_param_str,*end_param_str,*blksize_param_str;
+	char label[LABEL_LENGTH+1];
 	
 	format_data_t format_params;
 
@@ -465,23 +631,30 @@
 	char *endptr;
 
 	char c1,c2,cbuffer[6]; /* should be able to contain -end plus 1 char */
-	int i1,i2;
+	int i,i1,i2;
 	char *str;
 
 	int start_specified,end_specified,blksize_specified;
 	int devfile_specified,devno_specified,range_specified;
 
 	/******************* initialization ********************/
+	prog_name=argv[0];
 
 	endptr=NULL;
 
 	/* set default values */
-	format_params.start_unit=0;
-	format_params.stop_unit=-1;
-	format_params.blksize=4096;
+	format_params.start_unit=DASD_FORMAT_DEFAULT_START_UNIT;
+	format_params.stop_unit=DASD_FORMAT_DEFAULT_STOP_UNIT;
+	format_params.blksize=DASD_FORMAT_DEFAULT_BLOCKSIZE;
+	format_params.intensity=DASD_FORMAT_DEFAULT_INTENSITY;
 	testmode=0;
 	verbosity=0;
 	withoutprompt=0;
+	writenolabel=0;
+	labelspec=0;
+	for (i=0;i<LABEL_LENGTH;i++) label[i]=' ';
+	label[LABEL_LENGTH]=0;
+
 	start_specified=end_specified=blksize_specified=0;
 	devfile_specified=devno_specified=range_specified=0;
 
@@ -490,7 +663,10 @@
 	/* avoid error message generated by getopt */
 	opterr=0;
 
-	while ( (oc=getopt(argc,argv,"r:s:e:b:n:f:hty?vV")) !=EOF) {
+#ifdef RANGE_FORMATTING
+	while ( (oc=getopt(argc,argv,"r:s:e:b:n:l:f:hLty?vV")) !=EOF) {
+#endif /* RANGE_FORMATTING */
+	while ( (oc=getopt(argc,argv,"b:n:l:f:hLty?vV")) !=EOF) {
 		switch (oc) {
 		case 'y':
 			withoutprompt=1;
@@ -515,6 +691,18 @@
 			printf("%s version 0.99\n",prog_name);
 			exit(0);
 
+		case 'l':
+			strncpy(label,optarg,LABEL_LENGTH);
+			if (strlen(optarg)<LABEL_LENGTH)
+				label[strlen(optarg)]=' ';
+			labelspec++;
+			break;
+
+		case 'L':
+			writenolabel++;
+			break;
+
+#ifdef RANGE_FORMATTING
 		case 's' :
 			start_param_str=optarg;
 			start_specified++;
@@ -525,6 +713,12 @@
 			end_specified++;
 			break;
 
+		case 'r' :
+			range_param_str=optarg;
+			range_specified++;
+			break;
+#endif /* RANGE_FORMATTING */
+
 		case 'b' :
 			blksize_param_str=optarg;
 			blksize_specified++;
@@ -539,10 +733,6 @@
 			dev_filename=optarg;
 			devfile_specified++;
 			break;
-		case 'r' :
-			range_param_str=optarg;
-			range_specified++;
-			break;
 		}
 	}
 
@@ -594,6 +784,8 @@
 	CHECK_SPEC_MAX_ONCE(start_specified,"start track");
 	CHECK_SPEC_MAX_ONCE(end_specified,"end track");
 	CHECK_SPEC_MAX_ONCE(blksize_specified,"blocksize");
+	CHECK_SPEC_MAX_ONCE(labelspec,"label");
+	CHECK_SPEC_MAX_ONCE(writenolabel,"omit-label-writing flag");
 
 	if (devno_specified)
 		PARSE_PARAM_INTO(devno,devno_param_str,16,"device number");
@@ -616,9 +808,9 @@
 	str=check_param(CHECK_ALL,format_params);
 	if (str!=NULL) ERRMSG_EXIT(EXIT_MISUSE,"%s: %s\n",prog_name,str);
 
-	/*************** issue the real command *****************/
+	/******* issue the real command and reread part table *******/
 	do_format_dasd(dev_name,format_params,testmode,verbosity,
-		withoutprompt);
+		writenolabel,labelspec,label,withoutprompt,devno);
 
 	/*************** cleanup ********************************/
 	if (strncmp(dev_name,TEMPFILENAME,TEMPFILENAMECHARS)==0) {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)