xref: /csrg-svn/sys/i386/stand/disklabel.c (revision 41074)
1*41074Swilliam /*-
2*41074Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41074Swilliam  * All rights reserved.
4*41074Swilliam  *
5*41074Swilliam  * This code is derived from software contributed to Berkeley by
6*41074Swilliam  * William Jolitz.
7*41074Swilliam  *
8*41074Swilliam  * %sccs.include.noredist.c%
9*41074Swilliam  *
10*41074Swilliam  *	@(#)disklabel.c	7.1 (Berkeley) 04/24/90
11*41074Swilliam  */
12*41074Swilliam 
13*41074Swilliam #ifndef	STANDALONE
14*41074Swilliam #include <stdio.h>
15*41074Swilliam #else
16*41074Swilliam #define	stderr	0
17*41074Swilliam #define	NULL	0
18*41074Swilliam #endif
19*41074Swilliam #include <disktab.h>
20*41074Swilliam #include <sys/types.h>
21*41074Swilliam #include <sys/ioctl.h>
22*41074Swilliam #include "disk.h"
23*41074Swilliam 
24*41074Swilliam #define	BOOTSIZE	(8*1024)		/* size of boot "block" */
25*41074Swilliam 
26*41074Swilliam #define O_RDONLY	0
27*41074Swilliam #define O_WRONLY	1
28*41074Swilliam #define O_RDWR		2
29*41074Swilliam #define L_SET		0
30*41074Swilliam 
31*41074Swilliam #ifdef	STANDALONE
32*41074Swilliam #ifdef	TP
33*41074Swilliam char	*standdisk = "cst2d:" ;
34*41074Swilliam char	*st506boot = "cst2e:";		/* ST506 boot block */
35*41074Swilliam char	*scsiboot = "cst2f:";		/* SCSI boot block */
36*41074Swilliam #else
37*41074Swilliam char	*standdisk = "/etc/disktab" ;
38*41074Swilliam char	*st506boot = "/stand/bootwd";		/* ST506 boot block */
39*41074Swilliam char	*scsiboot = "/stand/bootswd";		/* SCSI boot block */
40*41074Swilliam #endif
41*41074Swilliam #else
42*41074Swilliam char	*st506boot = "/stand/bootwd";		/* ST506 boot block */
43*41074Swilliam char	*scsiboot = "/stand/bootswd";		/* SCSI boot block */
44*41074Swilliam #endif
45*41074Swilliam 
46*41074Swilliam char	name[BOOTSIZE];
47*41074Swilliam union {
48*41074Swilliam 	char bootstrap[BOOTSIZE];
49*41074Swilliam 	struct {
50*41074Swilliam 		char pad[LABELOFFSET];
51*41074Swilliam 		struct disklabel lab;
52*41074Swilliam 	} b;
53*41074Swilliam } block0;
54*41074Swilliam 
55*41074Swilliam #define MAXTYPES	4
56*41074Swilliam char *tnames[MAXTYPES] = {
57*41074Swilliam 	"type 0",
58*41074Swilliam 	"ST506",
59*41074Swilliam 	"floppy",
60*41074Swilliam 	"SCSI",
61*41074Swilliam };
62*41074Swilliam 
main(argc,argv)63*41074Swilliam main(argc, argv)
64*41074Swilliam char *argv[];
65*41074Swilliam {
66*41074Swilliam 	register struct disklabel *lp = &block0.b.lab;
67*41074Swilliam 	register struct disktab *dp;
68*41074Swilliam 	register i;
69*41074Swilliam 	int f, b;
70*41074Swilliam 	char *boot ;
71*41074Swilliam 	char *p;
72*41074Swilliam #ifndef	STANDALONE
73*41074Swilliam 	char *sprintf();
74*41074Swilliam 
75*41074Swilliam 	if (argc < 2 || argc > 5) {
76*41074Swilliam 		fprintf(stderr, "usage: disklabel disk    (to read label)\n");
77*41074Swilliam 		fprintf(stderr,
78*41074Swilliam 	"or disklabel disk type [ packid ] [ bootblock ]    (to write label)\n");
79*41074Swilliam 		exit(1);
80*41074Swilliam 	}
81*41074Swilliam 	if (argv[1][0] != '/')
82*41074Swilliam 		sprintf(name, "/dev/r%sc", argv[1]);
83*41074Swilliam 	else
84*41074Swilliam 		strcpy(name, argv[1]);
85*41074Swilliam 	if (argc == 2) {
86*41074Swilliam 		f = open(name, O_RDONLY);
87*41074Swilliam 		if (f < 0 && argv[1][0] != '/') {
88*41074Swilliam 			sprintf(name, "/dev/r%s", argv[1]);
89*41074Swilliam 			f = open(name, O_RDONLY);
90*41074Swilliam 		}
91*41074Swilliam 		if (f < 0)
92*41074Swilliam 			Perror(name);
93*41074Swilliam #else
94*41074Swilliam 	char buf[80],c ;
95*41074Swilliam 
96*41074Swilliam new_file:
97*41074Swilliam 	f = getdev("File", name) ;
98*41074Swilliam 	for(;;)	{
99*41074Swilliam 		printf("R)ead, W)rite, F)ilename,  or E)xit [RWFE] ? ") ;
100*41074Swilliam 		c = getchar() ;
101*41074Swilliam 		printf("\n") ;
102*41074Swilliam 		if (c == 'E') break ;
103*41074Swilliam 		if (c == 'W') goto wr_lab ;
104*41074Swilliam 		if (c == 'F') { close(f) ; goto new_file ; }
105*41074Swilliam 		if (c != 'R') continue ;
106*41074Swilliam #endif
107*41074Swilliam 		if (read(f, &block0, BOOTSIZE) < BOOTSIZE)
108*41074Swilliam 			Perror(name);
109*41074Swilliam 		if (lp->dk_magic != DISKMAGIC) {
110*41074Swilliam 			fprintf(stderr,
111*41074Swilliam 				"Bad pack magic number (pack is unlabeled)\n");
112*41074Swilliam #ifndef	STANDALONE
113*41074Swilliam 			exit(1);
114*41074Swilliam #else
115*41074Swilliam 			continue ;
116*41074Swilliam #endif
117*41074Swilliam 		}
118*41074Swilliam #ifndef	STANDALONE
119*41074Swilliam 		printf("%s (%.*s):\n", name, sizeof(lp->dk_name), lp->dk_name);
120*41074Swilliam #else
121*41074Swilliam 		printf("%s (%s):\n", name, lp->dk_name);
122*41074Swilliam #endif
123*41074Swilliam 		printf("%s, ", (unsigned) lp->dk_type < MAXTYPES?
124*41074Swilliam 			tnames[lp->dk_type] : "unknown type");
125*41074Swilliam 		if(lp->dk_type == DTYPE_SCSI) {
126*41074Swilliam 			printf("%d bytes/sector, %d sectors/drive, ",
127*41074Swilliam 				lp->dk_secsize, lp->dk_secperunit);
128*41074Swilliam 			printf("%d sectors/track,\n %d tracks/cylinder, ",
129*41074Swilliam 				lp->dk_secpercyl/lp->dk_ntracks,
130*41074Swilliam 				lp->dk_ntracks);
131*41074Swilliam 			printf ("%d sectors/cylinder, ", lp->dk_secpercyl) ;
132*41074Swilliam 			printf ("%s i/o mode\n", lp->dk_blind?"blind":"slow");
133*41074Swilliam 		} else {
134*41074Swilliam 			printf("%d bytes/sector, %d sectors/track, ",
135*41074Swilliam 				lp->dk_secsize, lp->dk_nsectors);
136*41074Swilliam 			printf("%d tracks/cylinder, %d cylinders\n",
137*41074Swilliam 				lp->dk_ntracks, lp->dk_ncylinders);
138*41074Swilliam 			if (lp->dk_secpercyl !=
139*41074Swilliam 				lp->dk_nsectors * lp->dk_ntracks)
140*41074Swilliam 				printf(
141*41074Swilliam 		"WARNING: sectors/cylinder field is wrong (%d instead of %d)\n",
142*41074Swilliam 					lp->dk_secpercyl,
143*41074Swilliam 					lp->dk_nsectors * lp->dk_ntracks);
144*41074Swilliam 			if (lp->dk_secperunit != lp->dk_nsectors *
145*41074Swilliam 		    		lp->dk_ntracks * lp->dk_ncylinders)
146*41074Swilliam 				printf(
147*41074Swilliam 		"WARNING: sectors/unit field is wrong (%d instead of %d)\n",
148*41074Swilliam 					lp->dk_secperunit,
149*41074Swilliam 					lp->dk_nsectors * lp->dk_ntracks *
150*41074Swilliam 					lp->dk_ncylinders);
151*41074Swilliam 		}
152*41074Swilliam #ifndef	STANDALONE
153*41074Swilliam 		printf("partitions:\n");
154*41074Swilliam 		printf("\t       size    offset\n");
155*41074Swilliam #else
156*41074Swilliam 		printf("partition table:\n");
157*41074Swilliam #endif
158*41074Swilliam 		for (i = 0; i < 8; i++) {
159*41074Swilliam #ifndef	STANDALONE
160*41074Swilliam 		    printf("\t%c: %8d %8d", 'a' + i,
161*41074Swilliam #else
162*41074Swilliam     printf("partition %c, size %d sectors, offset %d cylinders.", 'a' + i,
163*41074Swilliam #endif
164*41074Swilliam 		       lp->dk_partition[i].nblocks, lp->dk_partition[i].cyloff);
165*41074Swilliam 		    if (lp->dk_partition[i].nblocks){
166*41074Swilliam 				if (lp->dk_type != DTYPE_SCSI) {
167*41074Swilliam #ifndef	STANDALONE
168*41074Swilliam 			printf("\t(Cyl. %d - %d",
169*41074Swilliam #else
170*41074Swilliam 			printf(" (from cyl %d to %d",
171*41074Swilliam #endif
172*41074Swilliam 			    lp->dk_partition[i].cyloff,
173*41074Swilliam 			    lp->dk_partition[i].cyloff +
174*41074Swilliam 			    (lp->dk_partition[i].nblocks + lp->dk_secpercyl
175*41074Swilliam 			        - 1) / lp->dk_secpercyl - 1);
176*41074Swilliam 			if (lp->dk_partition[i].nblocks % lp->dk_secpercyl)
177*41074Swilliam 			    putchar('*');
178*41074Swilliam 			putchar(')');
179*41074Swilliam 		    		} else {
180*41074Swilliam 				}
181*41074Swilliam 			}
182*41074Swilliam 		    printf("\n");
183*41074Swilliam 		}
184*41074Swilliam #ifdef	STANDALONE
185*41074Swilliam 		continue ;
186*41074Swilliam wr_lab:
187*41074Swilliam 	printf("Type (e.g. miniscribe85...): ") ;
188*41074Swilliam 	gets(buf) ;
189*41074Swilliam 	dp = getdiskbyname(buf);
190*41074Swilliam 	if (dp == NULL) {
191*41074Swilliam 		printf("%s: unknown disk type\n", buf);
192*41074Swilliam #ifndef	STANDALONE
193*41074Swilliam 		exit(1);
194*41074Swilliam #else
195*41074Swilliam 		continue ;
196*41074Swilliam #endif
197*41074Swilliam 	}
198*41074Swilliam #else
199*41074Swilliam 		exit(0);
200*41074Swilliam 	}
201*41074Swilliam 	dp = getdiskbyname(argv[2]);
202*41074Swilliam 	if (dp == NULL) {
203*41074Swilliam 		fprintf(stderr, "%s: unknown disk type\n", argv[2]);
204*41074Swilliam 		exit(1);
205*41074Swilliam 	}
206*41074Swilliam 	f = open(name, O_WRONLY);
207*41074Swilliam 	if (f < 0)
208*41074Swilliam 		Perror(name);
209*41074Swilliam #endif
210*41074Swilliam 	if (strcmp(dp->d_type, "scsi") == 0 || strcmp(dp->d_type, "SCSI") == 0)
211*41074Swilliam 		boot = scsiboot ; else boot = st506boot ;
212*41074Swilliam #ifndef	STANDALONE
213*41074Swilliam 	if (argc > 4)
214*41074Swilliam 		boot = argv[4];
215*41074Swilliam #endif
216*41074Swilliam 	b = open(boot, O_RDONLY);
217*41074Swilliam 	if (b < 0)
218*41074Swilliam 		Perror(boot);
219*41074Swilliam 	if (read(b, &block0, BOOTSIZE) < 0)
220*41074Swilliam 		Perror(boot);
221*41074Swilliam 	close(b) ;
222*41074Swilliam 	for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++)
223*41074Swilliam 		if (*p) {
224*41074Swilliam 			fprintf(stderr,
225*41074Swilliam 			    "Bootstrap doesn't leave room for disk label\n");
226*41074Swilliam 			exit(2);
227*41074Swilliam 		}
228*41074Swilliam 	lp->dk_magic = DISKMAGIC;
229*41074Swilliam 	if (strcmp(dp->d_type, "st506") == 0 ||
230*41074Swilliam 	    strcmp(dp->d_type, "ST506") == 0) {
231*41074Swilliam 		lp->dk_type = DTYPE_ST506;
232*41074Swilliam 		lp->dk_precompcyl = dp->d_precomp;
233*41074Swilliam 	}
234*41074Swilliam 	if (strcmp(dp->d_type, "floppy") == 0)
235*41074Swilliam 		lp->dk_type = DTYPE_FLOPPY;
236*41074Swilliam 	if (strcmp(dp->d_type, "scsi") == 0)
237*41074Swilliam 		lp->dk_type = DTYPE_SCSI;
238*41074Swilliam 
239*41074Swilliam 	if (strcmp(dp->d_type, "SCSI") == 0)
240*41074Swilliam 		lp->dk_type = DTYPE_SCSI;
241*41074Swilliam 	lp->dk_secsize = dp->d_secsize;
242*41074Swilliam 	lp->dk_nsectors = dp->d_nsectors;
243*41074Swilliam 	lp->dk_ntracks = dp->d_ntracks;
244*41074Swilliam 	lp->dk_ncylinders = dp->d_ncylinders;
245*41074Swilliam 	if (lp->dk_type == DTYPE_SCSI) {
246*41074Swilliam 		lp->dk_secpercyl = dp->d_secpercyl ;
247*41074Swilliam 		lp->dk_secperunit = dp->d_nsectors ;
248*41074Swilliam 		lp->dk_blind = dp->d_blind ;
249*41074Swilliam 	} else {
250*41074Swilliam 		lp->dk_secpercyl = dp->d_nsectors * dp->d_ntracks;
251*41074Swilliam 		lp->dk_secperunit = dp->d_nsectors * dp->d_ntracks
252*41074Swilliam 					* dp->d_ncylinders;
253*41074Swilliam 	}
254*41074Swilliam 	for (i = 0; i < 8; i++) {
255*41074Swilliam 		lp->dk_partition[i].nblocks = dp->d_partitions[i].p_size;
256*41074Swilliam 		if (lp->dk_partition[i].nblocks == -1)
257*41074Swilliam 			lp->dk_partition[i].nblocks = 0;
258*41074Swilliam 		lp->dk_partition[i].cyloff = dp->d_partitions[i].p_offset;
259*41074Swilliam 		if (lp->dk_partition[i].cyloff == -1)
260*41074Swilliam 			lp->dk_partition[i].cyloff = 0;
261*41074Swilliam 	}
262*41074Swilliam #ifndef	STANDALONE
263*41074Swilliam 	if (argc > 3)
264*41074Swilliam 		strncpy(lp->dk_name, argv[3], sizeof(lp->dk_name));
265*41074Swilliam 	else
266*41074Swilliam #endif
267*41074Swilliam 		strncpy(lp->dk_name, dp->d_name, sizeof(lp->dk_name));
268*41074Swilliam 	if (write(f, &block0, BOOTSIZE) < BOOTSIZE)
269*41074Swilliam 		Perror("write");
270*41074Swilliam #ifdef	STANDALONE
271*41074Swilliam 	}
272*41074Swilliam #endif
273*41074Swilliam 	exit(0);
274*41074Swilliam }
275*41074Swilliam 
Perror(op)276*41074Swilliam Perror(op)
277*41074Swilliam 	char *op;
278*41074Swilliam {
279*41074Swilliam 
280*41074Swilliam 	fprintf(stderr, "disklabel: "); /*perror(op);*/
281*41074Swilliam 	exit(4);
282*41074Swilliam }
283*41074Swilliam 
284*41074Swilliam #ifdef	STANDALONE
getdev(prompt,buf)285*41074Swilliam getdev(prompt, buf)
286*41074Swilliam char *buf ;
287*41074Swilliam {
288*41074Swilliam 	register int i;
289*41074Swilliam 
290*41074Swilliam 	do {
291*41074Swilliam 		printf("%s: ", prompt);
292*41074Swilliam 		gets(buf);
293*41074Swilliam 		i = open(buf, 2);
294*41074Swilliam 	} while (i <= 0);
295*41074Swilliam 	return (i);
296*41074Swilliam }
297*41074Swilliam 
fprintf(a,b,c,d,e,f,g,h)298*41074Swilliam fprintf(a,b,c,d,e,f,g,h) {
299*41074Swilliam 	printf(b,c,d,e,f,g,h) ;
300*41074Swilliam }
301*41074Swilliam #endif
302