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