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