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