1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)diskpart.c	5.5 (Berkeley) 5/30/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * Program to calculate standard disk partition sizes.
  19:  */
  20: #include <sys/param.h>
  21: 
  22: #include <stdio.h>
  23: #include <disktab.h>
  24: 
  25: #define NPARTITIONS 8
  26: #define PART(x)     (x - 'a')
  27: 
  28: /*
  29:  * Default partition sizes, where they exist.
  30:  */
  31: #define NDEFAULTS   4
  32: int defpart[NDEFAULTS][NPARTITIONS] = {
  33:    { 15884, 66880, 0, 15884, 307200, 0, 0, 291346 },    /* ~ 356+ Mbytes */
  34:    { 15884, 33440, 0, 15884, 55936, 0, 0, 291346 }, /* ~ 206-355 Mbytes */
  35:    { 15884, 33440, 0, 15884, 55936, 0, 0, 0 },      /* ~ 61-205 Mbytes */
  36:    { 15884, 10032, 0, 15884, 0, 0, 0, 0 },      /* ~ 20-60 Mbytes */
  37: };
  38: 
  39: /*
  40:  * Each array defines a layout for a disk;
  41:  * that is, the collection of partitions totally
  42:  * covers the physical space on a disk.
  43:  */
  44: #define NLAYOUTS    3
  45: char    layouts[NLAYOUTS][NPARTITIONS] = {
  46:    { 'a', 'b', 'h', 'g' },
  47:    { 'a', 'b', 'h', 'd', 'e', 'f' },
  48:    { 'c' },
  49: };
  50: 
  51: /*
  52:  * Default disk block and disk block fragment
  53:  * sizes for each file system.  Those file systems
  54:  * with zero block and frag sizes are special cases
  55:  * (e.g. swap areas or for access to the entire device).
  56:  */
  57: struct  defparam {
  58:     int p_bsize;    /* block size */
  59:     int p_fsize;    /* frag size */
  60: } defparam[NPARTITIONS] = {
  61:     { 8192, 1024 },     /* a */
  62:     { 8192, 1024 },     /* b */
  63:     { 8192, 1024 },     /* c */
  64:     { 4096, 512 },      /* d */
  65:     { 8192, 1024 },     /* e */
  66:     { 8192, 1024 },     /* f */
  67:     { 8192, 1024 },     /* g */
  68:     { 8192, 1024 }      /* h */
  69: };
  70: 
  71: /*
  72:  * Each disk has some space reserved for a bad sector
  73:  * forwarding table.  DEC standard 144 uses the first
  74:  * 5 even numbered sectors in the last track of the
  75:  * last cylinder for replicated storage of the bad sector
  76:  * table; another 126 sectors past this is needed as a
  77:  * pool of replacement sectors.
  78:  */
  79: int badsecttable = 126; /* # sectors */
  80: 
  81: int pflag;          /* print device driver partition tables */
  82: int dflag;          /* print disktab entry */
  83: 
  84: struct  disktab *promptfordisk();
  85: 
  86: main(argc, argv)
  87:     int argc;
  88:     char *argv[];
  89: {
  90:     struct disktab *dp;
  91:     register int curcyl, spc, def, part, layout;
  92:     int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS];
  93:     char *lp;
  94: 
  95:     argc--, argv++;
  96:     if (argc < 1) {
  97:         fprintf(stderr, "usage: disktab [ -p ] [ -d ] disk-type\n");
  98:         exit(1);
  99:     }
 100:     if (argc > 0 && strcmp(*argv, "-p") == 0) {
 101:         pflag++;
 102:         argc--, argv++;
 103:     }
 104:     if (argc > 0 && strcmp(*argv, "-d") == 0) {
 105:         dflag++;
 106:         argc--, argv++;
 107:     }
 108:     dp = getdiskbyname(*argv);
 109:     if (dp == NULL) {
 110:         if (isatty(0))
 111:             dp = promptfordisk(*argv);
 112:         if (dp == NULL) {
 113:             fprintf(stderr, "%s: unknown disk type\n", *argv);
 114:             exit(2);
 115:         }
 116:     }
 117:     spc = dp->d_nsectors * dp->d_ntracks;
 118:     /*
 119: 	 * Bad sector table contains one track for the replicated
 120: 	 * copies of the table and enough full tracks preceding
 121: 	 * the last track to hold the pool of free blocks to which
 122: 	 * bad sectors are mapped.
 123: 	 */
 124:     badsecttable = dp->d_nsectors + roundup(badsecttable, dp->d_nsectors);
 125:     threshhold = howmany(spc, badsecttable);
 126:     if (dp->d_badsectforw == 0) {
 127:         badsecttable = 0;
 128:         threshhold = 0;
 129:     }
 130: 
 131:     /*
 132: 	 * Figure out if disk is large enough for
 133: 	 * expanded swap area and 'd', 'e', and 'f'
 134: 	 * partitions.  Otherwise, use smaller defaults
 135: 	 * based on RK07.
 136: 	 */
 137:     for (def = 0; def < NDEFAULTS; def++) {
 138:         curcyl = 0;
 139:         for (part = PART('a'); part < NPARTITIONS; part++)
 140:             curcyl += howmany(defpart[def][part], spc);
 141:         if (curcyl < dp->d_ncylinders - threshhold)
 142:             break;
 143:     }
 144:     if (def >= NDEFAULTS) {
 145:         fprintf(stderr, "%s: disk too small, calculate by hand\n",
 146:             *argv);
 147:         exit(3);
 148:     }
 149: 
 150:     /*
 151: 	 * Calculate number of cylinders allocated to each disk
 152: 	 * partition.  We may waste a bit of space here, but it's
 153: 	 * in the interest of compatibility (for mixed disk systems).
 154: 	 */
 155:     for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) {
 156:         numcyls[part] = 0;
 157:         if (defpart[def][part] != 0) {
 158:             numcyls[part] = howmany(defpart[def][part], spc);
 159:             curcyl += numcyls[part];
 160:         }
 161:     }
 162:     numcyls[PART('f')] = dp->d_ncylinders - curcyl;
 163:     numcyls[PART('g')] =
 164:         numcyls[PART('d')] + numcyls[PART('e')] + numcyls[PART('f')];
 165:     numcyls[PART('c')] = dp->d_ncylinders;
 166:     defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable;
 167:     defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable;
 168:     defpart[def][PART('c')] = numcyls[PART('c')] * spc;
 169:     if (!pflag)
 170:         defpart[def][PART('c')] -= badsecttable;
 171: 
 172:     /*
 173: 	 * Calculate starting cylinder number for each partition.
 174: 	 * Note the 'h' partition is physically located before the
 175: 	 * 'g' or 'd' partition.  This is reflected in the layout
 176: 	 * arrays defined above.
 177: 	 */
 178:     for (layout = 0; layout < NLAYOUTS; layout++) {
 179:         curcyl = 0;
 180:         for (lp = layouts[layout]; *lp != 0; lp++) {
 181:             startcyl[PART(*lp)] = curcyl;
 182:             curcyl += numcyls[PART(*lp)];
 183:         }
 184:     }
 185: 
 186:     if (pflag) {
 187:         printf("}, %s_sizes[%d] = {\n", dp->d_name, NPARTITIONS);
 188:         for (part = PART('a'); part < NPARTITIONS; part++) {
 189:             if (numcyls[part] == 0) {
 190:                 printf("\t0,\t0,\n");
 191:                 continue;
 192:             }
 193:             if (dp->d_sectoffset == 0) {
 194:                    printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n",
 195:                     defpart[def][part], startcyl[part],
 196:                     'A' + part, startcyl[part],
 197:                     startcyl[part] + numcyls[part] - 1);
 198:                 continue;
 199:             }
 200:             printf("\t%d,\t%d,\t\t/* %c=sectors %d thru %d */\n",
 201:                 defpart[def][part], spc * startcyl[part],
 202:                 'A' + part, spc * startcyl[part],
 203:                 spc * startcyl[part] + defpart[def][part] - 1);
 204:         }
 205:         exit(0);
 206:     }
 207:     if (dflag) {
 208:         int nparts;
 209: 
 210:         /*
 211: 		 * In case the disk is in the ``in-between'' range
 212: 		 * where the 'g' partition is smaller than the 'h'
 213: 		 * partition, reverse the frag sizes so the /usr partition
 214: 		 * is always set up with a frag size larger than the
 215: 		 * user's partition.
 216: 		 */
 217:         if (defpart[def][PART('g')] < defpart[def][PART('h')]) {
 218:             int temp;
 219: 
 220:             temp = defparam[PART('h')].p_fsize;
 221:             defparam[PART('h')].p_fsize =
 222:                 defparam[PART('g')].p_fsize;
 223:             defparam[PART('g')].p_fsize = temp;
 224:         }
 225:         printf("%s:\\\n", dp->d_name);
 226:         printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:%s%s\\\n", dp->d_type,
 227:             dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders,
 228:             dp->d_badsectforw ? "sf:" : "",
 229:             dp->d_sectoffset ? "so:" : "");
 230:         for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++)
 231:             if (defpart[def][part] != 0)
 232:                 nparts++;
 233:         for (part = PART('a'); part < NPARTITIONS; part++) {
 234:             if (defpart[def][part] == 0)
 235:                 continue;
 236:             printf("\t:p%c#%d:", 'a' + part, defpart[def][part]);
 237:             if (defparam[part].p_bsize != 0) {
 238:                 printf("b%c#%d:f%c#%d:",
 239:                   'a' + part, defparam[part].p_bsize,
 240:                   'a' + part, defparam[part].p_fsize);
 241:             }
 242:             nparts--;
 243:             printf("%s\n", nparts > 0 ? "\\" : "");
 244:         }
 245:         exit(0);
 246:     }
 247:     printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n",
 248:         dp->d_name, dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
 249:     printf("\n    Partition\t   Size\t   Range\n");
 250:     for (part = PART('a'); part < NPARTITIONS; part++) {
 251:         printf("\t%c\t", 'a' + part);
 252:         if (numcyls[part] == 0) {
 253:             printf(" unused\n");
 254:             continue;
 255:         }
 256:         printf("%7d\t%4d - %d\n", defpart[def][part], startcyl[part],
 257:             startcyl[part] + numcyls[part] - 1);
 258:     }
 259: }
 260: 
 261: struct disktab disk;
 262: 
 263: struct  field {
 264:     char    *f_name;
 265:     char    *f_defaults;
 266:     int *f_location;
 267: } fields[] = {
 268:     { "sector size",        "512",  &disk.d_secsize },
 269:     { "#sectors/track",     0,  &disk.d_nsectors },
 270:     { "#tracks/cylinder",       0,  &disk.d_ntracks },
 271:     { "#cylinders",         0,  &disk.d_ncylinders },
 272:     { "revolutions/minute",     "3600", &disk.d_rpm },
 273:     { 0, 0, 0 },
 274: };
 275: 
 276: struct disktab *
 277: promptfordisk(name)
 278:     char *name;
 279: {
 280:     register struct disktab *dp = &disk;
 281:     register struct field *fp;
 282:     static char type[BUFSIZ];
 283:     char buf[BUFSIZ], *cp, *gets();
 284: 
 285:     dp->d_name = name;
 286:     fprintf(stderr,
 287:         "%s: unknown disk type, want to supply parameters (y/n)? ",
 288:         name);
 289:     (void) gets(buf);
 290:     if (*buf != 'y')
 291:         return ((struct disktab *)0);
 292: gettype:
 293:     fprintf(stderr, "type (winchester|removable|simulated)? ");
 294:     (void) gets(type);
 295:     if (strcmp(type, "winchester") && strcmp(type, "removable") &&
 296:         strcmp(type, "simulated")) {
 297:         fprintf(stderr, "%s: bad disk type\n", type);
 298:         goto gettype;
 299:     }
 300:     dp->d_type = type;
 301:     fprintf(stderr, "(type <cr> to get default value, if only one)\n");
 302:     fprintf(stderr, "Do %ss require sector or cylinder offsets (%s)? ",
 303:         dp->d_name, "cylinder");
 304:     (void) gets(buf);
 305:     if (*buf == 's')
 306:         dp->d_sectoffset = 1;
 307:     else
 308:         dp->d_sectoffset = 0;
 309:     fprintf(stderr, "Do %ss support bad144 bad block forwarding (yes)? ",
 310:         dp->d_name);
 311:     (void) gets(buf);
 312:     if (*buf != 'n')
 313:         dp->d_badsectforw = 1;
 314:     else
 315:         dp->d_badsectforw = 0;
 316:     for (fp = fields; fp->f_name != NULL; fp++) {
 317: again:
 318:         fprintf(stderr, "%s ", fp->f_name);
 319:         if (fp->f_defaults != NULL)
 320:             fprintf(stderr, "(%s)", fp->f_defaults);
 321:         fprintf(stderr, "? ");
 322:         cp = gets(buf);
 323:         if (*cp == '\0') {
 324:             if (fp->f_defaults == NULL) {
 325:                 fprintf(stderr, "no default value\n");
 326:                 goto again;
 327:             }
 328:             cp = fp->f_defaults;
 329:         }
 330:         *fp->f_location = atoi(cp);
 331:         if (*fp->f_location == 0) {
 332:             fprintf(stderr, "%s: bad value\n", cp);
 333:             goto again;
 334:         }
 335:     }
 336:     return (dp);
 337: }

Defined functions

main defined in line 86; never used
promptfordisk defined in line 276; used 2 times

Defined variables

badsecttable defined in line 79; used 7 times
copyright defined in line 8; never used
defparam defined in line 60; used 7 times
defpart defined in line 32; used 16 times
dflag defined in line 82; used 2 times
disk defined in line 261; used 6 times
fields defined in line 267; used 1 times
layouts defined in line 45; used 1 times
pflag defined in line 81; used 3 times
sccsid defined in line 14; never used

Defined struct's

defparam defined in line 57; never used
field defined in line 263; used 2 times
  • in line 281(2)

Defined macros

NDEFAULTS defined in line 31; used 3 times
NLAYOUTS defined in line 44; used 2 times
NPARTITIONS defined in line 25; used 12 times
PART defined in line 26; used 27 times
Last modified: 1986-05-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1376
Valid CSS Valid XHTML 1.0 Strict