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 }