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