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