|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.