|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)diskpart.c 5.11 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * Program to calculate standard disk partition sizes. ! 32: */ ! 33: #include <sys/param.h> ! 34: #define DKTYPENAMES ! 35: #include <sys/disklabel.h> ! 36: ! 37: #include <stdio.h> ! 38: #include <ctype.h> ! 39: ! 40: #define for_now /* show all of `c' partition for disklabel */ ! 41: #define NPARTITIONS 8 ! 42: #define PART(x) (x - 'a') ! 43: ! 44: /* ! 45: * Default partition sizes, where they exist. ! 46: */ ! 47: #define NDEFAULTS 4 ! 48: int defpart[NDEFAULTS][NPARTITIONS] = { ! 49: { 15884, 66880, 0, 15884, 307200, 0, 0, 291346 }, /* ~ 356+ Mbytes */ ! 50: { 15884, 33440, 0, 15884, 55936, 0, 0, 291346 }, /* ~ 206-355 Mbytes */ ! 51: { 15884, 33440, 0, 15884, 55936, 0, 0, 0 }, /* ~ 61-205 Mbytes */ ! 52: { 15884, 10032, 0, 15884, 0, 0, 0, 0 }, /* ~ 20-60 Mbytes */ ! 53: }; ! 54: ! 55: /* ! 56: * Each array defines a layout for a disk; ! 57: * that is, the collection of partitions totally ! 58: * covers the physical space on a disk. ! 59: */ ! 60: #define NLAYOUTS 3 ! 61: char layouts[NLAYOUTS][NPARTITIONS] = { ! 62: { 'a', 'b', 'h', 'g' }, ! 63: { 'a', 'b', 'h', 'd', 'e', 'f' }, ! 64: { 'c' }, ! 65: }; ! 66: ! 67: /* ! 68: * Default disk block and disk block fragment ! 69: * sizes for each file system. Those file systems ! 70: * with zero block and frag sizes are special cases ! 71: * (e.g. swap areas or for access to the entire device). ! 72: */ ! 73: struct partition defparam[NPARTITIONS] = { ! 74: { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* a */ ! 75: { 0, 0, 1024, FS_SWAP, 8, 0 }, /* b */ ! 76: { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* c */ ! 77: { 0, 0, 512, FS_UNUSED, 8, 0 }, /* d */ ! 78: { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* e */ ! 79: { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* f */ ! 80: { 0, 0, 1024, FS_UNUSED, 8, 0 }, /* g */ ! 81: { 0, 0, 1024, FS_UNUSED, 8, 0 } /* h */ ! 82: }; ! 83: ! 84: /* ! 85: * Each disk has some space reserved for a bad sector ! 86: * forwarding table. DEC standard 144 uses the first ! 87: * 5 even numbered sectors in the last track of the ! 88: * last cylinder for replicated storage of the bad sector ! 89: * table; another 126 sectors past this is needed as a ! 90: * pool of replacement sectors. ! 91: */ ! 92: int badsecttable = 126; /* # sectors */ ! 93: ! 94: int pflag; /* print device driver partition tables */ ! 95: int dflag; /* print disktab entry */ ! 96: ! 97: struct disklabel *promptfordisk(); ! 98: ! 99: main(argc, argv) ! 100: int argc; ! 101: char *argv[]; ! 102: { ! 103: struct disklabel *dp; ! 104: register int curcyl, spc, def, part, layout, j; ! 105: int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS]; ! 106: int totsize = 0; ! 107: char *lp, *tyname; ! 108: ! 109: argc--, argv++; ! 110: if (argc < 1) { ! 111: fprintf(stderr, ! 112: "usage: disktab [ -p ] [ -d ] [ -s size ] disk-type\n"); ! 113: exit(1); ! 114: } ! 115: if (argc > 0 && strcmp(*argv, "-p") == 0) { ! 116: pflag++; ! 117: argc--, argv++; ! 118: } ! 119: if (argc > 0 && strcmp(*argv, "-d") == 0) { ! 120: dflag++; ! 121: argc--, argv++; ! 122: } ! 123: if (argc > 1 && strcmp(*argv, "-s") == 0) { ! 124: totsize = atoi(argv[1]); ! 125: argc += 2, argv += 2; ! 126: } ! 127: dp = getdiskbyname(*argv); ! 128: if (dp == NULL) { ! 129: if (isatty(0)) ! 130: dp = promptfordisk(*argv); ! 131: if (dp == NULL) { ! 132: fprintf(stderr, "%s: unknown disk type\n", *argv); ! 133: exit(2); ! 134: } ! 135: } else { ! 136: if (dp->d_flags & D_REMOVABLE) ! 137: tyname = "removable"; ! 138: else if (dp->d_flags & D_RAMDISK) ! 139: tyname = "simulated"; ! 140: else ! 141: tyname = "winchester"; ! 142: } ! 143: spc = dp->d_secpercyl; ! 144: /* ! 145: * Bad sector table contains one track for the replicated ! 146: * copies of the table and enough full tracks preceding ! 147: * the last track to hold the pool of free blocks to which ! 148: * bad sectors are mapped. ! 149: * If disk size was specified explicitly, use specified size. ! 150: */ ! 151: if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT && ! 152: totsize == 0) { ! 153: badsecttable = dp->d_nsectors + ! 154: roundup(badsecttable, dp->d_nsectors); ! 155: threshhold = howmany(spc, badsecttable); ! 156: } else { ! 157: badsecttable = 0; ! 158: threshhold = 0; ! 159: } ! 160: /* ! 161: * If disk size was specified, recompute number of cylinders ! 162: * that may be used, and set badsecttable to any remaining ! 163: * fraction of the last cylinder. ! 164: */ ! 165: if (totsize != 0) { ! 166: dp->d_ncylinders = howmany(totsize, spc); ! 167: badsecttable = spc * dp->d_ncylinders - totsize; ! 168: } ! 169: ! 170: /* ! 171: * Figure out if disk is large enough for ! 172: * expanded swap area and 'd', 'e', and 'f' ! 173: * partitions. Otherwise, use smaller defaults ! 174: * based on RK07. ! 175: */ ! 176: for (def = 0; def < NDEFAULTS; def++) { ! 177: curcyl = 0; ! 178: for (part = PART('a'); part < NPARTITIONS; part++) ! 179: curcyl += howmany(defpart[def][part], spc); ! 180: if (curcyl < dp->d_ncylinders - threshhold) ! 181: break; ! 182: } ! 183: if (def >= NDEFAULTS) { ! 184: fprintf(stderr, "%s: disk too small, calculate by hand\n", ! 185: *argv); ! 186: exit(3); ! 187: } ! 188: ! 189: /* ! 190: * Calculate number of cylinders allocated to each disk ! 191: * partition. We may waste a bit of space here, but it's ! 192: * in the interest of (very backward) compatibility ! 193: * (for mixed disk systems). ! 194: */ ! 195: for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) { ! 196: numcyls[part] = 0; ! 197: if (defpart[def][part] != 0) { ! 198: numcyls[part] = howmany(defpart[def][part], spc); ! 199: curcyl += numcyls[part]; ! 200: } ! 201: } ! 202: numcyls[PART('f')] = dp->d_ncylinders - curcyl; ! 203: numcyls[PART('g')] = ! 204: numcyls[PART('d')] + numcyls[PART('e')] + numcyls[PART('f')]; ! 205: numcyls[PART('c')] = dp->d_ncylinders; ! 206: defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable; ! 207: defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable; ! 208: defpart[def][PART('c')] = numcyls[PART('c')] * spc; ! 209: #ifndef for_now ! 210: if (totsize || !pflag) ! 211: #else ! 212: if (totsize) ! 213: #endif ! 214: defpart[def][PART('c')] -= badsecttable; ! 215: ! 216: /* ! 217: * Calculate starting cylinder number for each partition. ! 218: * Note the 'h' partition is physically located before the ! 219: * 'g' or 'd' partition. This is reflected in the layout ! 220: * arrays defined above. ! 221: */ ! 222: for (layout = 0; layout < NLAYOUTS; layout++) { ! 223: curcyl = 0; ! 224: for (lp = layouts[layout]; *lp != 0; lp++) { ! 225: startcyl[PART(*lp)] = curcyl; ! 226: curcyl += numcyls[PART(*lp)]; ! 227: } ! 228: } ! 229: ! 230: if (pflag) { ! 231: printf("}, %s_sizes[%d] = {\n", dp->d_typename, NPARTITIONS); ! 232: for (part = PART('a'); part < NPARTITIONS; part++) { ! 233: if (numcyls[part] == 0) { ! 234: printf("\t0,\t0,\n"); ! 235: continue; ! 236: } ! 237: if (dp->d_type != DTYPE_MSCP) { ! 238: printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n", ! 239: defpart[def][part], startcyl[part], ! 240: 'A' + part, startcyl[part], ! 241: startcyl[part] + numcyls[part] - 1); ! 242: continue; ! 243: } ! 244: printf("\t%d,\t%d,\t\t/* %c=sectors %d thru %d */\n", ! 245: defpart[def][part], spc * startcyl[part], ! 246: 'A' + part, spc * startcyl[part], ! 247: spc * startcyl[part] + defpart[def][part] - 1); ! 248: } ! 249: exit(0); ! 250: } ! 251: if (dflag) { ! 252: int nparts; ! 253: ! 254: /* ! 255: * In case the disk is in the ``in-between'' range ! 256: * where the 'g' partition is smaller than the 'h' ! 257: * partition, reverse the frag sizes so the /usr partition ! 258: * is always set up with a frag size larger than the ! 259: * user's partition. ! 260: */ ! 261: if (defpart[def][PART('g')] < defpart[def][PART('h')]) { ! 262: int temp; ! 263: ! 264: temp = defparam[PART('h')].p_fsize; ! 265: defparam[PART('h')].p_fsize = ! 266: defparam[PART('g')].p_fsize; ! 267: defparam[PART('g')].p_fsize = temp; ! 268: } ! 269: printf("%s:\\\n", dp->d_typename); ! 270: printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:", tyname, ! 271: dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders); ! 272: if (dp->d_secpercyl != dp->d_nsectors * dp->d_ntracks) ! 273: printf("sc#%d:", dp->d_secpercyl); ! 274: if (dp->d_type == DTYPE_SMD && dp->d_flags & D_BADSECT) ! 275: printf("sf:"); ! 276: printf("\\\n\t:dt=%s:", dktypenames[dp->d_type]); ! 277: for (part = NDDATA - 1; part >= 0; part--) ! 278: if (dp->d_drivedata[part]) ! 279: break; ! 280: for (j = 0; j <= part; j++) ! 281: printf("d%d#%d:", j, dp->d_drivedata[j]); ! 282: printf("\\\n"); ! 283: for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++) ! 284: if (defpart[def][part] != 0) ! 285: nparts++; ! 286: for (part = PART('a'); part < NPARTITIONS; part++) { ! 287: if (defpart[def][part] == 0) ! 288: continue; ! 289: printf("\t:p%c#%d:", 'a' + part, defpart[def][part]); ! 290: printf("o%c#%d:b%c#%d:f%c#%d:", ! 291: 'a' + part, spc * startcyl[part], ! 292: 'a' + part, ! 293: defparam[part].p_frag * defparam[part].p_fsize, ! 294: 'a' + part, defparam[part].p_fsize); ! 295: if (defparam[part].p_fstype == FS_SWAP) ! 296: printf("t%c=swap:", 'a' + part); ! 297: nparts--; ! 298: printf("%s\n", nparts > 0 ? "\\" : ""); ! 299: } ! 300: #ifdef for_now ! 301: defpart[def][PART('c')] -= badsecttable; ! 302: part = PART('c'); ! 303: printf("#\t:p%c#%d:", 'a' + part, defpart[def][part]); ! 304: printf("o%c#%d:b%c#%d:f%c#%d:\n", ! 305: 'a' + part, spc * startcyl[part], ! 306: 'a' + part, ! 307: defparam[part].p_frag * defparam[part].p_fsize, ! 308: 'a' + part, defparam[part].p_fsize); ! 309: #endif ! 310: exit(0); ! 311: } ! 312: printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n", ! 313: dp->d_typename, dp->d_nsectors, dp->d_ntracks, ! 314: dp->d_ncylinders); ! 315: printf("\n Partition\t Size\t Offset\t Range\n"); ! 316: for (part = PART('a'); part < NPARTITIONS; part++) { ! 317: printf("\t%c\t", 'a' + part); ! 318: if (numcyls[part] == 0) { ! 319: printf(" unused\n"); ! 320: continue; ! 321: } ! 322: printf("%7d\t%7d\t%4d - %d%s\n", ! 323: defpart[def][part], startcyl[part] * spc, ! 324: startcyl[part], startcyl[part] + numcyls[part] - 1, ! 325: defpart[def][part] % spc ? "*" : ""); ! 326: } ! 327: } ! 328: ! 329: struct disklabel disk; ! 330: ! 331: struct field { ! 332: char *f_name; ! 333: char *f_defaults; ! 334: u_long *f_location; ! 335: } fields[] = { ! 336: { "sector size", "512", &disk.d_secsize }, ! 337: { "#sectors/track", 0, &disk.d_nsectors }, ! 338: { "#tracks/cylinder", 0, &disk.d_ntracks }, ! 339: { "#cylinders", 0, &disk.d_ncylinders }, ! 340: { 0, 0, 0 }, ! 341: }; ! 342: ! 343: struct disklabel * ! 344: promptfordisk(name) ! 345: char *name; ! 346: { ! 347: register struct disklabel *dp = &disk; ! 348: register struct field *fp; ! 349: register i; ! 350: char buf[BUFSIZ], **tp, *cp, *gets(); ! 351: ! 352: strncpy(dp->d_typename, name, sizeof(dp->d_typename)); ! 353: fprintf(stderr, ! 354: "%s: unknown disk type, want to supply parameters (y/n)? ", ! 355: name); ! 356: (void) gets(buf); ! 357: if (*buf != 'y') ! 358: return ((struct disklabel *)0); ! 359: for (;;) { ! 360: fprintf(stderr, "Disk/controller type (%s)? ", dktypenames[1]); ! 361: (void) gets(buf); ! 362: if (buf[0] == 0) ! 363: dp->d_type = 1; ! 364: else ! 365: dp->d_type = gettype(buf, dktypenames); ! 366: if (dp->d_type >= 0) ! 367: break; ! 368: fprintf(stderr, "%s: unrecognized controller type\n", buf); ! 369: fprintf(stderr, "use one of:\n", buf); ! 370: for (tp = dktypenames; *tp; tp++) ! 371: if (index(*tp, ' ') == 0) ! 372: fprintf(stderr, "\t%s\n", *tp); ! 373: } ! 374: gettype: ! 375: dp->d_flags = 0; ! 376: fprintf(stderr, "type (winchester|removable|simulated)? "); ! 377: (void) gets(buf); ! 378: if (strcmp(buf, "removable") == 0) ! 379: dp->d_flags = D_REMOVABLE; ! 380: else if (strcmp(buf, "simulated") == 0) ! 381: dp->d_flags = D_RAMDISK; ! 382: else if (strcmp(buf, "winchester")) { ! 383: fprintf(stderr, "%s: bad disk type\n", buf); ! 384: goto gettype; ! 385: } ! 386: strncpy(dp->d_typename, buf, sizeof(dp->d_typename)); ! 387: fprintf(stderr, "(type <cr> to get default value, if only one)\n"); ! 388: if (dp->d_type == DTYPE_SMD) ! 389: fprintf(stderr, "Do %ss support bad144 bad block forwarding (yes)? ", ! 390: dp->d_typename); ! 391: (void) gets(buf); ! 392: if (*buf != 'n') ! 393: dp->d_flags |= D_BADSECT; ! 394: for (fp = fields; fp->f_name != NULL; fp++) { ! 395: again: ! 396: fprintf(stderr, "%s ", fp->f_name); ! 397: if (fp->f_defaults != NULL) ! 398: fprintf(stderr, "(%s)", fp->f_defaults); ! 399: fprintf(stderr, "? "); ! 400: cp = gets(buf); ! 401: if (*cp == '\0') { ! 402: if (fp->f_defaults == NULL) { ! 403: fprintf(stderr, "no default value\n"); ! 404: goto again; ! 405: } ! 406: cp = fp->f_defaults; ! 407: } ! 408: *fp->f_location = atol(cp); ! 409: if (*fp->f_location == 0) { ! 410: fprintf(stderr, "%s: bad value\n", cp); ! 411: goto again; ! 412: } ! 413: } ! 414: fprintf(stderr, "sectors/cylinder (%d)? ", ! 415: dp->d_nsectors * dp->d_ntracks); ! 416: (void) gets(buf); ! 417: if (buf[0] == 0) ! 418: dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks; ! 419: else ! 420: dp->d_secpercyl = atol(buf); ! 421: fprintf(stderr, "Drive-type-specific parameters, <cr> to terminate:\n"); ! 422: for (i = 0; i < NDDATA; i++) { ! 423: fprintf(stderr, "d%d? ", i); ! 424: (void) gets(buf); ! 425: if (buf[0] == 0) ! 426: break; ! 427: dp->d_drivedata[i] = atol(buf); ! 428: } ! 429: return (dp); ! 430: } ! 431: ! 432: gettype(t, names) ! 433: char *t; ! 434: char **names; ! 435: { ! 436: register char **nm; ! 437: ! 438: for (nm = names; *nm; nm++) ! 439: if (ustrcmp(t, *nm) == 0) ! 440: return (nm - names); ! 441: if (isdigit(*t)) ! 442: return (atoi(t)); ! 443: return (-1); ! 444: } ! 445: ! 446: ustrcmp(s1, s2) ! 447: register char *s1, *s2; ! 448: { ! 449: #define lower(c) (islower(c) ? (c) : tolower(c)) ! 450: ! 451: for (; *s1; s1++, s2++) { ! 452: if (*s1 == *s2) ! 453: continue; ! 454: if (isalpha(*s1) && isalpha(*s2) && ! 455: lower(*s1) == lower(*s2)) ! 456: continue; ! 457: return (*s2 - *s1); ! 458: } ! 459: return (0); ! 460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.