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