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