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