1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* ONC_PLUS EXTRACT START */ 22 /* 23 * Copyright (c) 1982, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 /* ONC_PLUS EXTRACT END */ 26 27 /* 28 * Configure root, swap and dump devices. 29 */ 30 31 #include <sys/types.h> 32 #include <sys/param.h> 33 #include <sys/sysmacros.h> 34 #include <sys/signal.h> 35 #include <sys/cred.h> 36 #include <sys/proc.h> 37 #include <sys/user.h> 38 #include <sys/conf.h> 39 #include <sys/buf.h> 40 #include <sys/systm.h> 41 #include <sys/vm.h> 42 #include <sys/reboot.h> 43 #include <sys/file.h> 44 #include <sys/vfs.h> 45 #include <sys/vnode.h> 46 #include <sys/errno.h> 47 #include <sys/kmem.h> 48 #include <sys/uio.h> 49 #include <sys/open.h> 50 #include <sys/mount.h> 51 #include <sys/kobj.h> 52 #include <sys/bootconf.h> 53 #include <sys/sysconf.h> 54 #include <sys/modctl.h> 55 #include <sys/autoconf.h> 56 #include <sys/debug.h> 57 #include <sys/fs/snode.h> 58 #include <fs/fs_subr.h> 59 #include <sys/socket.h> 60 #include <net/if.h> 61 62 #include <sys/mkdev.h> 63 #include <sys/cmn_err.h> 64 #include <sys/console.h> 65 66 #include <sys/conf.h> 67 #include <sys/ddi.h> 68 #include <sys/sunddi.h> 69 #include <sys/hwconf.h> 70 #include <sys/dc_ki.h> 71 #include <sys/promif.h> 72 #include <sys/bootprops.h> 73 74 /* 75 * Local routines 76 */ 77 static int preload_module(struct sysparam *, void *); 78 static struct vfssw *getfstype(char *, char *, size_t); 79 static int getphysdev(char *, char *, size_t); 80 static int load_bootpath_drivers(char *bootpath); 81 static int load_boot_driver(char *drv); 82 static int load_boot_platform_modules(char *drv); 83 static dev_info_t *path_to_devinfo(char *path); 84 static boolean_t netboot_over_ib(char *bootpath); 85 static boolean_t netboot_over_iscsi(void); 86 87 /* 88 * Module linkage information for the kernel. 89 */ 90 static struct modlmisc modlmisc = { 91 &mod_miscops, "root and swap configuration" 92 }; 93 94 static struct modlinkage modlinkage = { 95 MODREV_1, (void *)&modlmisc, NULL 96 }; 97 98 int 99 _init(void) 100 { 101 return (mod_install(&modlinkage)); 102 } 103 104 int 105 _fini(void) 106 { 107 return (mod_remove(&modlinkage)); 108 } 109 110 int 111 _info(struct modinfo *modinfop) 112 { 113 return (mod_info(&modlinkage, modinfop)); 114 } 115 116 extern ib_boot_prop_t *iscsiboot_prop; 117 /* 118 * Configure root file system. 119 */ 120 int 121 rootconf(void) 122 { 123 int error; 124 struct vfssw *vsw; 125 extern void pm_init(void); 126 int ret = -1; 127 BMDPRINTF(("rootconf: fstype %s\n", rootfs.bo_fstype)); 128 BMDPRINTF(("rootconf: name %s\n", rootfs.bo_name)); 129 BMDPRINTF(("rootconf: flags 0x%x\n", rootfs.bo_flags)); 130 BMDPRINTF(("rootconf: obp_bootpath %s\n", obp_bootpath)); 131 132 /* 133 * Install cluster modules that were only loaded during 134 * loadrootmodules(). 135 */ 136 if (error = clboot_rootconf()) 137 return (error); 138 139 if (root_is_svm) { 140 (void) strncpy(rootfs.bo_name, obp_bootpath, BO_MAXOBJNAME); 141 142 BMDPRINTF(("rootconf: svm: rootfs name %s\n", rootfs.bo_name)); 143 BMDPRINTF(("rootconf: svm: svm name %s\n", svm_bootpath)); 144 } 145 146 /* 147 * Run _init on the root filesystem (we already loaded it 148 * but we've been waiting until now to _init it) which will 149 * have the side-effect of running vsw_init() on this vfs. 150 * Because all the nfs filesystems are lumped into one 151 * module we need to special case it. 152 */ 153 if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 154 if (modload("fs", "nfs") == -1) { 155 cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 156 rootfs.bo_fstype); 157 return (ENXIO); 158 } 159 } else { 160 if (modload("fs", rootfs.bo_fstype) == -1) { 161 cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 162 rootfs.bo_fstype); 163 return (ENXIO); 164 } 165 } 166 RLOCK_VFSSW(); 167 vsw = vfs_getvfsswbyname(rootfs.bo_fstype); 168 RUNLOCK_VFSSW(); 169 if (vsw == NULL) { 170 cmn_err(CE_CONT, "Cannot find %s filesystem\n", 171 rootfs.bo_fstype); 172 return (ENXIO); 173 } 174 VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0); 175 VFS_HOLD(rootvfs); 176 177 if (root_is_svm) { 178 rootvfs->vfs_flag |= VFS_RDONLY; 179 } 180 181 /* 182 * This pm-releated call has to occur before root is mounted since we 183 * need to power up all devices. It is placed after VFS_INIT() such 184 * that opening a device via ddi_lyr_ interface just before root has 185 * been mounted would work. 186 */ 187 pm_init(); 188 189 if (netboot && iscsiboot_prop) { 190 cmn_err(CE_WARN, "NFS boot and iSCSI boot" 191 " shouldn't happen in the same time"); 192 return (EINVAL); 193 } 194 195 if (netboot || iscsiboot_prop) { 196 ret = strplumb(); 197 if (ret != 0) { 198 cmn_err(CE_WARN, "Cannot plumb network device %d", ret); 199 return (EFAULT); 200 } 201 } 202 203 if ((ret == 0) && iscsiboot_prop) { 204 ret = modload("drv", "iscsi"); 205 /* -1 indicates fail */ 206 if (ret == -1) { 207 cmn_err(CE_WARN, "Failed to load iscsi module"); 208 iscsi_boot_prop_free(); 209 return (EINVAL); 210 } else { 211 if (!i_ddi_attach_pseudo_node("iscsi")) { 212 cmn_err(CE_WARN, 213 "Failed to attach iscsi driver"); 214 iscsi_boot_prop_free(); 215 return (ENODEV); 216 } 217 } 218 } 219 220 /* 221 * ufs_mountroot() ends up calling getrootdev() 222 * (below) which actually triggers the _init, identify, 223 * probe and attach of the drivers that make up root device 224 * bush; these are also quietly waiting in memory. 225 */ 226 BMDPRINTF(("rootconf: calling VFS_MOUNTROOT %s\n", rootfs.bo_fstype)); 227 228 error = VFS_MOUNTROOT(rootvfs, ROOT_INIT); 229 vfs_unrefvfssw(vsw); 230 rootdev = rootvfs->vfs_dev; 231 232 if (error) 233 cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n", 234 rootfs.bo_name, rootfs.bo_fstype); 235 else 236 cmn_err(CE_CONT, "?root on %s fstype %s\n", 237 rootfs.bo_name, rootfs.bo_fstype); 238 return (error); 239 } 240 241 /* 242 * Remount root on an SVM mirror root device 243 * Only supported on UFS filesystems at present 244 */ 245 int 246 svm_rootconf(void) 247 { 248 int error; 249 extern int ufs_remountroot(struct vfs *vfsp); 250 251 ASSERT(root_is_svm == 1); 252 253 if (strcmp(rootfs.bo_fstype, "ufs") != 0) { 254 cmn_err(CE_CONT, "Mounting root on %s with filesystem " 255 "type %s is not supported\n", 256 rootfs.bo_name, rootfs.bo_fstype); 257 return (EINVAL); 258 } 259 260 (void) strncpy(rootfs.bo_name, svm_bootpath, BO_MAXOBJNAME); 261 262 BMDPRINTF(("svm_rootconf: rootfs %s\n", rootfs.bo_name)); 263 264 error = ufs_remountroot(rootvfs); 265 266 if (error) { 267 cmn_err(CE_CONT, "Cannot remount root on %s fstype %s\n", 268 rootfs.bo_name, rootfs.bo_fstype); 269 } else { 270 cmn_err(CE_CONT, "?root remounted on %s fstype %s\n", 271 rootfs.bo_name, rootfs.bo_fstype); 272 } 273 return (error); 274 } 275 276 /* 277 * Under the assumption that our root file system is on a 278 * disk partition, get the dev_t of the partition in question. 279 * 280 * By now, boot has faithfully loaded all our modules into memory, and 281 * we've taken over resource management. Before we go any further, we 282 * have to fire up the device drivers and stuff we need to mount the 283 * root filesystem. That's what we do here. Fingers crossed. 284 */ 285 dev_t 286 getrootdev(void) 287 { 288 dev_t d; 289 290 d = ddi_pathname_to_dev_t(rootfs.bo_name); 291 if ((d == NODEV) && (iscsiboot_prop != NULL)) { 292 /* Give it another try with the 'disk' path */ 293 get_iscsi_bootpath_phy(rootfs.bo_name); 294 d = ddi_pathname_to_dev_t(rootfs.bo_name); 295 } 296 if (d == NODEV) 297 cmn_err(CE_CONT, "Cannot assemble drivers for root %s\n", 298 rootfs.bo_name); 299 return (d); 300 } 301 302 /* 303 * If booted with ASKNAME, prompt on the console for a filesystem 304 * name and return it. 305 */ 306 void 307 getfsname(char *askfor, char *name, size_t namelen) 308 { 309 if (boothowto & RB_ASKNAME) { 310 printf("%s name: ", askfor); 311 console_gets(name, namelen); 312 } 313 } 314 315 /*ARGSUSED1*/ 316 static int 317 preload_module(struct sysparam *sysp, void *p) 318 { 319 static char *wmesg = "forceload of %s failed"; 320 char *name; 321 322 name = sysp->sys_ptr; 323 BMDPRINTF(("preload_module: %s\n", name)); 324 if (modloadonly(NULL, name) < 0) 325 cmn_err(CE_WARN, wmesg, name); 326 return (0); 327 } 328 329 /* ONC_PLUS EXTRACT START */ 330 /* 331 * We want to load all the modules needed to mount the root filesystem, 332 * so that when we start the ball rolling in 'getrootdev', every module 333 * should already be in memory, just waiting to be init-ed. 334 */ 335 336 int 337 loadrootmodules(void) 338 { 339 struct vfssw *vsw; 340 char *this; 341 char *name; 342 int err; 343 /* ONC_PLUS EXTRACT END */ 344 int i, proplen; 345 extern char *impl_module_list[]; 346 extern char *platform_module_list[]; 347 348 /* Make sure that the PROM's devinfo tree has been created */ 349 ASSERT(ddi_root_node()); 350 351 BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype)); 352 BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name)); 353 BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags)); 354 355 /* 356 * zzz We need to honor what's in rootfs if it's not null. 357 * non-null means use what's there. This way we can 358 * change rootfs with /etc/system AND with tunetool. 359 */ 360 if (root_is_svm) { 361 /* user replaced rootdev, record obp_bootpath */ 362 obp_bootpath[0] = '\0'; 363 (void) getphysdev("root", obp_bootpath, BO_MAXOBJNAME); 364 BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 365 } else { 366 /* 367 * Get the root fstype and root device path from boot. 368 */ 369 rootfs.bo_fstype[0] = '\0'; 370 rootfs.bo_name[0] = '\0'; 371 } 372 373 /* 374 * This lookup will result in modloadonly-ing the root 375 * filesystem module - it gets _init-ed in rootconf() 376 */ 377 if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL) 378 return (ENXIO); /* in case we have no file system types */ 379 380 (void) strcpy(rootfs.bo_fstype, vsw->vsw_name); 381 382 vfs_unrefvfssw(vsw); 383 384 /* 385 * Load the favored drivers of the implementation. 386 * e.g. 'sbus' and possibly 'zs' (even). 387 * 388 * Called whilst boot is still loaded (because boot does 389 * the i/o for us), and DDI services are unavailable. 390 */ 391 BMDPRINTF(("loadrootmodules: impl_module_list\n")); 392 for (i = 0; (this = impl_module_list[i]) != NULL; i++) { 393 if ((err = load_boot_driver(this)) != 0) { 394 cmn_err(CE_WARN, "Cannot load drv/%s", this); 395 return (err); 396 } 397 } 398 /* 399 * Now load the platform modules (if any) 400 */ 401 BMDPRINTF(("loadrootmodules: platform_module_list\n")); 402 for (i = 0; (this = platform_module_list[i]) != NULL; i++) { 403 if ((err = load_boot_platform_modules(this)) != 0) { 404 cmn_err(CE_WARN, "Cannot load drv/%s", this); 405 return (err); 406 } 407 } 408 409 loop: 410 (void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME); 411 /* 412 * Given a physical pathname, load the correct set of driver 413 * modules into memory, including all possible parents. 414 * 415 * NB: The code sets the variable 'name' for error reporting. 416 */ 417 err = 0; 418 BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 419 if (root_is_svm == 0) { 420 BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 421 name = rootfs.bo_name; 422 err = load_bootpath_drivers(rootfs.bo_name); 423 } 424 425 /* 426 * Load driver modules in obp_bootpath, this is always 427 * required for mountroot to succeed. obp_bootpath is 428 * is set if rootdev is set via /etc/system, which is 429 * the case if booting of a SVM/VxVM mirror. 430 */ 431 if ((err == 0) && obp_bootpath[0] != '\0') { 432 BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 433 name = obp_bootpath; 434 err = load_bootpath_drivers(obp_bootpath); 435 } 436 437 if (err != 0) { 438 cmn_err(CE_CONT, "Cannot load drivers for %s\n", name); 439 goto out; 440 } 441 442 /* 443 * Check to see if the booter performed DHCP configuration 444 * ("bootp-response" boot property exists). If so, then before 445 * bootops disappears we need to save the value of this property 446 * such that the userland dhcpagent can adopt the DHCP management 447 * of our primary network interface. 448 */ 449 proplen = BOP_GETPROPLEN(bootops, "bootp-response"); 450 if (proplen > 0) { 451 dhcack = kmem_zalloc(proplen, KM_SLEEP); 452 if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) { 453 cmn_err(CE_WARN, "BOP_GETPROP of " 454 "\"bootp-response\" failed\n"); 455 kmem_free(dhcack, dhcacklen); 456 dhcack = NULL; 457 goto out; 458 } 459 dhcacklen = proplen; 460 461 /* 462 * Fetch the "netdev-path" boot property (if it exists), and 463 * stash it for later use by sysinfo(SI_DHCP_CACHE, ...). 464 */ 465 proplen = BOP_GETPROPLEN(bootops, "netdev-path"); 466 if (proplen > 0) { 467 netdev_path = kmem_zalloc(proplen, KM_SLEEP); 468 if (BOP_GETPROP(bootops, "netdev-path", 469 (uchar_t *)netdev_path) == -1) { 470 cmn_err(CE_WARN, "BOP_GETPROP of " 471 "\"netdev-path\" failed\n"); 472 kmem_free(netdev_path, proplen); 473 goto out; 474 } 475 } 476 } 477 478 /* 479 * Preload (load-only, no init) all modules which 480 * were added to the /etc/system file with the 481 * FORCELOAD keyword. 482 */ 483 BMDPRINTF(("loadrootmodules: preload_module\n")); 484 (void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL); 485 486 /* ONC_PLUS EXTRACT START */ 487 /* 488 * If we booted otw then load in the plumbing 489 * routine now while we still can. If we didn't 490 * boot otw then we will load strplumb in main(). 491 * 492 * NFS is actually a set of modules, the core routines, 493 * a diskless helper module, rpcmod, and the tli interface. Load 494 * them now while we still can. 495 * 496 * Because we glomb all versions of nfs into a single module 497 * we check based on the initial string "nfs". 498 * 499 * XXX: A better test for this is to see if device_type 500 * XXX: from the PROM is "network". 501 */ 502 503 if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 504 ++netboot; 505 506 /* 507 * Preload (load-only, no init) the dacf module. We cannot 508 * init the module because one of its requisite modules is 509 * dld whose _init function will call taskq_create(), which 510 * will panic the system at this point. 511 */ 512 if ((err = modloadonly("dacf", "net_dacf")) < 0) { 513 cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 514 goto out; 515 } 516 if ((err = modload("misc", "tlimod")) < 0) { 517 cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 518 goto out; 519 } 520 if ((err = modload("strmod", "rpcmod")) < 0) { 521 cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n"); 522 goto out; 523 } 524 if ((err = modload("misc", "nfs_dlboot")) < 0) { 525 cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n"); 526 goto out; 527 } 528 if ((err = modload("mac", "mac_ether")) < 0) { 529 cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 530 goto out; 531 } 532 if ((err = modload("misc", "strplumb")) < 0) { 533 cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 534 goto out; 535 } 536 if ((err = strplumb_load()) < 0) { 537 goto out; 538 } 539 } 540 if (netboot_over_iscsi() == B_TRUE) { 541 /* iscsi boot */ 542 if ((err = modloadonly("dacf", "net_dacf")) < 0) { 543 cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 544 goto out; 545 } 546 if ((err = modload("misc", "tlimod")) < 0) { 547 cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 548 goto out; 549 } 550 if ((err = modload("mac", "mac_ether")) < 0) { 551 cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 552 goto out; 553 } 554 if ((err = modloadonly("drv", "iscsi")) < 0) { 555 cmn_err(CE_CONT, "Cannot load drv/iscsi\n"); 556 goto out; 557 } 558 if ((err = modloadonly("drv", "ssd")) < 0) { 559 cmn_err(CE_CONT, "Cannot load drv/ssd\n"); 560 goto out; 561 } 562 if ((err = modloadonly("drv", "sd")) < 0) { 563 cmn_err(CE_CONT, "Cannot load drv/sd\n"); 564 goto out; 565 } 566 if ((err = modload("misc", "strplumb")) < 0) { 567 cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 568 goto out; 569 } 570 if ((err = strplumb_load()) < 0) { 571 goto out; 572 } 573 } 574 /* 575 * Preload modules needed for booting as a cluster. 576 */ 577 err = clboot_loadrootmodules(); 578 579 out: 580 if (err != 0 && (boothowto & RB_ASKNAME)) 581 goto loop; 582 583 return (err); 584 } 585 /* ONC_PLUS EXTRACT END */ 586 587 static int 588 get_bootpath_prop(char *bootpath) 589 { 590 if (root_is_ramdisk) { 591 if (BOP_GETPROP(bootops, "bootarchive", bootpath) == -1) 592 return (-1); 593 (void) strlcat(bootpath, ":a", BO_MAXOBJNAME); 594 } else { 595 /* 596 * Look for the 1275 compliant name 'bootpath' first, 597 * but make certain it has a non-NULL value as well. 598 */ 599 if ((BOP_GETPROP(bootops, "bootpath", bootpath) == -1) || 600 strlen(bootpath) == 0) { 601 if (BOP_GETPROP(bootops, 602 "boot-path", bootpath) == -1) 603 return (-1); 604 } 605 if (memcmp(bootpath, BP_ISCSI_DISK, 606 strlen(BP_ISCSI_DISK)) == 0) { 607 /* iscsi boot */ 608 get_iscsi_bootpath_vhci(bootpath); 609 } 610 } 611 return (0); 612 } 613 614 static int 615 get_fstype_prop(char *fstype) 616 { 617 char *prop = (root_is_ramdisk) ? "archive-fstype" : "fstype"; 618 619 return (BOP_GETPROP(bootops, prop, fstype)); 620 } 621 622 /* 623 * Get the name of the root or swap filesystem type, and return 624 * the corresponding entry in the vfs switch. 625 * 626 * If we're not asking the user, and we're trying to find the 627 * root filesystem type, we ask boot for the filesystem 628 * type that it came from and use that. Similarly, if we're 629 * trying to find the swap filesystem, we try and derive it from 630 * the root filesystem type. 631 * 632 * If we are booting via NFS we currently have these options: 633 * nfs - dynamically choose NFS V2. V3, or V4 (default) 634 * nfs2 - force NFS V2 635 * nfs3 - force NFS V3 636 * nfs4 - force NFS V4 637 * Because we need to maintain backward compatibility with the naming 638 * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c) 639 * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic 640 * nfs module will map the type back to either "nfs", "nfs3", or "nfs4". 641 * This is only for root filesystems, all other uses such as cachefs 642 * will expect that "nfs" == NFS V2. 643 * 644 * If the filesystem isn't already loaded, vfs_getvfssw() will load 645 * it for us, but if (at the time we call it) modrootloaded is 646 * still not set, it won't run the filesystems _init routine (and 647 * implicitly it won't run the filesystems vsw_init() entry either). 648 * We do that explicitly in rootconf(). 649 */ 650 static struct vfssw * 651 getfstype(char *askfor, char *fsname, size_t fsnamelen) 652 { 653 struct vfssw *vsw; 654 static char defaultfs[BO_MAXFSNAME]; 655 int root = 0; 656 657 if (strcmp(askfor, "root") == 0) { 658 (void) get_fstype_prop(defaultfs); 659 root++; 660 } else { 661 (void) strcpy(defaultfs, "swapfs"); 662 } 663 664 if (boothowto & RB_ASKNAME) { 665 for (*fsname = '\0'; *fsname == '\0'; *fsname = '\0') { 666 printf("%s filesystem type [%s]: ", askfor, defaultfs); 667 console_gets(fsname, fsnamelen); 668 if (*fsname == '\0') 669 (void) strcpy(fsname, defaultfs); 670 if (root) { 671 if (strcmp(fsname, "nfs2") == 0) 672 (void) strcpy(fsname, "nfs"); 673 else if (strcmp(fsname, "nfs") == 0) 674 (void) strcpy(fsname, "nfsdyn"); 675 } 676 if ((vsw = vfs_getvfssw(fsname)) != NULL) 677 return (vsw); 678 printf("Unknown filesystem type '%s'\n", fsname); 679 } 680 } else if (*fsname == '\0') { 681 fsname = defaultfs; 682 } 683 if (*fsname == '\0') { 684 return (NULL); 685 } 686 687 if (root) { 688 if (strcmp(fsname, "nfs2") == 0) 689 (void) strcpy(fsname, "nfs"); 690 else if (strcmp(fsname, "nfs") == 0) 691 (void) strcpy(fsname, "nfsdyn"); 692 } 693 694 return (vfs_getvfssw(fsname)); 695 } 696 697 698 /* 699 * Get a physical device name, and maybe load and attach 700 * the driver. 701 * 702 * XXX Need better checking of whether or not a device 703 * actually exists if the user typed in a pathname. 704 * 705 * XXX Are we sure we want to expose users to this sort 706 * of physical namespace gobbledygook (now there's 707 * a word to conjure with..) 708 * 709 * XXX Note that on an OBP machine, we can easily ask the 710 * prom and pretty-print some plausible set of bootable 711 * devices. We can also user the prom to verify any 712 * such device. Later tim.. later. 713 */ 714 static int 715 getphysdev(char *askfor, char *name, size_t namelen) 716 { 717 static char fmt[] = "Enter physical name of %s device\n[%s]: "; 718 dev_t dev; 719 static char defaultpath[BO_MAXOBJNAME]; 720 721 /* 722 * Establish 'default' values - we get the root device from 723 * boot, and we infer the swap device is the same but with 724 * a 'b' on the end instead of an 'a'. A first stab at 725 * ease-of-use .. 726 */ 727 if (strcmp(askfor, "root") == 0) { 728 if (get_bootpath_prop(defaultpath) == -1) 729 boothowto |= RB_ASKNAME | RB_VERBOSE; 730 } else { 731 (void) strcpy(defaultpath, rootfs.bo_name); 732 defaultpath[strlen(defaultpath) - 1] = 'b'; 733 } 734 735 retry: 736 if (boothowto & RB_ASKNAME) { 737 printf(fmt, askfor, defaultpath); 738 console_gets(name, namelen); 739 } 740 if (*name == '\0') 741 (void) strcpy(name, defaultpath); 742 743 if (strcmp(askfor, "swap") == 0) { 744 745 /* 746 * Try to load and install the swap device driver. 747 */ 748 dev = ddi_pathname_to_dev_t(name); 749 750 if (dev == (dev_t)-1) { 751 printf("Not a supported device for swap.\n"); 752 boothowto |= RB_ASKNAME | RB_VERBOSE; 753 goto retry; 754 } 755 756 /* 757 * Ensure that we're not trying to swap on the floppy. 758 */ 759 if (strncmp(ddi_major_to_name(getmajor(dev)), "fd", 2) == 0) { 760 printf("Too dangerous to swap on the floppy\n"); 761 if (boothowto & RB_ASKNAME) 762 goto retry; 763 return (-1); 764 } 765 } 766 767 return (0); 768 } 769 770 771 /* 772 * Load a driver needed to boot. 773 */ 774 static int 775 load_boot_driver(char *drv) 776 { 777 char *drvname; 778 major_t major; 779 #ifdef sparc 780 struct devnames *dnp; 781 ddi_prop_t *propp; 782 char *module; 783 char *dir, *mf; 784 int plen; 785 int mlen; 786 #endif /* sparc */ 787 788 if ((major = ddi_name_to_major(drv)) == DDI_MAJOR_T_NONE) { 789 cmn_err(CE_CONT, "%s: no major number\n", drv); 790 return (-1); 791 } 792 /* 793 * resolve aliases 794 */ 795 drvname = ddi_major_to_name(major); 796 797 #ifdef DEBUG 798 if (strcmp(drv, drvname) == 0) { 799 BMDPRINTF(("load_boot_driver: %s\n", drv)); 800 } else { 801 BMDPRINTF(("load_boot_driver: %s -> %s\n", drv, drvname)); 802 } 803 #endif /* DEBUG */ 804 805 if (modloadonly("drv", drvname) == -1) { 806 cmn_err(CE_CONT, "%s: cannot load driver\n", drvname); 807 return (-1); 808 } 809 810 #ifdef sparc 811 /* 812 * NOTE: this can be removed when newboot-sparc is delivered. 813 * 814 * Check to see if the driver had a 'ddi-forceload' global driver.conf 815 * property to identify additional modules that need to be loaded. 816 * The driver still needs to use ddi_modopen() to open these modules, 817 * but the 'ddi-forceload' property allows the modules to be loaded 818 * into memory prior to lights-out, so that driver ddi_modopen() 819 * calls during lights-out (when mounting root) will work correctly. 820 * Use of 'ddi-forceload' is only required for drivers involved in 821 * getting root mounted. 822 */ 823 dnp = &devnamesp[major]; 824 if (dnp->dn_global_prop_ptr && dnp->dn_global_prop_ptr->prop_list && 825 ((propp = i_ddi_prop_search(DDI_DEV_T_ANY, 826 "ddi-forceload", DDI_PROP_TYPE_STRING, 827 &dnp->dn_global_prop_ptr->prop_list)) != NULL)) { 828 829 module = (char *)propp->prop_val; 830 plen = propp->prop_len; 831 while (plen > 0) { 832 mlen = strlen(module); 833 mf = strrchr(module, '/'); 834 if (mf) { 835 dir = module; 836 *mf++ = '\0'; /* '/' -> '\0' */ 837 } else { 838 dir = "misc"; 839 mf = module; 840 } 841 if (modloadonly(dir, mf) == -1) 842 cmn_err(CE_CONT, 843 "misc/%s: can't load module\n", mf); 844 if (mf != module) 845 *(mf - 1) = '/'; /* '\0' -> '/' */ 846 847 module += mlen + 1; 848 plen -= mlen + 1; 849 } 850 } 851 #endif /* sparc */ 852 853 return (0); 854 } 855 856 857 /* 858 * For a given instance, load that driver and its parents 859 */ 860 static int 861 load_parent_drivers(dev_info_t *dip, char *path) 862 { 863 int rval = 0; 864 major_t major = DDI_MAJOR_T_NONE; 865 char *drv; 866 char *p; 867 868 while (dip) { 869 /* check for path-oriented alias */ 870 if (path) 871 major = ddi_name_to_major(path); 872 else 873 major = DDI_MAJOR_T_NONE; 874 875 if (major != DDI_MAJOR_T_NONE) 876 drv = ddi_major_to_name(major); 877 else 878 drv = ddi_binding_name(dip); 879 880 if (load_boot_driver(drv) != 0) 881 rval = -1; 882 883 dip = ddi_get_parent(dip); 884 if (path) { 885 p = strrchr(path, '/'); 886 if (p) 887 *p = 0; 888 } 889 } 890 891 return (rval); 892 } 893 894 895 /* 896 * For a given path to a boot device, 897 * load that driver and all its parents. 898 */ 899 static int 900 load_bootpath_drivers(char *bootpath) 901 { 902 dev_info_t *dip; 903 char *pathcopy; 904 int pathcopy_len; 905 int rval; 906 char *p; 907 int proplen; 908 char iscsi_network_path[BO_MAXOBJNAME]; 909 910 if (bootpath == NULL || *bootpath == 0) 911 return (-1); 912 913 BMDPRINTF(("load_bootpath_drivers: %s\n", bootpath)); 914 #ifdef _OBP 915 if (netboot_over_iscsi()) { 916 /* iscsi boot */ 917 if (root_is_ramdisk) { 918 if (modloadonly("drv", "ramdisk") < 0) 919 return (-1); 920 } 921 proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_NETWORK_BOOTPATH); 922 if (proplen > 0) { 923 if (BOP_GETPROP(bootops, BP_ISCSI_NETWORK_BOOTPATH, 924 iscsi_network_path) > 0) { 925 p = strchr(iscsi_network_path, ':'); 926 if (p != NULL) { 927 *p = '\0'; 928 } 929 pathcopy = i_ddi_strdup(iscsi_network_path, 930 KM_SLEEP); 931 pathcopy_len = strlen(pathcopy) + 1; 932 } else { 933 return (-1); 934 } 935 } else { 936 return (-1); 937 } 938 } else { 939 #endif 940 pathcopy = i_ddi_strdup(bootpath, KM_SLEEP); 941 pathcopy_len = strlen(pathcopy) + 1; 942 #ifdef _OBP 943 } 944 #endif 945 dip = path_to_devinfo(pathcopy); 946 947 #if defined(__i386) || defined(__amd64) 948 /* 949 * i386 does not provide stub nodes for all boot devices, 950 * but we should be able to find the node for the parent, 951 * and the leaf of the boot path should be the driver name, 952 * which we go ahead and load here. 953 */ 954 if (dip == NULL) { 955 char *leaf; 956 957 /* 958 * Find last slash to build the full path to the 959 * parent of the leaf boot device 960 */ 961 p = strrchr(pathcopy, '/'); 962 *p++ = 0; 963 964 /* 965 * Now isolate the driver name of the leaf device 966 */ 967 leaf = p; 968 p = strchr(leaf, '@'); 969 *p = 0; 970 971 BMDPRINTF(("load_bootpath_drivers: parent=%s leaf=%s\n", 972 bootpath, leaf)); 973 974 dip = path_to_devinfo(pathcopy); 975 if (leaf) { 976 rval = load_boot_driver(leaf, NULL); 977 if (rval == -1) { 978 kmem_free(pathcopy, pathcopy_len); 979 return (NULL); 980 } 981 } 982 } 983 #endif 984 985 if (dip == NULL) { 986 cmn_err(CE_WARN, "can't bind driver for boot path <%s>", 987 bootpath); 988 kmem_free(pathcopy, pathcopy_len); 989 return (NULL); 990 } 991 992 /* 993 * Load IP over IB driver when netbooting over IB. 994 * As per IB 1275 binding, IP over IB is represented as 995 * service on the top of the HCA node. So, there is no 996 * PROM node and generic framework cannot pre-load 997 * IP over IB driver based on the bootpath. The following 998 * code preloads IP over IB driver when doing netboot over 999 * InfiniBand. 1000 */ 1001 if (netboot_over_ib(bootpath) && 1002 modloadonly("drv", "ibp") == -1) { 1003 cmn_err(CE_CONT, "ibp: cannot load platform driver\n"); 1004 kmem_free(pathcopy, pathcopy_len); 1005 return (NULL); 1006 } 1007 1008 /* 1009 * The PROM node for hubs have incomplete compatible 1010 * properties and therefore do not bind to the hubd driver. 1011 * As a result load_bootpath_drivers() loads the usb_mid driver 1012 * for hub nodes rather than the hubd driver. This causes 1013 * mountroot failures when booting off USB storage. To prevent 1014 * this, if we are booting via USB hubs, we preload the hubd driver. 1015 */ 1016 if (strstr(bootpath, "/hub@") && modloadonly("drv", "hubd") == -1) { 1017 cmn_err(CE_WARN, "bootpath contains a USB hub, " 1018 "but cannot load hubd driver"); 1019 } 1020 1021 /* get rid of minor node at end of copy (if not already done above) */ 1022 p = strrchr(pathcopy, '/'); 1023 if (p) { 1024 p = strchr(p, ':'); 1025 if (p) 1026 *p = 0; 1027 } 1028 1029 rval = load_parent_drivers(dip, pathcopy); 1030 kmem_free(pathcopy, pathcopy_len); 1031 return (rval); 1032 } 1033 1034 1035 1036 1037 /* 1038 * Load drivers required for a platform 1039 * Since all hardware nodes should be available in the device 1040 * tree, walk the per-driver list and load the parents of 1041 * each node found. If not a hardware node, try to load it. 1042 * Pseudo nexus is already loaded. 1043 */ 1044 static int 1045 load_boot_platform_modules(char *drv) 1046 { 1047 major_t major; 1048 dev_info_t *dip; 1049 char *drvname; 1050 int rval = 0; 1051 1052 if ((major = ddi_name_to_major(drv)) == DDI_MAJOR_T_NONE) { 1053 cmn_err(CE_CONT, "%s: no major number\n", drv); 1054 return (-1); 1055 } 1056 1057 /* 1058 * resolve aliases 1059 */ 1060 drvname = ddi_major_to_name(major); 1061 if ((major = ddi_name_to_major(drvname)) == DDI_MAJOR_T_NONE) 1062 return (-1); 1063 1064 #ifdef DEBUG 1065 if (strcmp(drv, drvname) == 0) { 1066 BMDPRINTF(("load_boot_platform_modules: %s\n", drv)); 1067 } else { 1068 BMDPRINTF(("load_boot_platform_modules: %s -> %s\n", 1069 drv, drvname)); 1070 } 1071 #endif /* DEBUG */ 1072 1073 dip = devnamesp[major].dn_head; 1074 if (dip == NULL) { 1075 /* pseudo node, not-enumerated, needs to be loaded */ 1076 if (modloadonly("drv", drvname) == -1) { 1077 cmn_err(CE_CONT, "%s: cannot load platform driver\n", 1078 drvname); 1079 rval = -1; 1080 } 1081 } else { 1082 while (dip) { 1083 if (load_parent_drivers(dip, NULL) != 0) 1084 rval = -1; 1085 dip = ddi_get_next(dip); 1086 } 1087 } 1088 1089 return (rval); 1090 } 1091 1092 1093 /* 1094 * i_find_node: Internal routine used by path_to_devinfo 1095 * to locate a given nodeid in the device tree. 1096 */ 1097 struct i_path_findnode { 1098 pnode_t nodeid; 1099 dev_info_t *dip; 1100 }; 1101 1102 static int 1103 i_path_find_node(dev_info_t *dev, void *arg) 1104 { 1105 struct i_path_findnode *f = (struct i_path_findnode *)arg; 1106 1107 1108 if (ddi_get_nodeid(dev) == (int)f->nodeid) { 1109 f->dip = dev; 1110 return (DDI_WALK_TERMINATE); 1111 } 1112 return (DDI_WALK_CONTINUE); 1113 } 1114 1115 /* 1116 * Return the devinfo node to a boot device 1117 */ 1118 static dev_info_t * 1119 path_to_devinfo(char *path) 1120 { 1121 struct i_path_findnode fn; 1122 extern dev_info_t *top_devinfo; 1123 1124 /* 1125 * Get the nodeid of the given pathname, if such a mapping exists. 1126 */ 1127 fn.dip = NULL; 1128 fn.nodeid = prom_finddevice(path); 1129 if (fn.nodeid != OBP_BADNODE) { 1130 /* 1131 * Find the nodeid in our copy of the device tree and return 1132 * whatever name we used to bind this node to a driver. 1133 */ 1134 ddi_walk_devs(top_devinfo, i_path_find_node, (void *)(&fn)); 1135 } 1136 1137 #ifdef DEBUG 1138 /* 1139 * If we're bound to something other than the nodename, 1140 * note that in the message buffer and system log. 1141 */ 1142 if (fn.dip) { 1143 char *p, *q; 1144 1145 p = ddi_binding_name(fn.dip); 1146 q = ddi_node_name(fn.dip); 1147 if (p && q && (strcmp(p, q) != 0)) { 1148 BMDPRINTF(("path_to_devinfo: %s bound to %s\n", 1149 path, p)); 1150 } 1151 } 1152 #endif /* DEBUG */ 1153 1154 return (fn.dip); 1155 } 1156 1157 /* 1158 * This routine returns B_TRUE if the bootpath corresponds to 1159 * IP over IB driver. 1160 * 1161 * The format of the bootpath for the IP over IB looks like 1162 * /pci@1f,700000/pci@1/ib@0:port=1,pkey=8001,protocol=ip 1163 * 1164 * The minor node portion "port=1,pkey=8001,protocol=ip" represents 1165 * IP over IB driver. 1166 */ 1167 static boolean_t 1168 netboot_over_ib(char *bootpath) 1169 { 1170 1171 char *temp; 1172 boolean_t ret = B_FALSE; 1173 pnode_t node = prom_finddevice(bootpath); 1174 int len; 1175 char devicetype[OBP_MAXDRVNAME]; 1176 1177 /* Is this IB node ? */ 1178 if (node == OBP_BADNODE || node == OBP_NONODE) { 1179 return (B_FALSE); 1180 } 1181 len = prom_getproplen(node, OBP_DEVICETYPE); 1182 if (len <= 1 || len >= OBP_MAXDRVNAME) 1183 return (B_FALSE); 1184 1185 (void) prom_getprop(node, OBP_DEVICETYPE, (caddr_t)devicetype); 1186 1187 if (strncmp("ib", devicetype, 2) == 0) { 1188 /* Check for proper IP over IB string */ 1189 if ((temp = strstr(bootpath, ":port=")) != NULL) { 1190 if ((temp = strstr(temp, ",pkey=")) != NULL) 1191 if ((temp = strstr(temp, 1192 ",protocol=ip")) != NULL) { 1193 ret = B_TRUE; 1194 } 1195 } 1196 } 1197 return (ret); 1198 } 1199 1200 static boolean_t 1201 netboot_over_iscsi(void) 1202 { 1203 int proplen; 1204 boolean_t ret = B_FALSE; 1205 char bootpath[OBP_MAXPATHLEN]; 1206 1207 proplen = BOP_GETPROPLEN(bootops, BP_BOOTPATH); 1208 if (proplen > 0) { 1209 if (BOP_GETPROP(bootops, BP_BOOTPATH, bootpath) > 0) { 1210 if (memcmp(bootpath, BP_ISCSI_DISK, 1211 strlen(BP_ISCSI_DISK)) == 0) { 1212 ret = B_TRUE; 1213 } 1214 } 1215 } 1216 return (ret); 1217 } 1218