|
|
1.1 ! root 1: %union { ! 2: char *str; ! 3: int val; ! 4: struct file_list *file; ! 5: struct idlst *lst; ! 6: } ! 7: ! 8: %token AND ! 9: %token ANY ! 10: %token ARGS ! 11: %token AT ! 12: %token COMMA ! 13: %token CONFIG ! 14: %token CONTROLLER ! 15: %token CPU ! 16: %token CSR ! 17: %token DEVICE ! 18: %token DISK ! 19: %token DRIVE ! 20: %token DST ! 21: %token DUMPS ! 22: %token EQUALS ! 23: %token FLAGS ! 24: %token HZ ! 25: %token IDENT ! 26: %token MACHINE ! 27: %token MAJOR ! 28: %token MASTER ! 29: %token MAXUSERS ! 30: %token MINOR ! 31: %token MINUS ! 32: %token NEXUS ! 33: %token ON ! 34: %token OPTIONS ! 35: %token MAKEOPTIONS ! 36: %token PRIORITY ! 37: %token PSEUDO_DEVICE ! 38: %token ROOT ! 39: %token SEMICOLON ! 40: %token SIZE ! 41: %token SLAVE ! 42: %token SWAP ! 43: %token TIMEZONE ! 44: %token TRACE ! 45: %token VECTOR ! 46: ! 47: %token <str> ID ! 48: %token <val> NUMBER ! 49: %token <val> FPNUMBER ! 50: ! 51: %type <str> Save_id ! 52: %type <str> Opt_value ! 53: %type <str> Dev ! 54: %type <lst> Id_list ! 55: %type <val> optional_size ! 56: %type <str> device_name ! 57: %type <val> major_minor ! 58: %type <val> arg_device_spec ! 59: %type <val> root_device_spec ! 60: %type <val> dump_device_spec ! 61: %type <file> swap_device_spec ! 62: ! 63: %{ ! 64: ! 65: /* ! 66: * Copyright (c) 1988 Regents of the University of California. ! 67: * All rights reserved. ! 68: * ! 69: * Redistribution and use in source and binary forms are permitted provided ! 70: * that: (1) source distributions retain this entire copyright notice and ! 71: * comment, and (2) distributions including binaries display the following ! 72: * acknowledgement: ``This product includes software developed by the ! 73: * University of California, Berkeley and its contributors'' in the ! 74: * documentation or other materials provided with the distribution and in ! 75: * all advertising materials mentioning features or use of this software. ! 76: * Neither the name of the University nor the names of its contributors may ! 77: * be used to endorse or promote products derived from this software without ! 78: * specific prior written permission. ! 79: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 80: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 81: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 82: * ! 83: * @(#)config.y 5.10 (Berkeley) 6/1/90 ! 84: */ ! 85: ! 86: #include "config.h" ! 87: #include <ctype.h> ! 88: #include <stdio.h> ! 89: ! 90: struct device cur; ! 91: struct device *curp = 0; ! 92: char *temp_id; ! 93: char *val_id; ! 94: char *malloc(); ! 95: ! 96: %} ! 97: %% ! 98: Configuration: ! 99: Many_specs ! 100: = { verifysystemspecs(); } ! 101: ; ! 102: ! 103: Many_specs: ! 104: Many_specs Spec ! 105: | ! 106: /* lambda */ ! 107: ; ! 108: ! 109: Spec: ! 110: Device_spec SEMICOLON ! 111: = { newdev(&cur); } | ! 112: Config_spec SEMICOLON ! 113: | ! 114: TRACE SEMICOLON ! 115: = { do_trace = !do_trace; } | ! 116: SEMICOLON ! 117: | ! 118: error SEMICOLON ! 119: ; ! 120: ! 121: Config_spec: ! 122: MACHINE Save_id ! 123: = { ! 124: if (!strcmp($2, "vax")) { ! 125: machine = MACHINE_VAX; ! 126: machinename = "vax"; ! 127: } else if (!strcmp($2, "tahoe")) { ! 128: machine = MACHINE_TAHOE; ! 129: machinename = "tahoe"; ! 130: } else if (!strcmp($2, "hp300")) { ! 131: machine = MACHINE_HP300; ! 132: machinename = "hp300"; ! 133: } else ! 134: yyerror("Unknown machine type"); ! 135: } | ! 136: CPU Save_id ! 137: = { ! 138: struct cputype *cp = ! 139: (struct cputype *)malloc(sizeof (struct cputype)); ! 140: cp->cpu_name = ns($2); ! 141: cp->cpu_next = cputype; ! 142: cputype = cp; ! 143: free(temp_id); ! 144: } | ! 145: OPTIONS Opt_list ! 146: | ! 147: MAKEOPTIONS Mkopt_list ! 148: | ! 149: IDENT ID ! 150: = { ident = ns($2); } | ! 151: System_spec ! 152: | ! 153: HZ NUMBER ! 154: = { yyerror("HZ specification obsolete; delete"); } | ! 155: TIMEZONE NUMBER ! 156: = { timezone = 60 * $2; check_tz(); } | ! 157: TIMEZONE NUMBER DST NUMBER ! 158: = { timezone = 60 * $2; dst = $4; check_tz(); } | ! 159: TIMEZONE NUMBER DST ! 160: = { timezone = 60 * $2; dst = 1; check_tz(); } | ! 161: TIMEZONE FPNUMBER ! 162: = { timezone = $2; check_tz(); } | ! 163: TIMEZONE FPNUMBER DST NUMBER ! 164: = { timezone = $2; dst = $4; check_tz(); } | ! 165: TIMEZONE FPNUMBER DST ! 166: = { timezone = $2; dst = 1; check_tz(); } | ! 167: TIMEZONE MINUS NUMBER ! 168: = { timezone = -60 * $3; check_tz(); } | ! 169: TIMEZONE MINUS NUMBER DST NUMBER ! 170: = { timezone = -60 * $3; dst = $5; check_tz(); } | ! 171: TIMEZONE MINUS NUMBER DST ! 172: = { timezone = -60 * $3; dst = 1; check_tz(); } | ! 173: TIMEZONE MINUS FPNUMBER ! 174: = { timezone = -$3; check_tz(); } | ! 175: TIMEZONE MINUS FPNUMBER DST NUMBER ! 176: = { timezone = -$3; dst = $5; check_tz(); } | ! 177: TIMEZONE MINUS FPNUMBER DST ! 178: = { timezone = -$3; dst = 1; check_tz(); } | ! 179: MAXUSERS NUMBER ! 180: = { maxusers = $2; }; ! 181: ! 182: System_spec: ! 183: System_id System_parameter_list ! 184: = { checksystemspec(*confp); } ! 185: ; ! 186: ! 187: System_id: ! 188: CONFIG Save_id ! 189: = { mkconf($2); } ! 190: ; ! 191: ! 192: System_parameter_list: ! 193: System_parameter_list System_parameter ! 194: | System_parameter ! 195: ; ! 196: ! 197: System_parameter: ! 198: swap_spec ! 199: | root_spec ! 200: | dump_spec ! 201: | arg_spec ! 202: ; ! 203: ! 204: swap_spec: ! 205: SWAP optional_on swap_device_list ! 206: ; ! 207: ! 208: swap_device_list: ! 209: swap_device_list AND swap_device ! 210: | swap_device ! 211: ; ! 212: ! 213: swap_device: ! 214: swap_device_spec optional_size ! 215: = { mkswap(*confp, $1, $2); } ! 216: ; ! 217: ! 218: swap_device_spec: ! 219: device_name ! 220: = { ! 221: struct file_list *fl = newswap(); ! 222: ! 223: if (eq($1, "generic")) ! 224: fl->f_fn = $1; ! 225: else { ! 226: fl->f_swapdev = nametodev($1, 0, 'b'); ! 227: fl->f_fn = devtoname(fl->f_swapdev); ! 228: } ! 229: $$ = fl; ! 230: } ! 231: | major_minor ! 232: = { ! 233: struct file_list *fl = newswap(); ! 234: ! 235: fl->f_swapdev = $1; ! 236: fl->f_fn = devtoname($1); ! 237: $$ = fl; ! 238: } ! 239: ; ! 240: ! 241: root_spec: ! 242: ROOT optional_on root_device_spec ! 243: = { ! 244: struct file_list *fl = *confp; ! 245: ! 246: if (fl && fl->f_rootdev != NODEV) ! 247: yyerror("extraneous root device specification"); ! 248: else ! 249: fl->f_rootdev = $3; ! 250: } ! 251: ; ! 252: ! 253: root_device_spec: ! 254: device_name ! 255: = { $$ = nametodev($1, 0, 'a'); } ! 256: | major_minor ! 257: ; ! 258: ! 259: dump_spec: ! 260: DUMPS optional_on dump_device_spec ! 261: = { ! 262: struct file_list *fl = *confp; ! 263: ! 264: if (fl && fl->f_dumpdev != NODEV) ! 265: yyerror("extraneous dump device specification"); ! 266: else ! 267: fl->f_dumpdev = $3; ! 268: } ! 269: ! 270: ; ! 271: ! 272: dump_device_spec: ! 273: device_name ! 274: = { $$ = nametodev($1, 0, 'b'); } ! 275: | major_minor ! 276: ; ! 277: ! 278: arg_spec: ! 279: ARGS optional_on arg_device_spec ! 280: = { ! 281: struct file_list *fl = *confp; ! 282: ! 283: if (fl && fl->f_argdev != NODEV) ! 284: yyerror("extraneous arg device specification"); ! 285: else ! 286: fl->f_argdev = $3; ! 287: } ! 288: ; ! 289: ! 290: arg_device_spec: ! 291: device_name ! 292: = { $$ = nametodev($1, 0, 'b'); } ! 293: | major_minor ! 294: ; ! 295: ! 296: major_minor: ! 297: MAJOR NUMBER MINOR NUMBER ! 298: = { $$ = makedev($2, $4); } ! 299: ; ! 300: ! 301: optional_on: ! 302: ON ! 303: | /* empty */ ! 304: ; ! 305: ! 306: optional_size: ! 307: SIZE NUMBER ! 308: = { $$ = $2; } ! 309: | /* empty */ ! 310: = { $$ = 0; } ! 311: ; ! 312: ! 313: device_name: ! 314: Save_id ! 315: = { $$ = $1; } ! 316: | Save_id NUMBER ! 317: = { ! 318: char buf[80]; ! 319: ! 320: (void) sprintf(buf, "%s%d", $1, $2); ! 321: $$ = ns(buf); free($1); ! 322: } ! 323: | Save_id NUMBER ID ! 324: = { ! 325: char buf[80]; ! 326: ! 327: (void) sprintf(buf, "%s%d%s", $1, $2, $3); ! 328: $$ = ns(buf); free($1); ! 329: } ! 330: ; ! 331: ! 332: Opt_list: ! 333: Opt_list COMMA Option ! 334: | ! 335: Option ! 336: ; ! 337: ! 338: Option: ! 339: Save_id ! 340: = { ! 341: struct opt *op = (struct opt *)malloc(sizeof (struct opt)); ! 342: op->op_name = ns($1); ! 343: op->op_next = opt; ! 344: op->op_value = 0; ! 345: opt = op; ! 346: free(temp_id); ! 347: } | ! 348: Save_id EQUALS Opt_value ! 349: = { ! 350: struct opt *op = (struct opt *)malloc(sizeof (struct opt)); ! 351: op->op_name = ns($1); ! 352: op->op_next = opt; ! 353: op->op_value = ns($3); ! 354: opt = op; ! 355: free(temp_id); ! 356: free(val_id); ! 357: } ; ! 358: ! 359: Opt_value: ! 360: ID ! 361: = { $$ = val_id = ns($1); } | ! 362: NUMBER ! 363: = { ! 364: char nb[16]; ! 365: (void) sprintf(nb, "%d", $1); ! 366: $$ = val_id = ns(nb); ! 367: } ; ! 368: ! 369: ! 370: Save_id: ! 371: ID ! 372: = { $$ = temp_id = ns($1); } ! 373: ; ! 374: ! 375: Mkopt_list: ! 376: Mkopt_list COMMA Mkoption ! 377: | ! 378: Mkoption ! 379: ; ! 380: ! 381: Mkoption: ! 382: Save_id EQUALS Opt_value ! 383: = { ! 384: struct opt *op = (struct opt *)malloc(sizeof (struct opt)); ! 385: op->op_name = ns($1); ! 386: op->op_next = mkopt; ! 387: op->op_value = ns($3); ! 388: mkopt = op; ! 389: free(temp_id); ! 390: free(val_id); ! 391: } ; ! 392: ! 393: Dev: ! 394: ID ! 395: = { $$ = ns($1); } ! 396: ; ! 397: ! 398: Device_spec: ! 399: DEVICE Dev_name Dev_info Int_spec ! 400: = { cur.d_type = DEVICE; } | ! 401: MASTER Dev_name Dev_info Int_spec ! 402: = { cur.d_type = MASTER; } | ! 403: DISK Dev_name Dev_info Int_spec ! 404: = { cur.d_dk = 1; cur.d_type = DEVICE; } | ! 405: CONTROLLER Dev_name Dev_info Int_spec ! 406: = { cur.d_type = CONTROLLER; } | ! 407: PSEUDO_DEVICE Init_dev Dev ! 408: = { ! 409: cur.d_name = $3; ! 410: cur.d_type = PSEUDO_DEVICE; ! 411: } | ! 412: PSEUDO_DEVICE Init_dev Dev NUMBER ! 413: = { ! 414: cur.d_name = $3; ! 415: cur.d_type = PSEUDO_DEVICE; ! 416: cur.d_slave = $4; ! 417: }; ! 418: ! 419: Dev_name: ! 420: Init_dev Dev NUMBER ! 421: = { ! 422: cur.d_name = $2; ! 423: if (eq($2, "mba")) ! 424: seen_mba = 1; ! 425: else if (eq($2, "uba")) ! 426: seen_uba = 1; ! 427: else if (eq($2, "vba")) ! 428: seen_vba = 1; ! 429: cur.d_unit = $3; ! 430: }; ! 431: ! 432: Init_dev: ! 433: /* lambda */ ! 434: = { init_dev(&cur); }; ! 435: ! 436: Dev_info: ! 437: Con_info Info_list ! 438: | ! 439: /* lambda */ ! 440: ; ! 441: ! 442: Con_info: ! 443: AT Dev NUMBER ! 444: = { ! 445: if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { ! 446: (void) sprintf(errbuf, ! 447: "%s must be connected to a nexus", cur.d_name); ! 448: yyerror(errbuf); ! 449: } ! 450: cur.d_conn = connect($2, $3); ! 451: } | ! 452: AT NEXUS NUMBER ! 453: = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; ! 454: ! 455: Info_list: ! 456: Info_list Info ! 457: | ! 458: /* lambda */ ! 459: ; ! 460: ! 461: Info: ! 462: CSR NUMBER ! 463: = { cur.d_addr = $2; } | ! 464: DRIVE NUMBER ! 465: = { cur.d_drive = $2; } | ! 466: SLAVE NUMBER ! 467: = { ! 468: if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && ! 469: cur.d_conn->d_type == MASTER) ! 470: cur.d_slave = $2; ! 471: else ! 472: yyerror("can't specify slave--not to master"); ! 473: } | ! 474: FLAGS NUMBER ! 475: = { cur.d_flags = $2; }; ! 476: ! 477: Int_spec: ! 478: VECTOR Id_list ! 479: = { cur.d_vec = $2; } | ! 480: PRIORITY NUMBER ! 481: = { cur.d_pri = $2; } | ! 482: /* lambda */ ! 483: ; ! 484: ! 485: Id_list: ! 486: Save_id ! 487: = { ! 488: struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); ! 489: a->id = $1; a->id_next = 0; $$ = a; ! 490: } | ! 491: Save_id Id_list = ! 492: { ! 493: struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); ! 494: a->id = $1; a->id_next = $2; $$ = a; ! 495: }; ! 496: ! 497: %% ! 498: ! 499: yyerror(s) ! 500: char *s; ! 501: { ! 502: ! 503: fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); ! 504: } ! 505: ! 506: /* ! 507: * return the passed string in a new space ! 508: */ ! 509: char * ! 510: ns(str) ! 511: register char *str; ! 512: { ! 513: register char *cp; ! 514: ! 515: cp = malloc((unsigned)(strlen(str)+1)); ! 516: (void) strcpy(cp, str); ! 517: return (cp); ! 518: } ! 519: ! 520: /* ! 521: * add a device to the list of devices ! 522: */ ! 523: newdev(dp) ! 524: register struct device *dp; ! 525: { ! 526: register struct device *np; ! 527: ! 528: np = (struct device *) malloc(sizeof *np); ! 529: *np = *dp; ! 530: np->d_next = 0; ! 531: if (curp == 0) ! 532: dtab = np; ! 533: else ! 534: curp->d_next = np; ! 535: curp = np; ! 536: } ! 537: ! 538: /* ! 539: * note that a configuration should be made ! 540: */ ! 541: mkconf(sysname) ! 542: char *sysname; ! 543: { ! 544: register struct file_list *fl, **flp; ! 545: ! 546: fl = (struct file_list *) malloc(sizeof *fl); ! 547: fl->f_type = SYSTEMSPEC; ! 548: fl->f_needs = sysname; ! 549: fl->f_rootdev = NODEV; ! 550: fl->f_argdev = NODEV; ! 551: fl->f_dumpdev = NODEV; ! 552: fl->f_fn = 0; ! 553: fl->f_next = 0; ! 554: for (flp = confp; *flp; flp = &(*flp)->f_next) ! 555: ; ! 556: *flp = fl; ! 557: confp = flp; ! 558: } ! 559: ! 560: struct file_list * ! 561: newswap() ! 562: { ! 563: struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); ! 564: ! 565: fl->f_type = SWAPSPEC; ! 566: fl->f_next = 0; ! 567: fl->f_swapdev = NODEV; ! 568: fl->f_swapsize = 0; ! 569: fl->f_needs = 0; ! 570: fl->f_fn = 0; ! 571: return (fl); ! 572: } ! 573: ! 574: /* ! 575: * Add a swap device to the system's configuration ! 576: */ ! 577: mkswap(system, fl, size) ! 578: struct file_list *system, *fl; ! 579: int size; ! 580: { ! 581: register struct file_list **flp; ! 582: char name[80]; ! 583: ! 584: if (system == 0 || system->f_type != SYSTEMSPEC) { ! 585: yyerror("\"swap\" spec precedes \"config\" specification"); ! 586: return; ! 587: } ! 588: if (size < 0) { ! 589: yyerror("illegal swap partition size"); ! 590: return; ! 591: } ! 592: /* ! 593: * Append swap description to the end of the list. ! 594: */ ! 595: flp = &system->f_next; ! 596: for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) ! 597: ; ! 598: fl->f_next = *flp; ! 599: *flp = fl; ! 600: fl->f_swapsize = size; ! 601: /* ! 602: * If first swap device for this system, ! 603: * set up f_fn field to insure swap ! 604: * files are created with unique names. ! 605: */ ! 606: if (system->f_fn) ! 607: return; ! 608: if (eq(fl->f_fn, "generic")) ! 609: system->f_fn = ns(fl->f_fn); ! 610: else ! 611: system->f_fn = ns(system->f_needs); ! 612: } ! 613: ! 614: /* ! 615: * find the pointer to connect to the given device and number. ! 616: * returns 0 if no such device and prints an error message ! 617: */ ! 618: struct device * ! 619: connect(dev, num) ! 620: register char *dev; ! 621: register int num; ! 622: { ! 623: register struct device *dp; ! 624: struct device *huhcon(); ! 625: ! 626: if (num == QUES) ! 627: return (huhcon(dev)); ! 628: for (dp = dtab; dp != 0; dp = dp->d_next) { ! 629: if ((num != dp->d_unit) || !eq(dev, dp->d_name)) ! 630: continue; ! 631: if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { ! 632: (void) sprintf(errbuf, ! 633: "%s connected to non-controller", dev); ! 634: yyerror(errbuf); ! 635: return (0); ! 636: } ! 637: return (dp); ! 638: } ! 639: (void) sprintf(errbuf, "%s %d not defined", dev, num); ! 640: yyerror(errbuf); ! 641: return (0); ! 642: } ! 643: ! 644: /* ! 645: * connect to an unspecific thing ! 646: */ ! 647: struct device * ! 648: huhcon(dev) ! 649: register char *dev; ! 650: { ! 651: register struct device *dp, *dcp; ! 652: struct device rdev; ! 653: int oldtype; ! 654: ! 655: /* ! 656: * First make certain that there are some of these to wildcard on ! 657: */ ! 658: for (dp = dtab; dp != 0; dp = dp->d_next) ! 659: if (eq(dp->d_name, dev)) ! 660: break; ! 661: if (dp == 0) { ! 662: (void) sprintf(errbuf, "no %s's to wildcard", dev); ! 663: yyerror(errbuf); ! 664: return (0); ! 665: } ! 666: oldtype = dp->d_type; ! 667: dcp = dp->d_conn; ! 668: /* ! 669: * Now see if there is already a wildcard entry for this device ! 670: * (e.g. Search for a "uba ?") ! 671: */ ! 672: for (; dp != 0; dp = dp->d_next) ! 673: if (eq(dev, dp->d_name) && dp->d_unit == -1) ! 674: break; ! 675: /* ! 676: * If there isn't, make one because everything needs to be connected ! 677: * to something. ! 678: */ ! 679: if (dp == 0) { ! 680: dp = &rdev; ! 681: init_dev(dp); ! 682: dp->d_unit = QUES; ! 683: dp->d_name = ns(dev); ! 684: dp->d_type = oldtype; ! 685: newdev(dp); ! 686: dp = curp; ! 687: /* ! 688: * Connect it to the same thing that other similar things are ! 689: * connected to, but make sure it is a wildcard unit ! 690: * (e.g. up connected to sc ?, here we make connect sc? to a ! 691: * uba?). If other things like this are on the NEXUS or ! 692: * if they aren't connected to anything, then make the same ! 693: * connection, else call ourself to connect to another ! 694: * unspecific device. ! 695: */ ! 696: if (dcp == TO_NEXUS || dcp == 0) ! 697: dp->d_conn = dcp; ! 698: else ! 699: dp->d_conn = connect(dcp->d_name, QUES); ! 700: } ! 701: return (dp); ! 702: } ! 703: ! 704: init_dev(dp) ! 705: register struct device *dp; ! 706: { ! 707: ! 708: dp->d_name = "OHNO!!!"; ! 709: dp->d_type = DEVICE; ! 710: dp->d_conn = 0; ! 711: dp->d_vec = 0; ! 712: dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0; ! 713: dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; ! 714: } ! 715: ! 716: /* ! 717: * make certain that this is a reasonable type of thing to connect to a nexus ! 718: */ ! 719: check_nexus(dev, num) ! 720: register struct device *dev; ! 721: int num; ! 722: { ! 723: ! 724: switch (machine) { ! 725: ! 726: case MACHINE_VAX: ! 727: if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && ! 728: !eq(dev->d_name, "bi")) ! 729: yyerror("only uba's, mba's, and bi's should be connected to the nexus"); ! 730: if (num != QUES) ! 731: yyerror("can't give specific nexus numbers"); ! 732: break; ! 733: ! 734: case MACHINE_TAHOE: ! 735: if (!eq(dev->d_name, "vba")) ! 736: yyerror("only vba's should be connected to the nexus"); ! 737: break; ! 738: ! 739: case MACHINE_HP300: ! 740: if (num != QUES) ! 741: dev->d_addr = num; ! 742: break; ! 743: } ! 744: } ! 745: ! 746: /* ! 747: * Check the timezone to make certain it is sensible ! 748: */ ! 749: ! 750: check_tz() ! 751: { ! 752: if (abs(timezone) > 12 * 60) ! 753: yyerror("timezone is unreasonable"); ! 754: else ! 755: hadtz = 1; ! 756: } ! 757: ! 758: /* ! 759: * Check system specification and apply defaulting ! 760: * rules on root, argument, dump, and swap devices. ! 761: */ ! 762: checksystemspec(fl) ! 763: register struct file_list *fl; ! 764: { ! 765: char buf[BUFSIZ]; ! 766: register struct file_list *swap; ! 767: int generic; ! 768: ! 769: if (fl == 0 || fl->f_type != SYSTEMSPEC) { ! 770: yyerror("internal error, bad system specification"); ! 771: exit(1); ! 772: } ! 773: swap = fl->f_next; ! 774: generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); ! 775: if (fl->f_rootdev == NODEV && !generic) { ! 776: yyerror("no root device specified"); ! 777: exit(1); ! 778: } ! 779: /* ! 780: * Default swap area to be in 'b' partition of root's ! 781: * device. If root specified to be other than on 'a' ! 782: * partition, give warning, something probably amiss. ! 783: */ ! 784: if (swap == 0 || swap->f_type != SWAPSPEC) { ! 785: dev_t dev; ! 786: ! 787: swap = newswap(); ! 788: dev = fl->f_rootdev; ! 789: if (minor(dev) & 07) { ! 790: (void) sprintf(buf, ! 791: "Warning, swap defaulted to 'b' partition with root on '%c' partition", ! 792: (minor(dev) & 07) + 'a'); ! 793: yyerror(buf); ! 794: } ! 795: swap->f_swapdev = ! 796: makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a')); ! 797: swap->f_fn = devtoname(swap->f_swapdev); ! 798: mkswap(fl, swap, 0); ! 799: } ! 800: /* ! 801: * Make sure a generic swap isn't specified, along with ! 802: * other stuff (user must really be confused). ! 803: */ ! 804: if (generic) { ! 805: if (fl->f_rootdev != NODEV) ! 806: yyerror("root device specified with generic swap"); ! 807: if (fl->f_argdev != NODEV) ! 808: yyerror("arg device specified with generic swap"); ! 809: if (fl->f_dumpdev != NODEV) ! 810: yyerror("dump device specified with generic swap"); ! 811: return; ! 812: } ! 813: /* ! 814: * Default argument device and check for oddball arrangements. ! 815: */ ! 816: if (fl->f_argdev == NODEV) ! 817: fl->f_argdev = swap->f_swapdev; ! 818: if (fl->f_argdev != swap->f_swapdev) ! 819: yyerror("Warning, arg device different than primary swap"); ! 820: /* ! 821: * Default dump device and warn if place is not a ! 822: * swap area or the argument device partition. ! 823: */ ! 824: if (fl->f_dumpdev == NODEV) ! 825: fl->f_dumpdev = swap->f_swapdev; ! 826: if (fl->f_dumpdev != swap->f_swapdev && fl->f_dumpdev != fl->f_argdev) { ! 827: struct file_list *p = swap->f_next; ! 828: ! 829: for (; p && p->f_type == SWAPSPEC; p = p->f_next) ! 830: if (fl->f_dumpdev == p->f_swapdev) ! 831: return; ! 832: (void) sprintf(buf, "Warning, orphaned dump device, %s", ! 833: "do you know what you're doing"); ! 834: yyerror(buf); ! 835: } ! 836: } ! 837: ! 838: /* ! 839: * Verify all devices specified in the system specification ! 840: * are present in the device specifications. ! 841: */ ! 842: verifysystemspecs() ! 843: { ! 844: register struct file_list *fl; ! 845: dev_t checked[50], *verifyswap(); ! 846: register dev_t *pchecked = checked; ! 847: ! 848: for (fl = conf_list; fl; fl = fl->f_next) { ! 849: if (fl->f_type != SYSTEMSPEC) ! 850: continue; ! 851: if (!finddev(fl->f_rootdev)) ! 852: deverror(fl->f_needs, "root"); ! 853: *pchecked++ = fl->f_rootdev; ! 854: pchecked = verifyswap(fl->f_next, checked, pchecked); ! 855: #define samedev(dev1, dev2) \ ! 856: ((minor(dev1) &~ 07) != (minor(dev2) &~ 07)) ! 857: if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { ! 858: if (!finddev(fl->f_dumpdev)) ! 859: deverror(fl->f_needs, "dump"); ! 860: *pchecked++ = fl->f_dumpdev; ! 861: } ! 862: if (!alreadychecked(fl->f_argdev, checked, pchecked)) { ! 863: if (!finddev(fl->f_argdev)) ! 864: deverror(fl->f_needs, "arg"); ! 865: *pchecked++ = fl->f_argdev; ! 866: } ! 867: } ! 868: } ! 869: ! 870: /* ! 871: * Do as above, but for swap devices. ! 872: */ ! 873: dev_t * ! 874: verifyswap(fl, checked, pchecked) ! 875: register struct file_list *fl; ! 876: dev_t checked[]; ! 877: register dev_t *pchecked; ! 878: { ! 879: ! 880: for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { ! 881: if (eq(fl->f_fn, "generic")) ! 882: continue; ! 883: if (alreadychecked(fl->f_swapdev, checked, pchecked)) ! 884: continue; ! 885: if (!finddev(fl->f_swapdev)) ! 886: fprintf(stderr, ! 887: "config: swap device %s not configured", fl->f_fn); ! 888: *pchecked++ = fl->f_swapdev; ! 889: } ! 890: return (pchecked); ! 891: } ! 892: ! 893: /* ! 894: * Has a device already been checked ! 895: * for it's existence in the configuration? ! 896: */ ! 897: alreadychecked(dev, list, last) ! 898: dev_t dev, list[]; ! 899: register dev_t *last; ! 900: { ! 901: register dev_t *p; ! 902: ! 903: for (p = list; p < last; p++) ! 904: if (samedev(*p, dev)) ! 905: return (1); ! 906: return (0); ! 907: } ! 908: ! 909: deverror(systemname, devtype) ! 910: char *systemname, *devtype; ! 911: { ! 912: ! 913: fprintf(stderr, "config: %s: %s device not configured\n", ! 914: systemname, devtype); ! 915: } ! 916: ! 917: /* ! 918: * Look for the device in the list of ! 919: * configured hardware devices. Must ! 920: * take into account stuff wildcarded. ! 921: */ ! 922: /*ARGSUSED*/ ! 923: finddev(dev) ! 924: dev_t dev; ! 925: { ! 926: ! 927: /* punt on this right now */ ! 928: return (1); ! 929: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.