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

Next file: linux/arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c
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.2.16/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>
@@ -31,7 +33,8 @@
 #undef __KERNEL__
 
 #include <linux/fs.h>
-#include <linux/dasd.h>
+#include <asm/dasd.h>
+#include <linux/hdreg.h>
 
 #define EXIT_MISUSE 1
 #define EXIT_BUSY 2
@@ -39,9 +42,11 @@
 #define TEMPFILENAMECHARS 8  /* 8 characters are fixed in all temp filenames */
 #define SLASHDEV "/dev/"
 #define PROC_DASD_DEVICES "/proc/dasd/devices"
-#define PROC_MOUNTS "/proc/mounts"  /* _PATH_MOUNTED is /etc/mtab - maybe bad */
+/* _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
 
@@ -73,19 +78,105 @@
 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);
+#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");
+#endif /* RANGE_FORMATTING */
 	printf("       and <diskspec> is either\n");
 	printf("           -f /dev/dasdX\n");
 	printf("       or\n");
@@ -108,9 +199,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) &&
@@ -255,6 +346,7 @@
 	char *str;
 	char output[60],o2[12];
 
+#ifdef RANGE_FORMATTING
 	i=params.start_unit;
 	do {
 		params.start_unit=i;
@@ -286,6 +378,7 @@
 			ASK_CHECK_PARAM(CHECK_END);
 		}
 	} while (rc!=1);
+#endif /* RANGE_FORMATTING */
 
 	i=params.blksize;
 	do {
@@ -364,12 +457,16 @@
 
 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 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);
@@ -393,6 +490,10 @@
 	}
 	check_mounted(major_no, minor_no);
 	
+	if ((!writenolabel) && (!labelspec)) {
+		sprintf(label,"LNX1 x%04x",devno);
+	}
+	
 	if ( ((withoutprompt)&&(verbosity>=1)) ||
 		(!withoutprompt) ) {
 		get_xno_from_xno(&devno,&major_no,&minor_no,
@@ -402,6 +503,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               : ");
@@ -409,6 +515,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");
@@ -439,6 +546,56 @@
 				"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,BLKGETBSZ,&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) {
@@ -461,11 +618,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;
 
@@ -474,7 +633,7 @@
 	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;
@@ -492,6 +651,11 @@
 	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;
 
@@ -500,7 +664,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;
@@ -525,6 +692,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++;
@@ -535,6 +714,12 @@
 			end_specified++;
 			break;
 
+		case 'r' :
+			range_param_str=optarg;
+			range_specified++;
+			break;
+#endif /* RANGE_FORMATTING */
+
 		case 'b' :
 			blksize_param_str=optarg;
 			blksize_specified++;
@@ -549,10 +734,6 @@
 			dev_filename=optarg;
 			devfile_specified++;
 			break;
-		case 'r' :
-			range_param_str=optarg;
-			range_specified++;
-			break;
 		}
 	}
 
@@ -604,6 +785,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");
@@ -628,7 +811,7 @@
 
 	/******* issue the real command and reread part table *******/
 	do_format_dasd(dev_name,format_params,testmode,verbosity,
-		withoutprompt);
+		writenolabel,labelspec,label,withoutprompt);
 
 	/*************** 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)