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