xref: /csrg-svn/sbin/newfs/newfs.c (revision 24702)
121159Sdist /*
221159Sdist  * Copyright (c) 1983 Regents of the University of California.
321159Sdist  * All rights reserved.  The Berkeley software License Agreement
421159Sdist  * specifies the terms and conditions for redistribution.
521159Sdist  */
621159Sdist 
710762Ssam #ifndef lint
821159Sdist char copyright[] =
921159Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1021159Sdist  All rights reserved.\n";
1121159Sdist #endif not lint
1210762Ssam 
1321159Sdist #ifndef lint
14*24702Smckusick static char sccsid[] = "@(#)newfs.c	5.2 (Berkeley) 09/11/85";
1521159Sdist #endif not lint
1621159Sdist 
1710762Ssam /*
1811069Ssam  * newfs: friendly front end to mkfs
1910762Ssam  */
2010762Ssam #include <sys/param.h>
2110762Ssam #include <sys/stat.h>
2210762Ssam #include <sys/fs.h>
2313603Ssam #include <sys/dir.h>
2410762Ssam 
2510762Ssam #include <stdio.h>
2610762Ssam #include <disktab.h>
2710762Ssam 
2811183Ssam #define	BOOTDIR	"/usr/mdec"	/* directory for boot blocks */
2911183Ssam 
3016945Smckusick int	Nflag;			/* run mkfs without writing file system */
3110762Ssam int	verbose;		/* show mkfs line before exec */
3212334Shelge int	noboot;			/* do not fill boot blocks */
3310762Ssam int	fssize;			/* file system size */
3410762Ssam int	fsize;			/* fragment size */
3510762Ssam int	bsize;			/* block size */
3610762Ssam int	ntracks;		/* # tracks/cylinder */
3710762Ssam int	nsectors;		/* # sectors/track */
3810762Ssam int	sectorsize;		/* bytes/sector */
3910762Ssam int	cpg;			/* cylinders/cylinder group */
4012334Shelge int	minfree = -1;		/* free space threshold */
41*24702Smckusick int	opt;			/* optimization preference (space or time) */
4211069Ssam int	rpm;			/* revolutions/minute of drive */
4314884Smckusick int	density;		/* number of bytes per inode */
4410762Ssam 
4510762Ssam char	*av[20];		/* argv array and buffers for exec */
4610762Ssam char	a2[20];
4710762Ssam char	a3[20];
4810762Ssam char	a4[20];
4910762Ssam char	a5[20];
5010762Ssam char	a6[20];
5110762Ssam char	a7[20];
5211069Ssam char	a8[20];
5311069Ssam char	a9[20];
5414884Smckusick char	a10[20];
5510762Ssam char	device[MAXPATHLEN];
5610762Ssam char	cmd[BUFSIZ];
5710762Ssam 
5810762Ssam char	*index();
5910762Ssam char	*rindex();
6010762Ssam char	*sprintf();
6110762Ssam 
6210762Ssam main(argc, argv)
6314064Smckusick 	int argc;
6410762Ssam 	char *argv[];
6510762Ssam {
6610762Ssam 	char *cp, *special;
6710762Ssam 	register struct disktab *dp;
6810762Ssam 	register struct partition *pp;
6910762Ssam 	struct stat st;
7010762Ssam 	register int i;
7110762Ssam 	int status;
7210762Ssam 
7310762Ssam 	argc--, argv++;
7410762Ssam 	while (argc > 0 && argv[0][0] == '-') {
7510762Ssam 		for (cp = &argv[0][1]; *cp; cp++)
7610762Ssam 			switch (*cp) {
7710762Ssam 
7810762Ssam 			case 'v':
7910762Ssam 				verbose++;
8010762Ssam 				break;
8110762Ssam 
8216945Smckusick 			case 'N':
8316945Smckusick 				Nflag++;
8416945Smckusick 				/* fall through to */
8516945Smckusick 
8612334Shelge 			case 'n':
8712334Shelge 				noboot++;
8812334Shelge 				break;
8912334Shelge 
9010762Ssam 			case 's':
9110762Ssam 				if (argc < 1)
9210762Ssam 					fatal("-s: missing file system size");
9310762Ssam 				argc--, argv++;
9410762Ssam 				fssize = atoi(*argv);
9510762Ssam 				if (fssize < 0)
9610762Ssam 					fatal("%s: bad file system size",
9710762Ssam 						*argv);
9810762Ssam 				goto next;
9910762Ssam 
10010762Ssam 			case 't':
10110762Ssam 				if (argc < 1)
10210762Ssam 					fatal("-t: missing track total");
10310762Ssam 				argc--, argv++;
10410762Ssam 				ntracks = atoi(*argv);
10510762Ssam 				if (ntracks < 0)
10610762Ssam 					fatal("%s: bad total tracks", *argv);
10710762Ssam 				goto next;
10810762Ssam 
109*24702Smckusick 			case 'o':
110*24702Smckusick 				if (argc < 1)
111*24702Smckusick 					fatal("-o: missing optimization preference");
112*24702Smckusick 				argc--, argv++;
113*24702Smckusick 				if (strcmp(*argv, "space") == 0)
114*24702Smckusick 					opt = FS_OPTSPACE;
115*24702Smckusick 				else if (strcmp(*argv, "time") == 0)
116*24702Smckusick 					opt = FS_OPTTIME;
117*24702Smckusick 				else
118*24702Smckusick 					fatal("%s: bad optimization preference %s",
119*24702Smckusick 					    *argv,
120*24702Smckusick 					    "(options are `space' or `time')");
121*24702Smckusick 				goto next;
122*24702Smckusick 
12310762Ssam 			case 'b':
12410762Ssam 				if (argc < 1)
12510762Ssam 					fatal("-b: missing block size");
12610762Ssam 				argc--, argv++;
12710762Ssam 				bsize = atoi(*argv);
12810762Ssam 				if (bsize < 0 || bsize < MINBSIZE)
12910762Ssam 					fatal("%s: bad block size", *argv);
13010762Ssam 				goto next;
13110762Ssam 
13210762Ssam 			case 'f':
13310762Ssam 				if (argc < 1)
13410762Ssam 					fatal("-f: missing frag size");
13510762Ssam 				argc--, argv++;
13610762Ssam 				fsize = atoi(*argv);
13710762Ssam 				if (fsize < 0)
13810762Ssam 					fatal("%s: bad frag size", *argv);
13910762Ssam 				goto next;
14010762Ssam 
14110762Ssam 			case 'S':
14210762Ssam 				if (argc < 1)
14310762Ssam 					fatal("-S: missing sector size");
14410762Ssam 				argc--, argv++;
14510762Ssam 				sectorsize = atoi(*argv);
14610762Ssam 				if (sectorsize < 0)
14710762Ssam 					fatal("%s: bad sector size", *argv);
14810762Ssam 				goto next;
14910762Ssam 
15010762Ssam 			case 'c':
15110762Ssam 				if (argc < 1)
15210762Ssam 					fatal("-c: missing cylinders/group");
15310762Ssam 				argc--, argv++;
15410762Ssam 				cpg = atoi(*argv);
15510762Ssam 				if (cpg < 0)
15610762Ssam 					fatal("%s: bad cylinders/group", *argv);
15710762Ssam 				goto next;
15810762Ssam 
15911069Ssam 			case 'm':
16011069Ssam 				if (argc < 1)
16111069Ssam 					fatal("-m: missing free space %%\n");
16211069Ssam 				argc--, argv++;
16311069Ssam 				minfree = atoi(*argv);
16411069Ssam 				if (minfree < 0 || minfree > 99)
16511069Ssam 					fatal("%s: bad free space %%\n",
16611069Ssam 						*argv);
16711069Ssam 				goto next;
16811069Ssam 
16911069Ssam 			case 'r':
17011069Ssam 				if (argc < 1)
17111069Ssam 					fatal("-r: missing revs/minute\n");
17211069Ssam 				argc--, argv++;
17311069Ssam 				rpm = atoi(*argv);
17411069Ssam 				if (rpm < 0)
17511069Ssam 					fatal("%s: bad revs/minute\n", *argv);
17611069Ssam 				goto next;
17711069Ssam 
17814884Smckusick 			case 'i':
17914884Smckusick 				if (argc < 1)
18014884Smckusick 					fatal("-i: missing bytes per inode\n");
18114884Smckusick 				argc--, argv++;
18214884Smckusick 				density = atoi(*argv);
18314884Smckusick 				if (density < 0)
18414884Smckusick 					fatal("%s: bad bytes per inode\n",
18514884Smckusick 						*argv);
18614884Smckusick 				goto next;
18714884Smckusick 
18810762Ssam 			default:
18910762Ssam 				fatal("-%c: unknown flag", cp);
19010762Ssam 			}
19110762Ssam next:
19210762Ssam 		argc--, argv++;
19310762Ssam 	}
19410762Ssam 	if (argc < 2) {
19511069Ssam 		fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n",
19610762Ssam 			"special-device device-type");
19710762Ssam 		fprintf(stderr, "where mkfs-options are:\n");
19816945Smckusick 		fprintf(stderr, "\t-N do not create file system, %s\n",
19916945Smckusick 			"just print out parameters");
20011057Ssam 		fprintf(stderr, "\t-s file system size (sectors)\n");
20111057Ssam 		fprintf(stderr, "\t-b block size\n");
20211057Ssam 		fprintf(stderr, "\t-f frag size\n");
20310873Ssam 		fprintf(stderr, "\t-t tracks/cylinder\n");
20410873Ssam 		fprintf(stderr, "\t-c cylinders/group\n");
20511069Ssam 		fprintf(stderr, "\t-m minimum free space %%\n");
206*24702Smckusick 		fprintf(stderr, "\t-o optimization preference %s\n",
207*24702Smckusick 			"(`space' or `time')");
20811069Ssam 		fprintf(stderr, "\t-r revolutions/minute\n");
20911057Ssam 		fprintf(stderr, "\t-S sector size\n");
21014884Smckusick 		fprintf(stderr, "\t-i number of bytes per inode\n");
21110762Ssam 		exit(1);
21210762Ssam 	}
21310762Ssam 	special = argv[0];
21414064Smckusick 	cp = rindex(special, '/');
21514064Smckusick 	if (cp != 0)
21614064Smckusick 		special = cp + 1;
21714321Ssam 	if (*special == 'r' && special[1] != 'a' && special[1] != 'b')
21814064Smckusick 		special++;
21914064Smckusick 	special = sprintf(device, "/dev/r%s", special);
22010762Ssam 	if (stat(special, &st) < 0) {
22111069Ssam 		fprintf(stderr, "newfs: "); perror(special);
22210762Ssam 		exit(2);
22310762Ssam 	}
22414064Smckusick 	if ((st.st_mode & S_IFMT) != S_IFCHR)
22514064Smckusick 		fatal("%s: not a character device", special);
22610762Ssam 	dp = getdiskbyname(argv[1]);
22710762Ssam 	if (dp == 0)
22810762Ssam 		fatal("%s: unknown disk type", argv[1]);
22910762Ssam 	cp = index(argv[0], '\0') - 1;
23010762Ssam 	if (cp == 0 || *cp < 'a' || *cp > 'h')
23110762Ssam 		fatal("%s: can't figure out file system partition", argv[0]);
23210762Ssam 	pp = &dp->d_partitions[*cp - 'a'];
23310762Ssam 	if (fssize == 0) {
23410762Ssam 		fssize = pp->p_size;
23510762Ssam 		if (fssize < 0)
23610762Ssam 			fatal("%s: no default size for `%c' partition",
23710762Ssam 				argv[1], *cp);
23810762Ssam 	}
23910762Ssam 	if (nsectors == 0) {
24010762Ssam 		nsectors = dp->d_nsectors;
24110762Ssam 		if (nsectors < 0)
24210762Ssam 			fatal("%s: no default #sectors/track", argv[1]);
24310762Ssam 	}
24410762Ssam 	if (ntracks == 0) {
24510762Ssam 		ntracks = dp->d_ntracks;
24610762Ssam 		if (ntracks < 0)
24710762Ssam 			fatal("%s: no default #tracks", argv[1]);
24810762Ssam 	}
24910762Ssam 	if (sectorsize == 0) {
25010762Ssam 		sectorsize = dp->d_secsize;
25110762Ssam 		if (sectorsize < 0)
25210762Ssam 			fatal("%s: no default sector size", argv[1]);
25310762Ssam 	}
25410762Ssam 	if (bsize == 0) {
25510762Ssam 		bsize = pp->p_bsize;
25610762Ssam 		if (bsize < 0)
25710762Ssam 			fatal("%s: no default block size for `%c' partition",
25810762Ssam 				argv[1], *cp);
25910762Ssam 	}
26010762Ssam 	if (fsize == 0) {
26110762Ssam 		fsize = pp->p_fsize;
26210762Ssam 		if (fsize < 0)
26310762Ssam 			fatal("%s: no default frag size for `%c' partition",
26410762Ssam 				argv[1], *cp);
26510762Ssam 	}
26611069Ssam 	if (rpm == 0) {
26711069Ssam 		rpm = dp->d_rpm;
26811069Ssam 		if (rpm < 0)
26911069Ssam 			fatal("%s: no default revolutions/minute value",
27011069Ssam 				argv[1]);
27111069Ssam 	}
27214884Smckusick 	if (density <= 0)
27314884Smckusick 		density = 2048;
27412334Shelge 	if (minfree < 0)
27511069Ssam 		minfree = 10;
276*24702Smckusick 	if (minfree < 10 && opt != FS_OPTSPACE) {
277*24702Smckusick 		fprintf(stderr, "setting optimization for space ");
278*24702Smckusick 		fprintf(stderr, "with minfree less than 10%\n");
279*24702Smckusick 		opt = FS_OPTSPACE;
280*24702Smckusick 	}
28111069Ssam 	if (cpg == 0)
28211069Ssam 		cpg = 16;
28310762Ssam 	i = 0;
28416945Smckusick 	if (Nflag)
28516945Smckusick 		av[i++] = "-N";
28616945Smckusick 	av[i++] = special;
28710762Ssam 	av[i++] = sprintf(a2, "%d", fssize);
28810762Ssam 	av[i++] = sprintf(a3, "%d", nsectors);
28910762Ssam 	av[i++] = sprintf(a4, "%d", ntracks);
29010762Ssam 	av[i++] = sprintf(a5, "%d", bsize);
29110762Ssam 	av[i++] = sprintf(a6, "%d", fsize);
29211069Ssam 	av[i++] = sprintf(a7, "%d", cpg);
29311069Ssam 	av[i++] = sprintf(a8, "%d", minfree);
29411069Ssam 	av[i++] = sprintf(a9, "%d", rpm / 60);
29514884Smckusick 	av[i++] = sprintf(a10, "%d", density);
296*24702Smckusick 	av[i++] = opt == FS_OPTSPACE ? "s" : "t";
29710762Ssam 	av[i++] = 0;
29816945Smckusick 	strcpy(cmd, "/etc/mkfs");
29910762Ssam 	for (i = 0; av[i] != 0; i++) {
30010762Ssam 		strcat(cmd, " ");
30110762Ssam 		strcat(cmd, av[i]);
30210762Ssam 	}
30310762Ssam 	if (verbose)
30410762Ssam 		printf("%s\n", cmd);
30510762Ssam 	if (status = system(cmd))
30616407Sralph 		exit(status >> 8);
30712334Shelge 	if (*cp == 'a' && !noboot) {
30810762Ssam 		char type[3];
30913819Ssam 		struct stat sb;
31010762Ssam 
31110762Ssam 		cp = rindex(special, '/');
31210762Ssam 		if (cp == NULL)
31310762Ssam 			fatal("%s: can't figure out disk type from name",
31410762Ssam 				special);
31513819Ssam 		if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR)
31610873Ssam 			cp++;
31710762Ssam 		type[0] = *++cp;
31810762Ssam 		type[1] = *++cp;
31910762Ssam 		type[2] = '\0';
32010762Ssam 		installboot(special, type);
32110762Ssam 	}
32210762Ssam 	exit(0);
32310762Ssam }
32410762Ssam 
32510762Ssam installboot(dev, type)
32610762Ssam 	char *dev, *type;
32710762Ssam {
32810762Ssam 	int fd;
32910762Ssam 	char bootblock[MAXPATHLEN], standalonecode[MAXPATHLEN];
33010762Ssam 	char bootimage[BBSIZE];
33110762Ssam 
33211183Ssam 	sprintf(bootblock, "%s/%sboot", BOOTDIR, type);
33311183Ssam 	sprintf(standalonecode, "%s/boot%s", BOOTDIR, type);
33410762Ssam 	if (verbose) {
33510762Ssam 		printf("installing boot code\n");
33610762Ssam 		printf("sector 0 boot = %s\n", bootblock);
33710762Ssam 		printf("1st level boot = %s\n", standalonecode);
33810762Ssam 	}
33910762Ssam 	fd = open(bootblock, 0);
34010762Ssam 	if (fd < 0) {
34111069Ssam 		fprintf(stderr, "newfs: "); perror(bootblock);
34210762Ssam 		exit(1);
34310762Ssam 	}
34410762Ssam 	if (read(fd, bootimage, DEV_BSIZE) < 0) {
34511069Ssam 		fprintf(stderr, "newfs: "); perror(bootblock);
34610762Ssam 		exit(2);
34710762Ssam 	}
34810762Ssam 	close(fd);
34910762Ssam 	fd = open(standalonecode, 0);
35010762Ssam 	if (fd < 0) {
35111069Ssam 		fprintf(stderr, "newfs: "); perror(standalonecode);
35210762Ssam 		exit(1);
35310762Ssam 	}
35410762Ssam 	if (read(fd, &bootimage[DEV_BSIZE], BBSIZE - DEV_BSIZE) < 0) {
35511069Ssam 		fprintf(stderr, "newfs: "); perror(standalonecode);
35610762Ssam 		exit(2);
35710762Ssam 	}
35810762Ssam 	close(fd);
35910763Ssam 	fd = open(dev, 1);
36010762Ssam 	if (fd < 0) {
36111069Ssam 		fprintf(stderr, "newfs: "); perror(dev);
36210762Ssam 		exit(1);
36310762Ssam 	}
36410762Ssam 	if (write(fd, bootimage, BBSIZE) != BBSIZE) {
36511069Ssam 		fprintf(stderr, "newfs: "); perror(dev);
36610762Ssam 		exit(2);
36710762Ssam 	}
36810762Ssam 	close(fd);
36910762Ssam }
37010762Ssam 
37110762Ssam /*VARARGS*/
37210762Ssam fatal(fmt, arg1, arg2)
37310762Ssam 	char *fmt;
37410762Ssam {
37510762Ssam 
37611069Ssam 	fprintf(stderr, "newfs: ");
37710762Ssam 	fprintf(stderr, fmt, arg1, arg2);
37810762Ssam 	putc('\n', stderr);
37910762Ssam 	exit(10);
38010762Ssam }
381