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