Print this page
OS-90 Kernel should generate events when device gets retired / unretired.
re #13613 rb4516 Tunables needs volatile keyword
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/os/modctl.c
+++ new/usr/src/uts/common/os/modctl.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
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 21
22 22 /*
23 23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 25 */
25 26
26 27 /*
27 28 * modctl system call for loadable module support.
28 29 */
29 30
30 31 #include <sys/param.h>
31 32 #include <sys/user.h>
32 33 #include <sys/systm.h>
33 34 #include <sys/exec.h>
34 35 #include <sys/file.h>
35 36 #include <sys/stat.h>
36 37 #include <sys/conf.h>
37 38 #include <sys/time.h>
38 39 #include <sys/reboot.h>
39 40 #include <sys/fs/ufs_fsdir.h>
40 41 #include <sys/kmem.h>
41 42 #include <sys/sysconf.h>
42 43 #include <sys/cmn_err.h>
43 44 #include <sys/ddi.h>
44 45 #include <sys/sunddi.h>
45 46 #include <sys/sunndi.h>
46 47 #include <sys/ndi_impldefs.h>
47 48 #include <sys/ddi_impldefs.h>
48 49 #include <sys/ddi_implfuncs.h>
49 50 #include <sys/bootconf.h>
50 51 #include <sys/dc_ki.h>
51 52 #include <sys/cladm.h>
52 53 #include <sys/dtrace.h>
53 54 #include <sys/kdi.h>
54 55
55 56 #include <sys/devpolicy.h>
56 57 #include <sys/modctl.h>
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
57 58 #include <sys/kobj.h>
58 59 #include <sys/devops.h>
59 60 #include <sys/autoconf.h>
60 61 #include <sys/hwconf.h>
61 62 #include <sys/callb.h>
62 63 #include <sys/debug.h>
63 64 #include <sys/cpuvar.h>
64 65 #include <sys/sysmacros.h>
65 66 #include <sys/sysevent.h>
66 67 #include <sys/sysevent_impl.h>
68 +#include <sys/sysevent/eventdefs.h>
69 +#include <sys/sysevent/dev.h>
67 70 #include <sys/instance.h>
68 71 #include <sys/modhash.h>
69 72 #include <sys/modhash_impl.h>
70 73 #include <sys/dacf_impl.h>
71 74 #include <sys/vfs.h>
72 75 #include <sys/pathname.h>
73 76 #include <sys/console.h>
74 77 #include <sys/policy.h>
75 78 #include <ipp/ipp_impl.h>
76 79 #include <sys/fs/dv_node.h>
77 80 #include <sys/strsubr.h>
78 81 #include <sys/fs/sdev_impl.h>
79 82
80 83 static int mod_circdep(struct modctl *);
81 84 static int modinfo(modid_t, struct modinfo *);
82 85
83 86 static void mod_uninstall_all(void);
84 87 static int mod_getinfo(struct modctl *, struct modinfo *);
85 88 static struct modctl *allocate_modp(const char *, const char *);
86 89
87 90 static int mod_load(struct modctl *, int);
88 91 static void mod_unload(struct modctl *);
89 92 static int modinstall(struct modctl *);
90 93 static int moduninstall(struct modctl *);
91 94
92 95 static struct modctl *mod_hold_by_name_common(struct modctl *, const char *);
93 96 static struct modctl *mod_hold_next_by_id(modid_t);
94 97 static struct modctl *mod_hold_loaded_mod(struct modctl *, char *, int *);
95 98 static struct modctl *mod_hold_installed_mod(char *, int, int, int *);
96 99
97 100 static void mod_release(struct modctl *);
98 101 static void mod_make_requisite(struct modctl *, struct modctl *);
99 102 static int mod_install_requisites(struct modctl *);
100 103 static void check_esc_sequences(char *, char *);
101 104 static struct modctl *mod_hold_by_name_requisite(struct modctl *, char *);
102 105
103 106 /*
104 107 * module loading thread control structure. Calls to kobj_load_module()() are
105 108 * handled off to a separate thead using this structure.
106 109 */
107 110 struct loadmt {
108 111 ksema_t sema;
109 112 struct modctl *mp;
110 113 int usepath;
111 114 kthread_t *owner;
112 115 int retval;
113 116 };
114 117
115 118 static void modload_thread(struct loadmt *);
116 119
117 120 kcondvar_t mod_cv;
118 121 kcondvar_t mod_uninstall_cv; /* Communication between swapper */
119 122 /* and the uninstall daemon. */
120 123 kmutex_t mod_lock; /* protects &modules insert linkage, */
121 124 /* mod_busy, mod_want, and mod_ref. */
122 125 /* blocking operations while holding */
123 126 /* mod_lock should be avoided */
124 127 kmutex_t mod_uninstall_lock; /* protects mod_uninstall_cv */
|
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
125 128 kthread_id_t mod_aul_thread;
126 129
127 130 int modunload_wait;
128 131 kmutex_t modunload_wait_mutex;
129 132 kcondvar_t modunload_wait_cv;
130 133 int modunload_active_count;
131 134 int modunload_disable_count;
132 135
133 136 int isminiroot; /* set if running as miniroot */
134 137 int modrootloaded; /* set after root driver and fs are loaded */
135 -int moddebug = 0x0; /* debug flags for module writers */
138 +volatile int moddebug = 0x0; /* debug flags for module writers */
136 139 int swaploaded; /* set after swap driver and fs are loaded */
137 140 int bop_io_quiesced = 0; /* set when BOP I/O can no longer be used */
138 141 int last_module_id;
139 142 clock_t mod_uninstall_interval = 0;
140 143 int mod_uninstall_pass_max = 6;
141 144 int mod_uninstall_ref_zero; /* # modules that went mod_ref == 0 */
142 145 int mod_uninstall_pass_exc; /* mod_uninstall_all left new stuff */
143 146
144 147 int ddi_modclose_unload = 1; /* 0 -> just decrement reference */
145 148
146 149 int devcnt_incr = 256; /* allow for additional drivers */
147 150 int devcnt_min = 512; /* and always at least this number */
148 151
149 152 struct devnames *devnamesp;
150 153 struct devnames orphanlist;
151 154
152 155 krwlock_t devinfo_tree_lock; /* obsolete, to be removed */
153 156
154 157 #define MAJBINDFILE "/etc/name_to_major"
155 158 #define SYSBINDFILE "/etc/name_to_sysnum"
156 159
157 160 static char majbind[] = MAJBINDFILE;
158 161 static char sysbind[] = SYSBINDFILE;
159 162 static uint_t mod_autounload_key; /* for module autounload detection */
160 163
161 164 extern int obpdebug;
162 165
163 166 #define DEBUGGER_PRESENT ((boothowto & RB_DEBUG) || (obpdebug != 0))
164 167
165 168 static int minorperm_loaded = 0;
166 169
167 170 void
168 171 mod_setup(void)
169 172 {
170 173 struct sysent *callp;
171 174 int callnum, exectype;
172 175 int num_devs;
173 176 int i;
174 177
175 178 /*
176 179 * Initialize the list of loaded driver dev_ops.
177 180 * XXX - This must be done before reading the system file so that
178 181 * forceloads of drivers will work.
179 182 */
180 183 num_devs = read_binding_file(majbind, mb_hashtab, make_mbind);
181 184 /*
182 185 * Since read_binding_file is common code, it doesn't enforce that all
183 186 * of the binding file entries have major numbers <= MAXMAJ32. Thus,
184 187 * ensure that we don't allocate some massive amount of space due to a
185 188 * bad entry. We can't have major numbers bigger than MAXMAJ32
186 189 * until file system support for larger major numbers exists.
187 190 */
188 191
189 192 /*
190 193 * Leave space for expansion, but not more than L_MAXMAJ32
191 194 */
192 195 devcnt = MIN(num_devs + devcnt_incr, L_MAXMAJ32);
193 196 devcnt = MAX(devcnt, devcnt_min);
194 197 devopsp = kmem_alloc(devcnt * sizeof (struct dev_ops *), KM_SLEEP);
195 198 for (i = 0; i < devcnt; i++)
196 199 devopsp[i] = &mod_nodev_ops;
197 200
198 201 init_devnamesp(devcnt);
199 202
200 203 /*
201 204 * Sync up with the work that the stand-alone linker has already done.
202 205 */
203 206 (void) kobj_sync();
204 207
205 208 if (boothowto & RB_DEBUG)
206 209 kdi_dvec_modavail();
207 210
208 211 make_aliases(mb_hashtab);
209 212
210 213 /*
211 214 * Initialize streams device implementation structures.
212 215 */
213 216 devimpl = kmem_zalloc(devcnt * sizeof (cdevsw_impl_t), KM_SLEEP);
214 217
215 218 /*
216 219 * If the cl_bootstrap module is present,
217 220 * we should be configured as a cluster. Loading this module
218 221 * will set "cluster_bootflags" to non-zero.
219 222 */
220 223 (void) modload("misc", "cl_bootstrap");
221 224
222 225 (void) read_binding_file(sysbind, sb_hashtab, make_mbind);
223 226 init_syscallnames(NSYSCALL);
224 227
225 228 /*
226 229 * Start up dynamic autoconfiguration framework (dacf).
227 230 */
228 231 mod_hash_init();
229 232 dacf_init();
230 233
231 234 /*
232 235 * Start up IP policy framework (ipp).
233 236 */
234 237 ipp_init();
235 238
236 239 /*
237 240 * Allocate loadable native system call locks.
238 241 */
239 242 for (callnum = 0, callp = sysent; callnum < NSYSCALL;
240 243 callnum++, callp++) {
241 244 if (LOADABLE_SYSCALL(callp)) {
242 245 if (mod_getsysname(callnum) != NULL) {
243 246 callp->sy_lock =
244 247 kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
245 248 rw_init(callp->sy_lock, NULL, RW_DEFAULT, NULL);
246 249 } else {
247 250 callp->sy_flags &= ~SE_LOADABLE;
248 251 callp->sy_callc = nosys;
249 252 }
250 253 #ifdef DEBUG
251 254 } else {
252 255 /*
253 256 * Do some sanity checks on the sysent table
254 257 */
255 258 switch (callp->sy_flags & SE_RVAL_MASK) {
256 259 case SE_32RVAL1:
257 260 /* only r_val1 returned */
258 261 case SE_32RVAL1 | SE_32RVAL2:
259 262 /* r_val1 and r_val2 returned */
260 263 case SE_64RVAL:
261 264 /* 64-bit rval returned */
262 265 break;
263 266 default:
264 267 cmn_err(CE_WARN, "sysent[%d]: bad flags %x",
265 268 callnum, callp->sy_flags);
266 269 }
267 270 #endif
268 271 }
269 272 }
270 273
271 274 #ifdef _SYSCALL32_IMPL
272 275 /*
273 276 * Allocate loadable system call locks for 32-bit compat syscalls
274 277 */
275 278 for (callnum = 0, callp = sysent32; callnum < NSYSCALL;
276 279 callnum++, callp++) {
277 280 if (LOADABLE_SYSCALL(callp)) {
278 281 if (mod_getsysname(callnum) != NULL) {
279 282 callp->sy_lock =
280 283 kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
281 284 rw_init(callp->sy_lock, NULL, RW_DEFAULT, NULL);
282 285 } else {
283 286 callp->sy_flags &= ~SE_LOADABLE;
284 287 callp->sy_callc = nosys;
285 288 }
286 289 #ifdef DEBUG
287 290 } else {
288 291 /*
289 292 * Do some sanity checks on the sysent table
290 293 */
291 294 switch (callp->sy_flags & SE_RVAL_MASK) {
292 295 case SE_32RVAL1:
293 296 /* only r_val1 returned */
294 297 case SE_32RVAL1 | SE_32RVAL2:
295 298 /* r_val1 and r_val2 returned */
296 299 case SE_64RVAL:
297 300 /* 64-bit rval returned */
298 301 break;
299 302 default:
300 303 cmn_err(CE_WARN, "sysent32[%d]: bad flags %x",
301 304 callnum, callp->sy_flags);
302 305 goto skip;
303 306 }
304 307
305 308 /*
306 309 * Cross-check the native and compatibility tables.
307 310 */
308 311 if (callp->sy_callc == nosys ||
309 312 sysent[callnum].sy_callc == nosys)
310 313 continue;
311 314 /*
312 315 * If only one or the other slot is loadable, then
313 316 * there's an error -- they should match!
314 317 */
315 318 if ((callp->sy_callc == loadable_syscall) ^
316 319 (sysent[callnum].sy_callc == loadable_syscall)) {
317 320 cmn_err(CE_WARN, "sysent[%d] loadable?",
318 321 callnum);
319 322 }
320 323 /*
321 324 * This is more of a heuristic test -- if the
322 325 * system call returns two values in the 32-bit
323 326 * world, it should probably return two 32-bit
324 327 * values in the 64-bit world too.
325 328 */
326 329 if (((callp->sy_flags & SE_32RVAL2) == 0) ^
327 330 ((sysent[callnum].sy_flags & SE_32RVAL2) == 0)) {
328 331 cmn_err(CE_WARN, "sysent[%d] rval2 mismatch!",
329 332 callnum);
330 333 }
331 334 skip:;
332 335 #endif /* DEBUG */
333 336 }
334 337 }
335 338 #endif /* _SYSCALL32_IMPL */
336 339
337 340 /*
338 341 * Allocate loadable exec locks. (Assumes all execs are loadable)
339 342 */
340 343 for (exectype = 0; exectype < nexectype; exectype++) {
341 344 execsw[exectype].exec_lock =
342 345 kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
343 346 rw_init(execsw[exectype].exec_lock, NULL, RW_DEFAULT, NULL);
344 347 }
345 348
346 349 read_class_file();
347 350
348 351 /* init thread specific structure for mod_uninstall_all */
349 352 tsd_create(&mod_autounload_key, NULL);
350 353 }
351 354
352 355 static int
353 356 modctl_modload(int use_path, char *filename, int *rvp)
354 357 {
355 358 struct modctl *modp;
356 359 int retval = 0;
357 360 char *filenamep;
358 361 int modid;
359 362
360 363 filenamep = kmem_zalloc(MOD_MAXPATH, KM_SLEEP);
361 364
362 365 if (copyinstr(filename, filenamep, MOD_MAXPATH, 0)) {
363 366 retval = EFAULT;
364 367 goto out;
365 368 }
366 369
367 370 filenamep[MOD_MAXPATH - 1] = 0;
368 371 modp = mod_hold_installed_mod(filenamep, use_path, 0, &retval);
369 372
370 373 if (modp == NULL)
371 374 goto out;
372 375
373 376 modp->mod_loadflags |= MOD_NOAUTOUNLOAD;
374 377 modid = modp->mod_id;
375 378 mod_release_mod(modp);
376 379 CPU_STATS_ADDQ(CPU, sys, modload, 1);
377 380 if (rvp != NULL && copyout(&modid, rvp, sizeof (modid)) != 0)
378 381 retval = EFAULT;
379 382 out:
380 383 kmem_free(filenamep, MOD_MAXPATH);
381 384
382 385 return (retval);
383 386 }
384 387
385 388 static int
386 389 modctl_modunload(modid_t id)
387 390 {
388 391 int rval = 0;
389 392
390 393 if (id == 0) {
391 394 #ifdef DEBUG
392 395 /*
393 396 * Turn on mod_uninstall_daemon
394 397 */
395 398 if (mod_uninstall_interval == 0) {
396 399 mod_uninstall_interval = 60;
397 400 modreap();
398 401 return (rval);
399 402 }
400 403 #endif
401 404 mod_uninstall_all();
402 405 } else {
403 406 rval = modunload(id);
404 407 }
405 408 return (rval);
406 409 }
407 410
408 411 static int
409 412 modctl_modinfo(modid_t id, struct modinfo *umodi)
410 413 {
411 414 int retval;
412 415 struct modinfo modi;
413 416 #if defined(_SYSCALL32_IMPL)
414 417 int nobase;
415 418 struct modinfo32 modi32;
416 419 #endif
417 420
418 421 if (get_udatamodel() == DATAMODEL_NATIVE) {
419 422 if (copyin(umodi, &modi, sizeof (struct modinfo)) != 0)
420 423 return (EFAULT);
421 424 }
422 425 #ifdef _SYSCALL32_IMPL
423 426 else {
424 427 bzero(&modi, sizeof (modi));
425 428 if (copyin(umodi, &modi32, sizeof (struct modinfo32)) != 0)
426 429 return (EFAULT);
427 430 modi.mi_info = modi32.mi_info;
428 431 modi.mi_id = modi32.mi_id;
429 432 modi.mi_nextid = modi32.mi_nextid;
430 433 nobase = modi.mi_info & MI_INFO_NOBASE;
431 434 }
432 435 #endif
433 436 /*
434 437 * This flag is -only- for the kernels use.
435 438 */
436 439 modi.mi_info &= ~MI_INFO_LINKAGE;
437 440
438 441 retval = modinfo(id, &modi);
439 442 if (retval)
440 443 return (retval);
441 444
442 445 if (get_udatamodel() == DATAMODEL_NATIVE) {
443 446 if (copyout(&modi, umodi, sizeof (struct modinfo)) != 0)
444 447 retval = EFAULT;
445 448 #ifdef _SYSCALL32_IMPL
446 449 } else {
447 450 int i;
448 451
449 452 if (!nobase && (uintptr_t)modi.mi_base > UINT32_MAX)
450 453 return (EOVERFLOW);
451 454
452 455 modi32.mi_info = modi.mi_info;
453 456 modi32.mi_state = modi.mi_state;
454 457 modi32.mi_id = modi.mi_id;
455 458 modi32.mi_nextid = modi.mi_nextid;
456 459 modi32.mi_base = (caddr32_t)(uintptr_t)modi.mi_base;
457 460 modi32.mi_size = modi.mi_size;
458 461 modi32.mi_rev = modi.mi_rev;
459 462 modi32.mi_loadcnt = modi.mi_loadcnt;
460 463 bcopy(modi.mi_name, modi32.mi_name, sizeof (modi32.mi_name));
461 464 for (i = 0; i < MODMAXLINK32; i++) {
462 465 modi32.mi_msinfo[i].msi_p0 = modi.mi_msinfo[i].msi_p0;
463 466 bcopy(modi.mi_msinfo[i].msi_linkinfo,
464 467 modi32.mi_msinfo[i].msi_linkinfo,
465 468 sizeof (modi32.mi_msinfo[0].msi_linkinfo));
466 469 }
467 470 if (copyout(&modi32, umodi, sizeof (struct modinfo32)) != 0)
468 471 retval = EFAULT;
469 472 #endif
470 473 }
471 474
472 475 return (retval);
473 476 }
474 477
475 478 /*
476 479 * Return the last major number in the range of permissible major numbers.
477 480 */
478 481 /*ARGSUSED*/
479 482 static int
480 483 modctl_modreserve(modid_t id, int *data)
481 484 {
482 485 if (copyout(&devcnt, data, sizeof (devcnt)) != 0)
483 486 return (EFAULT);
484 487 return (0);
485 488 }
486 489
487 490 /* Add/Remove driver and binding aliases */
488 491 static int
489 492 modctl_update_driver_aliases(int add, int *data)
490 493 {
491 494 struct modconfig mc;
492 495 int i, n, rv = 0;
493 496 struct aliases alias;
494 497 struct aliases *ap;
495 498 char name[MAXMODCONFNAME];
496 499 char cname[MAXMODCONFNAME];
497 500 char *drvname;
498 501 int resid;
499 502 struct alias_info {
500 503 char *alias_name;
501 504 int alias_resid;
502 505 } *aliases, *aip;
503 506
504 507 bzero(&mc, sizeof (struct modconfig));
505 508 if (get_udatamodel() == DATAMODEL_NATIVE) {
506 509 if (copyin(data, &mc, sizeof (struct modconfig)) != 0)
507 510 return (EFAULT);
508 511 }
509 512 #ifdef _SYSCALL32_IMPL
510 513 else {
511 514 struct modconfig32 modc32;
512 515 if (copyin(data, &modc32, sizeof (struct modconfig32)) != 0)
513 516 return (EFAULT);
514 517 else {
515 518 bcopy(modc32.drvname, mc.drvname,
516 519 sizeof (modc32.drvname));
517 520 bcopy(modc32.drvclass, mc.drvclass,
518 521 sizeof (modc32.drvclass));
519 522 mc.major = modc32.major;
520 523 mc.flags = modc32.flags;
521 524 mc.num_aliases = modc32.num_aliases;
522 525 mc.ap = (struct aliases *)(uintptr_t)modc32.ap;
523 526 }
524 527 }
525 528 #endif
526 529
527 530 /*
528 531 * If the driver is already in the mb_hashtab, and the name given
529 532 * doesn't match that driver's name, fail. Otherwise, pass, since
530 533 * we may be adding aliases.
531 534 */
532 535 drvname = mod_major_to_name(mc.major);
533 536 if ((drvname != NULL) && strcmp(drvname, mc.drvname) != 0)
534 537 return (EINVAL);
535 538
536 539 /*
537 540 * Precede alias removal by unbinding as many devices as possible.
538 541 */
539 542 if (add == 0) {
540 543 (void) i_ddi_unload_drvconf(mc.major);
541 544 i_ddi_unbind_devs(mc.major);
542 545 }
543 546
544 547 /*
545 548 * Add/remove each supplied driver alias to/from mb_hashtab
546 549 */
547 550 ap = mc.ap;
548 551 if (mc.num_aliases > 0)
549 552 aliases = kmem_zalloc(
550 553 mc.num_aliases * sizeof (struct alias_info), KM_SLEEP);
551 554 aip = aliases;
552 555 for (i = 0; i < mc.num_aliases; i++) {
553 556 bzero(&alias, sizeof (struct aliases));
554 557 if (get_udatamodel() == DATAMODEL_NATIVE) {
555 558 if (copyin(ap, &alias, sizeof (struct aliases)) != 0) {
556 559 rv = EFAULT;
557 560 goto error;
558 561 }
559 562 if (alias.a_len > MAXMODCONFNAME) {
560 563 rv = EINVAL;
561 564 goto error;
562 565 }
563 566 if (copyin(alias.a_name, name, alias.a_len) != 0) {
564 567 rv = EFAULT;
565 568 goto error;
566 569 }
567 570 if (name[alias.a_len - 1] != '\0') {
568 571 rv = EINVAL;
569 572 goto error;
570 573 }
571 574 }
572 575 #ifdef _SYSCALL32_IMPL
573 576 else {
574 577 struct aliases32 al32;
575 578 bzero(&al32, sizeof (struct aliases32));
576 579 if (copyin(ap, &al32, sizeof (struct aliases32)) != 0) {
577 580 rv = EFAULT;
578 581 goto error;
579 582 }
580 583 if (al32.a_len > MAXMODCONFNAME) {
581 584 rv = EINVAL;
582 585 goto error;
583 586 }
584 587 if (copyin((void *)(uintptr_t)al32.a_name,
585 588 name, al32.a_len) != 0) {
586 589 rv = EFAULT;
587 590 goto error;
588 591 }
589 592 if (name[al32.a_len - 1] != '\0') {
590 593 rv = EINVAL;
591 594 goto error;
592 595 }
593 596 alias.a_next = (void *)(uintptr_t)al32.a_next;
594 597 }
595 598 #endif
596 599 check_esc_sequences(name, cname);
597 600 aip->alias_name = strdup(cname);
598 601 ap = alias.a_next;
599 602 aip++;
600 603 }
601 604
602 605 if (add == 0) {
603 606 ap = mc.ap;
604 607 resid = 0;
605 608 aip = aliases;
606 609 /* attempt to unbind all devices bound to each alias */
607 610 for (i = 0; i < mc.num_aliases; i++) {
608 611 n = i_ddi_unbind_devs_by_alias(
609 612 mc.major, aip->alias_name);
610 613 resid += n;
611 614 aip->alias_resid = n;
612 615 }
613 616
614 617 /*
615 618 * If some device bound to an alias remains in use,
616 619 * and override wasn't specified, no change is made to
617 620 * the binding state and we fail the operation.
618 621 */
619 622 if (resid > 0 && ((mc.flags & MOD_UNBIND_OVERRIDE) == 0)) {
620 623 rv = EBUSY;
621 624 goto error;
622 625 }
623 626
624 627 /*
625 628 * No device remains bound of any of the aliases,
626 629 * or force was requested. Mark each alias as
627 630 * inactive via delete_mbind so no future binds
628 631 * to this alias take place and that a new
629 632 * binding can be established.
630 633 */
631 634 aip = aliases;
632 635 for (i = 0; i < mc.num_aliases; i++) {
633 636 if (moddebug & MODDEBUG_BINDING)
634 637 cmn_err(CE_CONT, "Removing binding for %s "
635 638 "(%d active references)\n",
636 639 aip->alias_name, aip->alias_resid);
637 640 delete_mbind(aip->alias_name, mb_hashtab);
638 641 aip++;
639 642 }
640 643 rv = 0;
641 644 } else {
642 645 aip = aliases;
643 646 for (i = 0; i < mc.num_aliases; i++) {
644 647 if (moddebug & MODDEBUG_BINDING)
645 648 cmn_err(CE_NOTE, "Adding binding for '%s'\n",
646 649 aip->alias_name);
647 650 (void) make_mbind(aip->alias_name,
648 651 mc.major, NULL, mb_hashtab);
649 652 aip++;
650 653 }
651 654 /*
652 655 * Try to establish an mbinding for mc.drvname, and add it to
653 656 * devnames. Add class if any after establishing the major
654 657 * number.
655 658 */
656 659 (void) make_mbind(mc.drvname, mc.major, NULL, mb_hashtab);
657 660 if ((rv = make_devname(mc.drvname, mc.major,
658 661 (mc.flags & MOD_ADDMAJBIND_UPDATE) ?
659 662 DN_DRIVER_INACTIVE : 0)) != 0) {
660 663 goto error;
661 664 }
662 665
663 666 if (mc.drvclass[0] != '\0')
664 667 add_class(mc.drvname, mc.drvclass);
665 668 if ((mc.flags & MOD_ADDMAJBIND_UPDATE) == 0) {
666 669 (void) i_ddi_load_drvconf(mc.major);
667 670 }
668 671 }
669 672
670 673 /*
671 674 * Ensure that all nodes are bound to the most appropriate driver
672 675 * possible, attempting demotion and rebind when a more appropriate
673 676 * driver now exists. But not when adding a driver update-only.
674 677 */
675 678 if ((add == 0) || ((mc.flags & MOD_ADDMAJBIND_UPDATE) == 0)) {
676 679 i_ddi_bind_devs();
677 680 i_ddi_di_cache_invalidate();
678 681 }
679 682
680 683 error:
681 684 if (mc.num_aliases > 0) {
682 685 aip = aliases;
683 686 for (i = 0; i < mc.num_aliases; i++) {
684 687 if (aip->alias_name != NULL)
685 688 strfree(aip->alias_name);
686 689 aip++;
687 690 }
688 691 kmem_free(aliases, mc.num_aliases * sizeof (struct alias_info));
689 692 }
690 693 return (rv);
691 694 }
692 695
693 696 static int
694 697 modctl_add_driver_aliases(int *data)
695 698 {
696 699 return (modctl_update_driver_aliases(1, data));
697 700 }
698 701
699 702 static int
700 703 modctl_remove_driver_aliases(int *data)
701 704 {
702 705 return (modctl_update_driver_aliases(0, data));
703 706 }
704 707
705 708 static int
706 709 modctl_rem_major(major_t major)
707 710 {
708 711 struct devnames *dnp;
709 712
710 713 if (major >= devcnt)
711 714 return (EINVAL);
712 715
713 716 /* mark devnames as removed */
714 717 dnp = &devnamesp[major];
715 718 LOCK_DEV_OPS(&dnp->dn_lock);
716 719 if (dnp->dn_name == NULL ||
717 720 (dnp->dn_flags & (DN_DRIVER_REMOVED | DN_TAKEN_GETUDEV))) {
718 721 UNLOCK_DEV_OPS(&dnp->dn_lock);
719 722 return (EINVAL);
720 723 }
721 724 dnp->dn_flags |= DN_DRIVER_REMOVED;
722 725 pm_driver_removed(major);
723 726 UNLOCK_DEV_OPS(&dnp->dn_lock);
724 727
725 728 (void) i_ddi_unload_drvconf(major);
726 729 i_ddi_unbind_devs(major);
727 730 i_ddi_bind_devs();
728 731 i_ddi_di_cache_invalidate();
729 732
730 733 /* purge all the bindings to this driver */
731 734 purge_mbind(major, mb_hashtab);
732 735 return (0);
733 736 }
734 737
735 738 static struct vfs *
736 739 path_to_vfs(char *name)
737 740 {
738 741 vnode_t *vp;
739 742 struct vfs *vfsp;
740 743
741 744 if (lookupname(name, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp))
742 745 return (NULL);
743 746
744 747 vfsp = vp->v_vfsp;
745 748 VN_RELE(vp);
746 749 return (vfsp);
747 750 }
748 751
749 752 static int
750 753 new_vfs_in_modpath()
751 754 {
752 755 static int n_modpath = 0;
753 756 static char *modpath_copy;
754 757 static struct pathvfs {
755 758 char *path;
756 759 struct vfs *vfsp;
757 760 } *pathvfs;
758 761
759 762 int i, new_vfs = 0;
760 763 char *tmp, *tmp1;
761 764 struct vfs *vfsp;
762 765
763 766 if (n_modpath != 0) {
764 767 for (i = 0; i < n_modpath; i++) {
765 768 vfsp = path_to_vfs(pathvfs[i].path);
766 769 if (vfsp != pathvfs[i].vfsp) {
767 770 pathvfs[i].vfsp = vfsp;
768 771 if (vfsp)
769 772 new_vfs = 1;
770 773 }
771 774 }
772 775 return (new_vfs);
773 776 }
774 777
775 778 /*
776 779 * First call, initialize the pathvfs structure
777 780 */
778 781 modpath_copy = i_ddi_strdup(default_path, KM_SLEEP);
779 782 tmp = modpath_copy;
780 783 n_modpath = 1;
781 784 tmp1 = strchr(tmp, ' ');
782 785 while (tmp1) {
783 786 *tmp1 = '\0';
784 787 n_modpath++;
785 788 tmp = tmp1 + 1;
786 789 tmp1 = strchr(tmp, ' ');
787 790 }
788 791
789 792 pathvfs = kmem_zalloc(n_modpath * sizeof (struct pathvfs), KM_SLEEP);
790 793 tmp = modpath_copy;
791 794 for (i = 0; i < n_modpath; i++) {
792 795 pathvfs[i].path = tmp;
793 796 vfsp = path_to_vfs(tmp);
794 797 pathvfs[i].vfsp = vfsp;
795 798 tmp += strlen(tmp) + 1;
796 799 }
797 800 return (1); /* always reread driver.conf the first time */
798 801 }
799 802
800 803 static int
801 804 modctl_load_drvconf(major_t major, int flags)
802 805 {
803 806 int ret;
804 807
805 808 /*
806 809 * devfsadm -u - read all new driver.conf files
807 810 * and bind and configure devices for new drivers.
808 811 */
809 812 if (flags & MOD_LOADDRVCONF_RECONF) {
810 813 (void) i_ddi_load_drvconf(DDI_MAJOR_T_NONE);
811 814 i_ddi_bind_devs();
812 815 i_ddi_di_cache_invalidate();
813 816 return (0);
814 817 }
815 818
816 819 /*
817 820 * update_drv <drv> - reload driver.conf for the specified driver
818 821 */
819 822 if (major != DDI_MAJOR_T_NONE) {
820 823 ret = i_ddi_load_drvconf(major);
821 824 if (ret == 0)
822 825 i_ddi_bind_devs();
823 826 return (ret);
824 827 }
825 828
826 829 /*
827 830 * We are invoked to rescan new driver.conf files. It is
828 831 * only necessary if a new file system was mounted in the
829 832 * module_path. Because rescanning driver.conf files can
830 833 * take some time on older platforms (sun4m), the following
831 834 * code skips unnecessary driver.conf rescans to optimize
832 835 * boot performance.
833 836 */
834 837 if (new_vfs_in_modpath()) {
835 838 (void) i_ddi_load_drvconf(DDI_MAJOR_T_NONE);
836 839 /*
837 840 * If we are still initializing io subsystem,
838 841 * load drivers with ddi-forceattach property
839 842 */
840 843 if (!i_ddi_io_initialized())
841 844 i_ddi_forceattach_drivers();
842 845 }
843 846 return (0);
844 847 }
845 848
846 849 /*
847 850 * Unload driver.conf file and follow up by attempting
848 851 * to rebind devices to more appropriate driver.
849 852 */
850 853 static int
851 854 modctl_unload_drvconf(major_t major)
852 855 {
853 856 int ret;
854 857
855 858 if (major >= devcnt)
856 859 return (EINVAL);
857 860
858 861 ret = i_ddi_unload_drvconf(major);
859 862 if (ret != 0)
860 863 return (ret);
861 864 (void) i_ddi_unbind_devs(major);
862 865 i_ddi_bind_devs();
863 866
864 867 return (0);
865 868 }
866 869
867 870 static void
868 871 check_esc_sequences(char *str, char *cstr)
869 872 {
870 873 int i;
871 874 size_t len;
872 875 char *p;
873 876
874 877 len = strlen(str);
875 878 for (i = 0; i < len; i++, str++, cstr++) {
876 879 if (*str != '\\') {
877 880 *cstr = *str;
878 881 } else {
879 882 p = str + 1;
880 883 /*
881 884 * we only handle octal escape sequences for SPACE
882 885 */
883 886 if (*p++ == '0' && *p++ == '4' && *p == '0') {
884 887 *cstr = ' ';
885 888 str += 3;
886 889 } else {
887 890 *cstr = *str;
888 891 }
889 892 }
890 893 }
891 894 *cstr = 0;
892 895 }
893 896
894 897 static int
895 898 modctl_getmodpathlen(int *data)
896 899 {
897 900 int len;
898 901 len = strlen(default_path);
899 902 if (copyout(&len, data, sizeof (len)) != 0)
900 903 return (EFAULT);
901 904 return (0);
902 905 }
903 906
904 907 static int
905 908 modctl_getmodpath(char *data)
906 909 {
907 910 if (copyout(default_path, data, strlen(default_path) + 1) != 0)
908 911 return (EFAULT);
909 912 return (0);
910 913 }
911 914
912 915 static int
913 916 modctl_read_sysbinding_file(void)
914 917 {
915 918 (void) read_binding_file(sysbind, sb_hashtab, make_mbind);
916 919 return (0);
917 920 }
918 921
919 922 static int
920 923 modctl_getmaj(char *uname, uint_t ulen, int *umajorp)
921 924 {
922 925 char name[256];
923 926 int retval;
924 927 major_t major;
925 928
926 929 if (ulen == 0)
927 930 return (EINVAL);
928 931 if ((retval = copyinstr(uname, name,
929 932 (ulen < 256) ? ulen : 256, 0)) != 0)
930 933 return (retval);
931 934 if ((major = mod_name_to_major(name)) == DDI_MAJOR_T_NONE)
932 935 return (ENODEV);
933 936 if (copyout(&major, umajorp, sizeof (major_t)) != 0)
934 937 return (EFAULT);
935 938 return (0);
936 939 }
937 940
938 941 static char **
939 942 convert_constraint_string(char *constraints, size_t len)
940 943 {
941 944 int i;
942 945 int n;
943 946 char *p;
944 947 char **array;
945 948
946 949 ASSERT(constraints != NULL);
947 950 ASSERT(len > 0);
948 951
949 952 for (i = 0, p = constraints; strlen(p) > 0; i++, p += strlen(p) + 1)
950 953 ;
951 954
952 955 n = i;
953 956
954 957 if (n == 0) {
955 958 kmem_free(constraints, len);
956 959 return (NULL);
957 960 }
958 961
959 962 array = kmem_alloc((n + 1) * sizeof (char *), KM_SLEEP);
|
↓ open down ↓ |
814 lines elided |
↑ open up ↑ |
960 963
961 964 for (i = 0, p = constraints; i < n; i++, p += strlen(p) + 1) {
962 965 array[i] = i_ddi_strdup(p, KM_SLEEP);
963 966 }
964 967 array[n] = NULL;
965 968
966 969 kmem_free(constraints, len);
967 970
968 971 return (array);
969 972 }
973 +
974 +static void
975 +publish_retire_event(char *path, int retire)
976 +{
977 + sysevent_t *ev;
978 + sysevent_id_t eid;
979 + sysevent_value_t se_val;
980 + sysevent_attr_list_t *ev_attr_list = NULL;
981 +
982 + ev = sysevent_alloc(EC_DEV_STATUS,
983 + retire ? ESC_DEV_RETIRE : ESC_DEV_UNRETIRE, EC_DEVFS, SE_SLEEP);
984 + if (ev == NULL) {
985 + goto fail;
986 + }
987 +
988 + se_val.value_type = SE_DATA_TYPE_STRING;
989 + se_val.value.sv_string = path;
990 +
991 + if (sysevent_add_attr(&ev_attr_list, DEV_PHYS_PATH,
992 + &se_val, SE_SLEEP) != 0) {
993 + goto fail;
994 + }
995 +
996 + if (sysevent_attach_attributes(ev, ev_attr_list) != 0) {
997 + goto fail;
998 + }
999 +
1000 + if (log_sysevent(ev, SE_SLEEP, &eid) != 0) {
1001 + goto fail;
1002 + }
1003 +
1004 + sysevent_free(ev);
1005 + return;
1006 +
1007 +fail:
1008 +
1009 + cmn_err(CE_WARN, "failed to log device %s event for %s",
1010 + retire ? "retire" : "unretire", path);
1011 +
1012 + if (ev_attr_list != NULL) {
1013 + sysevent_free_attr(ev_attr_list);
1014 + }
1015 +
1016 + sysevent_free(ev);
1017 +}
1018 +
970 1019 /*ARGSUSED*/
971 1020 static int
972 1021 modctl_retire(char *path, char *uconstraints, size_t ulen)
973 1022 {
974 1023 char *pathbuf;
975 1024 char *devpath;
976 1025 size_t pathsz;
977 1026 int retval;
978 1027 char *constraints;
979 1028 char **cons_array;
980 1029
981 1030 if (path == NULL)
982 1031 return (EINVAL);
983 1032
984 1033 if ((uconstraints == NULL) ^ (ulen == 0))
985 1034 return (EINVAL);
986 1035
987 1036 pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
988 1037 retval = copyinstr(path, pathbuf, MAXPATHLEN, &pathsz);
989 1038 if (retval != 0) {
990 1039 kmem_free(pathbuf, MAXPATHLEN);
991 1040 return (retval);
992 1041 }
993 1042 devpath = i_ddi_strdup(pathbuf, KM_SLEEP);
994 1043 kmem_free(pathbuf, MAXPATHLEN);
995 1044
996 1045 /*
997 1046 * First check if the device is already retired.
998 1047 * If it is, then persist the retire anyway, just in case the retire
999 1048 * store has got out of sync with the boot archive.
1000 1049 */
1001 1050 if (e_ddi_device_retired(devpath)) {
1002 1051 cmn_err(CE_NOTE, "Device: already retired: %s", devpath);
1003 1052 (void) e_ddi_retire_persist(devpath);
1004 1053 kmem_free(devpath, strlen(devpath) + 1);
1005 1054 return (0);
1006 1055 }
1007 1056
1008 1057 cons_array = NULL;
1009 1058 if (uconstraints) {
1010 1059 constraints = kmem_alloc(ulen, KM_SLEEP);
1011 1060 if (copyin(uconstraints, constraints, ulen)) {
1012 1061 kmem_free(constraints, ulen);
1013 1062 kmem_free(devpath, strlen(devpath) + 1);
1014 1063 return (EFAULT);
1015 1064 }
1016 1065 cons_array = convert_constraint_string(constraints, ulen);
1017 1066 }
1018 1067
1019 1068 /*
1020 1069 * Try to retire the device first. The following
1021 1070 * routine will return an error only if the device
1022 1071 * is not retireable i.e. retire constraints forbid
1023 1072 * a retire. A return of success from this routine
1024 1073 * indicates that device is retireable.
1025 1074 */
1026 1075 retval = e_ddi_retire_device(devpath, cons_array);
1027 1076 if (retval != DDI_SUCCESS) {
1028 1077 cmn_err(CE_WARN, "constraints forbid retire: %s", devpath);
1029 1078 kmem_free(devpath, strlen(devpath) + 1);
1030 1079 return (ENOTSUP);
1031 1080 }
1032 1081
1033 1082 /*
1034 1083 * Ok, the retire succeeded. Persist the retire.
1035 1084 * If retiring a nexus, we need to only persist the
1036 1085 * nexus retire. Any children of a retired nexus
1037 1086 * are automatically covered by the retire store
1038 1087 * code.
1039 1088 */
|
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
1040 1089 retval = e_ddi_retire_persist(devpath);
1041 1090 if (retval != 0) {
1042 1091 cmn_err(CE_WARN, "Failed to persist device retire: error %d: "
1043 1092 "%s", retval, devpath);
1044 1093 kmem_free(devpath, strlen(devpath) + 1);
1045 1094 return (retval);
1046 1095 }
1047 1096 if (moddebug & MODDEBUG_RETIRE)
1048 1097 cmn_err(CE_NOTE, "Persisted retire of device: %s", devpath);
1049 1098
1099 + /* Issue sysevent. */
1100 + publish_retire_event(devpath, 1);
1101 +
1050 1102 kmem_free(devpath, strlen(devpath) + 1);
1051 1103 return (0);
1052 1104 }
1053 1105
1054 1106 static int
1055 1107 modctl_is_retired(char *path, int *statep)
1056 1108 {
1057 1109 char *pathbuf;
1058 1110 char *devpath;
1059 1111 size_t pathsz;
1060 1112 int error;
1061 1113 int status;
1062 1114
1063 1115 if (path == NULL || statep == NULL)
1064 1116 return (EINVAL);
1065 1117
1066 1118 pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1067 1119 error = copyinstr(path, pathbuf, MAXPATHLEN, &pathsz);
1068 1120 if (error != 0) {
1069 1121 kmem_free(pathbuf, MAXPATHLEN);
1070 1122 return (error);
1071 1123 }
1072 1124 devpath = i_ddi_strdup(pathbuf, KM_SLEEP);
1073 1125 kmem_free(pathbuf, MAXPATHLEN);
1074 1126
1075 1127 if (e_ddi_device_retired(devpath))
1076 1128 status = 1;
1077 1129 else
1078 1130 status = 0;
1079 1131 kmem_free(devpath, strlen(devpath) + 1);
1080 1132
1081 1133 return (copyout(&status, statep, sizeof (status)) ? EFAULT : 0);
1082 1134 }
1083 1135
1084 1136 static int
1085 1137 modctl_unretire(char *path)
1086 1138 {
1087 1139 char *pathbuf;
1088 1140 char *devpath;
1089 1141 size_t pathsz;
1090 1142 int retired;
1091 1143 int retval;
1092 1144
1093 1145 if (path == NULL)
1094 1146 return (EINVAL);
1095 1147
1096 1148 pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1097 1149 retval = copyinstr(path, pathbuf, MAXPATHLEN, &pathsz);
1098 1150 if (retval != 0) {
1099 1151 kmem_free(pathbuf, MAXPATHLEN);
1100 1152 return (retval);
1101 1153 }
1102 1154 devpath = i_ddi_strdup(pathbuf, KM_SLEEP);
1103 1155 kmem_free(pathbuf, MAXPATHLEN);
1104 1156
1105 1157 /*
1106 1158 * We check if a device is retired (first) before
1107 1159 * unpersisting the retire, because we use the
1108 1160 * retire store to determine if a device is retired.
1109 1161 * If we unpersist first, the device will always appear
1110 1162 * to be unretired. For the rationale behind unpersisting
1111 1163 * a device that is not retired, see the next comment.
1112 1164 */
1113 1165 retired = e_ddi_device_retired(devpath);
1114 1166
1115 1167 /*
1116 1168 * We call unpersist unconditionally because the lookup
1117 1169 * for retired devices (e_ddi_device_retired()), skips "bypassed"
1118 1170 * devices. We still want to be able remove "bypassed" entries
1119 1171 * from the persistent store, so we unpersist unconditionally
1120 1172 * i.e. whether or not the entry is found on a lookup.
1121 1173 *
1122 1174 * e_ddi_retire_unpersist() returns 1 if it found and cleared
1123 1175 * an entry from the retire store or 0 otherwise.
1124 1176 */
1125 1177 if (e_ddi_retire_unpersist(devpath))
1126 1178 if (moddebug & MODDEBUG_RETIRE) {
1127 1179 cmn_err(CE_NOTE, "Unpersisted retire of device: %s",
1128 1180 devpath);
1129 1181 }
1130 1182
1131 1183 /*
1132 1184 * Check if the device is already unretired. If so,
1133 1185 * the unretire becomes a NOP
1134 1186 */
1135 1187 if (!retired) {
1136 1188 cmn_err(CE_NOTE, "Not retired: %s", devpath);
|
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
1137 1189 kmem_free(devpath, strlen(devpath) + 1);
1138 1190 return (0);
1139 1191 }
1140 1192
1141 1193 retval = e_ddi_unretire_device(devpath);
1142 1194 if (retval != 0) {
1143 1195 cmn_err(CE_WARN, "cannot unretire device: error %d, path %s\n",
1144 1196 retval, devpath);
1145 1197 }
1146 1198
1199 + /* Issue sysevent. */
1200 + publish_retire_event(devpath, 0);
1201 +
1147 1202 kmem_free(devpath, strlen(devpath) + 1);
1148 1203
1149 1204 return (retval);
1150 1205 }
1151 1206
1152 1207 static int
1153 1208 modctl_getname(char *uname, uint_t ulen, int *umajorp)
1154 1209 {
1155 1210 char *name;
1156 1211 major_t major;
1157 1212
1158 1213 if (copyin(umajorp, &major, sizeof (major)) != 0)
1159 1214 return (EFAULT);
1160 1215 if ((name = mod_major_to_name(major)) == NULL)
1161 1216 return (ENODEV);
1162 1217 if ((strlen(name) + 1) > ulen)
1163 1218 return (ENOSPC);
1164 1219 return (copyoutstr(name, uname, ulen, NULL));
1165 1220 }
1166 1221
1167 1222 static int
1168 1223 modctl_devt2instance(dev_t dev, int *uinstancep)
1169 1224 {
1170 1225 int instance;
1171 1226
1172 1227 if ((instance = dev_to_instance(dev)) == -1)
1173 1228 return (EINVAL);
1174 1229
1175 1230 return (copyout(&instance, uinstancep, sizeof (int)));
1176 1231 }
1177 1232
1178 1233 /*
1179 1234 * Return the sizeof of the device id.
1180 1235 */
1181 1236 static int
1182 1237 modctl_sizeof_devid(dev_t dev, uint_t *len)
1183 1238 {
1184 1239 uint_t sz;
1185 1240 ddi_devid_t devid;
1186 1241
1187 1242 /* get device id */
1188 1243 if (ddi_lyr_get_devid(dev, &devid) == DDI_FAILURE)
1189 1244 return (EINVAL);
1190 1245
1191 1246 sz = ddi_devid_sizeof(devid);
1192 1247 ddi_devid_free(devid);
1193 1248
1194 1249 /* copyout device id size */
1195 1250 if (copyout(&sz, len, sizeof (sz)) != 0)
1196 1251 return (EFAULT);
1197 1252
1198 1253 return (0);
1199 1254 }
1200 1255
1201 1256 /*
1202 1257 * Return a copy of the device id.
1203 1258 */
1204 1259 static int
1205 1260 modctl_get_devid(dev_t dev, uint_t len, ddi_devid_t udevid)
1206 1261 {
1207 1262 uint_t sz;
1208 1263 ddi_devid_t devid;
1209 1264 int err = 0;
1210 1265
1211 1266 /* get device id */
1212 1267 if (ddi_lyr_get_devid(dev, &devid) == DDI_FAILURE)
1213 1268 return (EINVAL);
1214 1269
1215 1270 sz = ddi_devid_sizeof(devid);
1216 1271
1217 1272 /* Error if device id is larger than space allocated */
1218 1273 if (sz > len) {
1219 1274 ddi_devid_free(devid);
1220 1275 return (ENOSPC);
1221 1276 }
1222 1277
1223 1278 /* copy out device id */
1224 1279 if (copyout(devid, udevid, sz) != 0)
1225 1280 err = EFAULT;
1226 1281 ddi_devid_free(devid);
1227 1282 return (err);
1228 1283 }
1229 1284
1230 1285 /*
1231 1286 * return the /devices paths associated with the specified devid and
1232 1287 * minor name.
1233 1288 */
1234 1289 /*ARGSUSED*/
1235 1290 static int
1236 1291 modctl_devid2paths(ddi_devid_t udevid, char *uminor_name, uint_t flag,
1237 1292 size_t *ulensp, char *upaths)
1238 1293 {
1239 1294 ddi_devid_t devid = NULL;
1240 1295 int devid_len;
1241 1296 char *minor_name = NULL;
1242 1297 dev_info_t *dip = NULL;
1243 1298 int circ;
1244 1299 struct ddi_minor_data *dmdp;
1245 1300 char *path = NULL;
1246 1301 int ulens;
1247 1302 int lens;
1248 1303 int len;
1249 1304 dev_t *devlist = NULL;
1250 1305 int ndevs;
1251 1306 int i;
1252 1307 int ret = 0;
1253 1308
1254 1309 /*
1255 1310 * If upaths is NULL then we are only computing the amount of space
1256 1311 * needed to hold the paths and returning the value in *ulensp. If we
1257 1312 * are copying out paths then we get the amount of space allocated by
1258 1313 * the caller. If the actual space needed for paths is larger, or
1259 1314 * things are changing out from under us, then we return EAGAIN.
1260 1315 */
1261 1316 if (upaths) {
1262 1317 if (ulensp == NULL)
1263 1318 return (EINVAL);
1264 1319 if (copyin(ulensp, &ulens, sizeof (ulens)) != 0)
1265 1320 return (EFAULT);
1266 1321 }
1267 1322
1268 1323 /*
1269 1324 * copyin enough of the devid to determine the length then
1270 1325 * reallocate and copy in the entire devid.
1271 1326 */
1272 1327 devid_len = ddi_devid_sizeof(NULL);
1273 1328 devid = kmem_alloc(devid_len, KM_SLEEP);
1274 1329 if (copyin(udevid, devid, devid_len)) {
1275 1330 ret = EFAULT;
1276 1331 goto out;
1277 1332 }
1278 1333 len = devid_len;
1279 1334 devid_len = ddi_devid_sizeof(devid);
1280 1335 kmem_free(devid, len);
1281 1336 devid = kmem_alloc(devid_len, KM_SLEEP);
1282 1337 if (copyin(udevid, devid, devid_len)) {
1283 1338 ret = EFAULT;
1284 1339 goto out;
1285 1340 }
1286 1341
1287 1342 /* copyin the minor name if specified. */
1288 1343 minor_name = uminor_name;
1289 1344 if ((minor_name != DEVID_MINOR_NAME_ALL) &&
1290 1345 (minor_name != DEVID_MINOR_NAME_ALL_CHR) &&
1291 1346 (minor_name != DEVID_MINOR_NAME_ALL_BLK)) {
1292 1347 minor_name = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1293 1348 if (copyinstr(uminor_name, minor_name, MAXPATHLEN, 0)) {
1294 1349 ret = EFAULT;
1295 1350 goto out;
1296 1351 }
1297 1352 }
1298 1353
1299 1354 /*
1300 1355 * Use existing function to resolve the devid into a devlist.
1301 1356 *
1302 1357 * NOTE: there is a loss of spectype information in the current
1303 1358 * ddi_lyr_devid_to_devlist implementation. We work around this by not
1304 1359 * passing down DEVID_MINOR_NAME_ALL here, but reproducing all minor
1305 1360 * node forms in the loop processing the devlist below. It would be
1306 1361 * best if at some point the use of this interface here was replaced
1307 1362 * with a path oriented call.
1308 1363 */
1309 1364 if (ddi_lyr_devid_to_devlist(devid,
1310 1365 (minor_name == DEVID_MINOR_NAME_ALL) ?
1311 1366 DEVID_MINOR_NAME_ALL_CHR : minor_name,
1312 1367 &ndevs, &devlist) != DDI_SUCCESS) {
1313 1368 ret = EINVAL;
1314 1369 goto out;
1315 1370 }
1316 1371
1317 1372 /*
1318 1373 * loop over the devlist, converting each devt to a path and doing
1319 1374 * a copyout of the path and computation of the amount of space
1320 1375 * needed to hold all the paths
1321 1376 */
1322 1377 path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1323 1378 for (i = 0, lens = 0; i < ndevs; i++) {
1324 1379
1325 1380 /* find the dip associated with the dev_t */
1326 1381 if ((dip = e_ddi_hold_devi_by_dev(devlist[i], 0)) == NULL)
1327 1382 continue;
1328 1383
1329 1384 /* loop over all the minor nodes, skipping ones we don't want */
1330 1385 ndi_devi_enter(dip, &circ);
1331 1386 for (dmdp = DEVI(dip)->devi_minor; dmdp; dmdp = dmdp->next) {
1332 1387 if ((dmdp->ddm_dev != devlist[i]) ||
1333 1388 (dmdp->type != DDM_MINOR))
1334 1389 continue;
1335 1390
1336 1391 if ((minor_name != DEVID_MINOR_NAME_ALL) &&
1337 1392 (minor_name != DEVID_MINOR_NAME_ALL_CHR) &&
1338 1393 (minor_name != DEVID_MINOR_NAME_ALL_BLK) &&
1339 1394 strcmp(minor_name, dmdp->ddm_name))
1340 1395 continue;
1341 1396 else {
1342 1397 if ((minor_name == DEVID_MINOR_NAME_ALL_CHR) &&
1343 1398 (dmdp->ddm_spec_type != S_IFCHR))
1344 1399 continue;
1345 1400 if ((minor_name == DEVID_MINOR_NAME_ALL_BLK) &&
1346 1401 (dmdp->ddm_spec_type != S_IFBLK))
1347 1402 continue;
1348 1403 }
1349 1404
1350 1405 (void) ddi_pathname_minor(dmdp, path);
1351 1406 len = strlen(path) + 1;
1352 1407 *(path + len) = '\0'; /* set double termination */
1353 1408 lens += len;
1354 1409
1355 1410 /* copyout the path with double terminations */
1356 1411 if (upaths) {
1357 1412 if (lens > ulens) {
1358 1413 ret = EAGAIN;
1359 1414 goto out;
1360 1415 }
1361 1416 if (copyout(path, upaths, len + 1)) {
1362 1417 ret = EFAULT;
1363 1418 goto out;
1364 1419 }
1365 1420 upaths += len;
1366 1421 }
1367 1422 }
1368 1423 ndi_devi_exit(dip, circ);
1369 1424 ddi_release_devi(dip);
1370 1425 dip = NULL;
1371 1426 }
1372 1427 lens++; /* add one for double termination */
1373 1428
1374 1429 /* copy out the amount of space needed to hold the paths */
1375 1430 if (ulensp && copyout(&lens, ulensp, sizeof (lens))) {
1376 1431 ret = EFAULT;
1377 1432 goto out;
1378 1433 }
1379 1434 ret = 0;
1380 1435
1381 1436 out: if (dip) {
1382 1437 ndi_devi_exit(dip, circ);
1383 1438 ddi_release_devi(dip);
1384 1439 }
1385 1440 if (path)
1386 1441 kmem_free(path, MAXPATHLEN);
1387 1442 if (devlist)
1388 1443 ddi_lyr_free_devlist(devlist, ndevs);
1389 1444 if (minor_name &&
1390 1445 (minor_name != DEVID_MINOR_NAME_ALL) &&
1391 1446 (minor_name != DEVID_MINOR_NAME_ALL_CHR) &&
1392 1447 (minor_name != DEVID_MINOR_NAME_ALL_BLK))
1393 1448 kmem_free(minor_name, MAXPATHLEN);
1394 1449 if (devid)
1395 1450 kmem_free(devid, devid_len);
1396 1451 return (ret);
1397 1452 }
1398 1453
1399 1454 /*
1400 1455 * Return the size of the minor name.
1401 1456 */
1402 1457 static int
1403 1458 modctl_sizeof_minorname(dev_t dev, int spectype, uint_t *len)
1404 1459 {
1405 1460 uint_t sz;
1406 1461 char *name;
1407 1462
1408 1463 /* get the minor name */
1409 1464 if (ddi_lyr_get_minor_name(dev, spectype, &name) == DDI_FAILURE)
1410 1465 return (EINVAL);
1411 1466
1412 1467 sz = strlen(name) + 1;
1413 1468 kmem_free(name, sz);
1414 1469
1415 1470 /* copy out the size of the minor name */
1416 1471 if (copyout(&sz, len, sizeof (sz)) != 0)
1417 1472 return (EFAULT);
1418 1473
1419 1474 return (0);
1420 1475 }
1421 1476
1422 1477 /*
1423 1478 * Return the minor name.
1424 1479 */
1425 1480 static int
1426 1481 modctl_get_minorname(dev_t dev, int spectype, uint_t len, char *uname)
1427 1482 {
1428 1483 uint_t sz;
1429 1484 char *name;
1430 1485 int err = 0;
1431 1486
1432 1487 /* get the minor name */
1433 1488 if (ddi_lyr_get_minor_name(dev, spectype, &name) == DDI_FAILURE)
1434 1489 return (EINVAL);
1435 1490
1436 1491 sz = strlen(name) + 1;
1437 1492
1438 1493 /* Error if the minor name is larger than the space allocated */
1439 1494 if (sz > len) {
1440 1495 kmem_free(name, sz);
1441 1496 return (ENOSPC);
1442 1497 }
1443 1498
1444 1499 /* copy out the minor name */
1445 1500 if (copyout(name, uname, sz) != 0)
1446 1501 err = EFAULT;
1447 1502 kmem_free(name, sz);
1448 1503 return (err);
1449 1504 }
1450 1505
1451 1506 /*
1452 1507 * Return the size of the (dev_t,spectype) devfspath name.
1453 1508 */
1454 1509 static int
1455 1510 modctl_devfspath_len(dev_t dev, int spectype, uint_t *len)
1456 1511 {
1457 1512 uint_t sz;
1458 1513 char *name;
1459 1514
1460 1515 /* get the path name */
1461 1516 name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1462 1517 if (ddi_dev_pathname(dev, spectype, name) == DDI_FAILURE) {
1463 1518 kmem_free(name, MAXPATHLEN);
1464 1519 return (EINVAL);
1465 1520 }
1466 1521
1467 1522 sz = strlen(name) + 1;
1468 1523 kmem_free(name, MAXPATHLEN);
1469 1524
1470 1525 /* copy out the size of the path name */
1471 1526 if (copyout(&sz, len, sizeof (sz)) != 0)
1472 1527 return (EFAULT);
1473 1528
1474 1529 return (0);
1475 1530 }
1476 1531
1477 1532 /*
1478 1533 * Return the (dev_t,spectype) devfspath name.
1479 1534 */
1480 1535 static int
1481 1536 modctl_devfspath(dev_t dev, int spectype, uint_t len, char *uname)
1482 1537 {
1483 1538 uint_t sz;
1484 1539 char *name;
1485 1540 int err = 0;
1486 1541
1487 1542 /* get the path name */
1488 1543 name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1489 1544 if (ddi_dev_pathname(dev, spectype, name) == DDI_FAILURE) {
1490 1545 kmem_free(name, MAXPATHLEN);
1491 1546 return (EINVAL);
1492 1547 }
1493 1548
1494 1549 sz = strlen(name) + 1;
1495 1550
1496 1551 /* Error if the path name is larger than the space allocated */
1497 1552 if (sz > len) {
1498 1553 kmem_free(name, MAXPATHLEN);
1499 1554 return (ENOSPC);
1500 1555 }
1501 1556
1502 1557 /* copy out the path name */
1503 1558 if (copyout(name, uname, sz) != 0)
1504 1559 err = EFAULT;
1505 1560 kmem_free(name, MAXPATHLEN);
1506 1561 return (err);
1507 1562 }
1508 1563
1509 1564 /*
1510 1565 * Return the size of the (major,instance) devfspath name.
1511 1566 */
1512 1567 static int
1513 1568 modctl_devfspath_mi_len(major_t major, int instance, uint_t *len)
1514 1569 {
1515 1570 uint_t sz;
1516 1571 char *name;
1517 1572
1518 1573 /* get the path name */
1519 1574 name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1520 1575 if (e_ddi_majorinstance_to_path(major, instance, name) != DDI_SUCCESS) {
1521 1576 kmem_free(name, MAXPATHLEN);
1522 1577 return (EINVAL);
1523 1578 }
1524 1579
1525 1580 sz = strlen(name) + 1;
1526 1581 kmem_free(name, MAXPATHLEN);
1527 1582
1528 1583 /* copy out the size of the path name */
1529 1584 if (copyout(&sz, len, sizeof (sz)) != 0)
1530 1585 return (EFAULT);
1531 1586
1532 1587 return (0);
1533 1588 }
1534 1589
1535 1590 /*
1536 1591 * Return the (major_instance) devfspath name.
1537 1592 * NOTE: e_ddi_majorinstance_to_path does not require the device to attach to
1538 1593 * return a path - it uses the instance tree.
1539 1594 */
1540 1595 static int
1541 1596 modctl_devfspath_mi(major_t major, int instance, uint_t len, char *uname)
1542 1597 {
1543 1598 uint_t sz;
1544 1599 char *name;
1545 1600 int err = 0;
1546 1601
1547 1602 /* get the path name */
1548 1603 name = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1549 1604 if (e_ddi_majorinstance_to_path(major, instance, name) != DDI_SUCCESS) {
1550 1605 kmem_free(name, MAXPATHLEN);
1551 1606 return (EINVAL);
1552 1607 }
1553 1608
1554 1609 sz = strlen(name) + 1;
1555 1610
1556 1611 /* Error if the path name is larger than the space allocated */
1557 1612 if (sz > len) {
1558 1613 kmem_free(name, MAXPATHLEN);
1559 1614 return (ENOSPC);
1560 1615 }
1561 1616
1562 1617 /* copy out the path name */
1563 1618 if (copyout(name, uname, sz) != 0)
1564 1619 err = EFAULT;
1565 1620 kmem_free(name, MAXPATHLEN);
1566 1621 return (err);
1567 1622 }
1568 1623
1569 1624 static int
1570 1625 modctl_get_fbname(char *path)
1571 1626 {
1572 1627 extern dev_t fbdev;
1573 1628 char *pathname = NULL;
1574 1629 int rval = 0;
1575 1630
1576 1631 /* make sure fbdev is set before we plunge in */
1577 1632 if (fbdev == NODEV)
1578 1633 return (ENODEV);
1579 1634
1580 1635 pathname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1581 1636 if ((rval = ddi_dev_pathname(fbdev, S_IFCHR,
1582 1637 pathname)) == DDI_SUCCESS) {
1583 1638 if (copyout(pathname, path, strlen(pathname)+1) != 0) {
1584 1639 rval = EFAULT;
1585 1640 }
1586 1641 }
1587 1642 kmem_free(pathname, MAXPATHLEN);
1588 1643 return (rval);
1589 1644 }
1590 1645
1591 1646 /*
1592 1647 * modctl_reread_dacf()
1593 1648 * Reread the dacf rules database from the named binding file.
1594 1649 * If NULL is specified, pass along the NULL, it means 'use the default'.
1595 1650 */
1596 1651 static int
1597 1652 modctl_reread_dacf(char *path)
1598 1653 {
1599 1654 int rval = 0;
1600 1655 char *filename, *filenamep;
1601 1656
1602 1657 filename = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1603 1658
1604 1659 if (path == NULL) {
1605 1660 filenamep = NULL;
1606 1661 } else {
1607 1662 if (copyinstr(path, filename, MAXPATHLEN, 0) != 0) {
1608 1663 rval = EFAULT;
1609 1664 goto out;
1610 1665 }
1611 1666 filenamep = filename;
1612 1667 filenamep[MAXPATHLEN - 1] = '\0';
1613 1668 }
1614 1669
1615 1670 rval = read_dacf_binding_file(filenamep);
1616 1671 out:
1617 1672 kmem_free(filename, MAXPATHLEN);
1618 1673 return (rval);
1619 1674 }
1620 1675
1621 1676 /*ARGSUSED*/
1622 1677 static int
1623 1678 modctl_modevents(int subcmd, uintptr_t a2, uintptr_t a3, uintptr_t a4,
1624 1679 uint_t flag)
1625 1680 {
1626 1681 int error = 0;
1627 1682 char *filenamep;
1628 1683
1629 1684 switch (subcmd) {
1630 1685
1631 1686 case MODEVENTS_FLUSH:
1632 1687 /* flush all currently queued events */
1633 1688 log_sysevent_flushq(subcmd, flag);
1634 1689 break;
1635 1690
1636 1691 case MODEVENTS_SET_DOOR_UPCALL_FILENAME:
1637 1692 /*
1638 1693 * bind door_upcall to filename
1639 1694 * this should only be done once per invocation
1640 1695 * of the event daemon.
1641 1696 */
1642 1697
1643 1698 filenamep = kmem_zalloc(MOD_MAXPATH, KM_SLEEP);
1644 1699
1645 1700 if (copyinstr((char *)a2, filenamep, MOD_MAXPATH, 0)) {
1646 1701 error = EFAULT;
1647 1702 } else {
1648 1703 error = log_sysevent_filename(filenamep);
1649 1704 }
1650 1705 kmem_free(filenamep, MOD_MAXPATH);
1651 1706 break;
1652 1707
1653 1708 case MODEVENTS_GETDATA:
1654 1709 error = log_sysevent_copyout_data((sysevent_id_t *)a2,
1655 1710 (size_t)a3, (caddr_t)a4);
1656 1711 break;
1657 1712
1658 1713 case MODEVENTS_FREEDATA:
1659 1714 error = log_sysevent_free_data((sysevent_id_t *)a2);
1660 1715 break;
1661 1716 case MODEVENTS_POST_EVENT:
1662 1717 error = log_usr_sysevent((sysevent_t *)a2, (uint32_t)a3,
1663 1718 (sysevent_id_t *)a4);
1664 1719 break;
1665 1720 case MODEVENTS_REGISTER_EVENT:
1666 1721 error = log_sysevent_register((char *)a2, (char *)a3,
1667 1722 (se_pubsub_t *)a4);
1668 1723 break;
1669 1724 default:
1670 1725 error = EINVAL;
1671 1726 }
1672 1727
1673 1728 return (error);
1674 1729 }
1675 1730
1676 1731 static void
1677 1732 free_mperm(mperm_t *mp)
1678 1733 {
1679 1734 int len;
1680 1735
1681 1736 if (mp->mp_minorname) {
1682 1737 len = strlen(mp->mp_minorname) + 1;
1683 1738 kmem_free(mp->mp_minorname, len);
1684 1739 }
1685 1740 kmem_free(mp, sizeof (mperm_t));
1686 1741 }
1687 1742
1688 1743 #define MP_NO_DRV_ERR \
1689 1744 "/etc/minor_perm: no driver for %s\n"
1690 1745
1691 1746 #define MP_EMPTY_MINOR \
1692 1747 "/etc/minor_perm: empty minor name for driver %s\n"
1693 1748
1694 1749 #define MP_NO_MINOR \
1695 1750 "/etc/minor_perm: no minor matching %s for driver %s\n"
1696 1751
1697 1752 /*
1698 1753 * Remove mperm entry with matching minorname
1699 1754 */
1700 1755 static void
1701 1756 rem_minorperm(major_t major, char *drvname, mperm_t *mp, int is_clone)
1702 1757 {
1703 1758 mperm_t **mp_head;
1704 1759 mperm_t *freemp = NULL;
1705 1760 struct devnames *dnp = &devnamesp[major];
1706 1761 mperm_t **wildmp;
1707 1762
1708 1763 ASSERT(mp->mp_minorname && strlen(mp->mp_minorname) > 0);
1709 1764
1710 1765 LOCK_DEV_OPS(&dnp->dn_lock);
1711 1766 if (strcmp(mp->mp_minorname, "*") == 0) {
1712 1767 wildmp = ((is_clone == 0) ?
1713 1768 &dnp->dn_mperm_wild : &dnp->dn_mperm_clone);
1714 1769 if (*wildmp)
1715 1770 freemp = *wildmp;
1716 1771 *wildmp = NULL;
1717 1772 } else {
1718 1773 mp_head = &dnp->dn_mperm;
1719 1774 while (*mp_head) {
1720 1775 if (strcmp((*mp_head)->mp_minorname,
1721 1776 mp->mp_minorname) != 0) {
1722 1777 mp_head = &(*mp_head)->mp_next;
1723 1778 continue;
1724 1779 }
1725 1780 /* remove the entry */
1726 1781 freemp = *mp_head;
1727 1782 *mp_head = freemp->mp_next;
1728 1783 break;
1729 1784 }
1730 1785 }
1731 1786 if (freemp) {
1732 1787 if (moddebug & MODDEBUG_MINORPERM) {
1733 1788 cmn_err(CE_CONT, "< %s %s 0%o %d %d\n",
1734 1789 drvname, freemp->mp_minorname,
1735 1790 freemp->mp_mode & 0777,
1736 1791 freemp->mp_uid, freemp->mp_gid);
1737 1792 }
1738 1793 free_mperm(freemp);
1739 1794 } else {
1740 1795 if (moddebug & MODDEBUG_MINORPERM) {
1741 1796 cmn_err(CE_CONT, MP_NO_MINOR,
1742 1797 drvname, mp->mp_minorname);
1743 1798 }
1744 1799 }
1745 1800
1746 1801 UNLOCK_DEV_OPS(&dnp->dn_lock);
1747 1802 }
1748 1803
1749 1804 /*
1750 1805 * Add minor perm entry
1751 1806 */
1752 1807 static void
1753 1808 add_minorperm(major_t major, char *drvname, mperm_t *mp, int is_clone)
1754 1809 {
1755 1810 mperm_t **mp_head;
1756 1811 mperm_t *freemp = NULL;
1757 1812 struct devnames *dnp = &devnamesp[major];
1758 1813 mperm_t **wildmp;
1759 1814
1760 1815 ASSERT(mp->mp_minorname && strlen(mp->mp_minorname) > 0);
1761 1816
1762 1817 /*
1763 1818 * Note that update_drv replace semantics require
1764 1819 * replacing matching entries with the new permissions.
1765 1820 */
1766 1821 LOCK_DEV_OPS(&dnp->dn_lock);
1767 1822 if (strcmp(mp->mp_minorname, "*") == 0) {
1768 1823 wildmp = ((is_clone == 0) ?
1769 1824 &dnp->dn_mperm_wild : &dnp->dn_mperm_clone);
1770 1825 if (*wildmp)
1771 1826 freemp = *wildmp;
1772 1827 *wildmp = mp;
1773 1828 } else {
1774 1829 mperm_t *p, *v = NULL;
1775 1830 for (p = dnp->dn_mperm; p; v = p, p = p->mp_next) {
1776 1831 if (strcmp(p->mp_minorname, mp->mp_minorname) == 0) {
1777 1832 if (v == NULL)
1778 1833 dnp->dn_mperm = mp;
1779 1834 else
1780 1835 v->mp_next = mp;
1781 1836 mp->mp_next = p->mp_next;
1782 1837 freemp = p;
1783 1838 goto replaced;
1784 1839 }
1785 1840 }
1786 1841 if (p == NULL) {
1787 1842 mp_head = &dnp->dn_mperm;
1788 1843 if (*mp_head == NULL) {
1789 1844 *mp_head = mp;
1790 1845 } else {
1791 1846 mp->mp_next = *mp_head;
1792 1847 *mp_head = mp;
1793 1848 }
1794 1849 }
1795 1850 }
1796 1851 replaced:
1797 1852 if (freemp) {
1798 1853 if (moddebug & MODDEBUG_MINORPERM) {
1799 1854 cmn_err(CE_CONT, "< %s %s 0%o %d %d\n",
1800 1855 drvname, freemp->mp_minorname,
1801 1856 freemp->mp_mode & 0777,
1802 1857 freemp->mp_uid, freemp->mp_gid);
1803 1858 }
1804 1859 free_mperm(freemp);
1805 1860 }
1806 1861 if (moddebug & MODDEBUG_MINORPERM) {
1807 1862 cmn_err(CE_CONT, "> %s %s 0%o %d %d\n",
1808 1863 drvname, mp->mp_minorname, mp->mp_mode & 0777,
1809 1864 mp->mp_uid, mp->mp_gid);
1810 1865 }
1811 1866 UNLOCK_DEV_OPS(&dnp->dn_lock);
1812 1867 }
1813 1868
1814 1869
1815 1870 static int
1816 1871 process_minorperm(int cmd, nvlist_t *nvl)
1817 1872 {
1818 1873 char *minor;
1819 1874 major_t major;
1820 1875 mperm_t *mp;
1821 1876 nvpair_t *nvp;
1822 1877 char *name;
1823 1878 int is_clone;
1824 1879 major_t minmaj;
1825 1880
1826 1881 ASSERT(cmd == MODLOADMINORPERM ||
1827 1882 cmd == MODADDMINORPERM || cmd == MODREMMINORPERM);
1828 1883
1829 1884 nvp = NULL;
1830 1885 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
1831 1886 name = nvpair_name(nvp);
1832 1887
1833 1888 is_clone = 0;
1834 1889 (void) nvpair_value_string(nvp, &minor);
1835 1890 major = ddi_name_to_major(name);
1836 1891 if (major != DDI_MAJOR_T_NONE) {
1837 1892 mp = kmem_zalloc(sizeof (*mp), KM_SLEEP);
1838 1893 if (minor == NULL || strlen(minor) == 0) {
1839 1894 if (moddebug & MODDEBUG_MINORPERM) {
1840 1895 cmn_err(CE_CONT, MP_EMPTY_MINOR, name);
1841 1896 }
1842 1897 minor = "*";
1843 1898 }
1844 1899
1845 1900 /*
1846 1901 * The minor name of a node using the clone
1847 1902 * driver must be the driver name. To avoid
1848 1903 * multiple searches, we map entries in the form
1849 1904 * clone:<driver> to <driver>:*. This also allows us
1850 1905 * to filter out some of the litter in /etc/minor_perm.
1851 1906 * Minor perm alias entries where the name is not
1852 1907 * the driver kept on the clone list itself.
1853 1908 * This all seems very fragile as a driver could
1854 1909 * be introduced with an existing alias name.
1855 1910 */
1856 1911 if (strcmp(name, "clone") == 0) {
1857 1912 minmaj = ddi_name_to_major(minor);
1858 1913 if (minmaj != DDI_MAJOR_T_NONE) {
1859 1914 if (moddebug & MODDEBUG_MINORPERM) {
1860 1915 cmn_err(CE_CONT,
1861 1916 "mapping %s:%s to %s:*\n",
1862 1917 name, minor, minor);
1863 1918 }
1864 1919 major = minmaj;
1865 1920 name = minor;
1866 1921 minor = "*";
1867 1922 is_clone = 1;
1868 1923 }
1869 1924 }
1870 1925
1871 1926 if (mp) {
1872 1927 mp->mp_minorname =
1873 1928 i_ddi_strdup(minor, KM_SLEEP);
1874 1929 }
1875 1930 } else {
1876 1931 mp = NULL;
1877 1932 if (moddebug & MODDEBUG_MINORPERM) {
1878 1933 cmn_err(CE_CONT, MP_NO_DRV_ERR, name);
1879 1934 }
1880 1935 }
1881 1936
1882 1937 /* mode */
1883 1938 nvp = nvlist_next_nvpair(nvl, nvp);
1884 1939 ASSERT(strcmp(nvpair_name(nvp), "mode") == 0);
1885 1940 if (mp)
1886 1941 (void) nvpair_value_int32(nvp, (int *)&mp->mp_mode);
1887 1942 /* uid */
1888 1943 nvp = nvlist_next_nvpair(nvl, nvp);
1889 1944 ASSERT(strcmp(nvpair_name(nvp), "uid") == 0);
1890 1945 if (mp)
1891 1946 (void) nvpair_value_uint32(nvp, &mp->mp_uid);
1892 1947 /* gid */
1893 1948 nvp = nvlist_next_nvpair(nvl, nvp);
1894 1949 ASSERT(strcmp(nvpair_name(nvp), "gid") == 0);
1895 1950 if (mp) {
1896 1951 (void) nvpair_value_uint32(nvp, &mp->mp_gid);
1897 1952
1898 1953 if (cmd == MODREMMINORPERM) {
1899 1954 rem_minorperm(major, name, mp, is_clone);
1900 1955 free_mperm(mp);
1901 1956 } else {
1902 1957 add_minorperm(major, name, mp, is_clone);
1903 1958 }
1904 1959 }
1905 1960 }
1906 1961
1907 1962 if (cmd == MODLOADMINORPERM)
1908 1963 minorperm_loaded = 1;
1909 1964
1910 1965 /*
1911 1966 * Reset permissions of cached dv_nodes
1912 1967 */
1913 1968 (void) devfs_reset_perm(DV_RESET_PERM);
1914 1969
1915 1970 return (0);
1916 1971 }
1917 1972
1918 1973 static int
1919 1974 modctl_minorperm(int cmd, char *usrbuf, size_t buflen)
1920 1975 {
1921 1976 int error;
1922 1977 nvlist_t *nvl;
1923 1978 char *buf = kmem_alloc(buflen, KM_SLEEP);
1924 1979
1925 1980 if ((error = ddi_copyin(usrbuf, buf, buflen, 0)) != 0) {
1926 1981 kmem_free(buf, buflen);
1927 1982 return (error);
1928 1983 }
1929 1984
1930 1985 error = nvlist_unpack(buf, buflen, &nvl, KM_SLEEP);
1931 1986 kmem_free(buf, buflen);
1932 1987 if (error)
1933 1988 return (error);
1934 1989
1935 1990 error = process_minorperm(cmd, nvl);
1936 1991 nvlist_free(nvl);
1937 1992 return (error);
1938 1993 }
1939 1994
1940 1995 struct walk_args {
1941 1996 char *wa_drvname;
1942 1997 list_t wa_pathlist;
1943 1998 };
1944 1999
1945 2000 struct path_elem {
1946 2001 char *pe_dir;
1947 2002 char *pe_nodename;
1948 2003 list_node_t pe_node;
1949 2004 int pe_dirlen;
1950 2005 };
1951 2006
1952 2007 /*ARGSUSED*/
1953 2008 static int
1954 2009 modctl_inst_walker(const char *path, in_node_t *np, in_drv_t *dp, void *arg)
1955 2010 {
1956 2011 struct walk_args *wargs = (struct walk_args *)arg;
1957 2012 struct path_elem *pe;
1958 2013 char *nodename;
1959 2014
1960 2015 /*
1961 2016 * Search may be restricted to a single driver in the case of rem_drv
1962 2017 */
1963 2018 if (wargs->wa_drvname &&
1964 2019 strcmp(dp->ind_driver_name, wargs->wa_drvname) != 0)
1965 2020 return (INST_WALK_CONTINUE);
1966 2021
1967 2022 pe = kmem_zalloc(sizeof (*pe), KM_SLEEP);
1968 2023 pe->pe_dir = i_ddi_strdup((char *)path, KM_SLEEP);
1969 2024 pe->pe_dirlen = strlen(pe->pe_dir) + 1;
1970 2025 ASSERT(strrchr(pe->pe_dir, '/') != NULL);
1971 2026 nodename = strrchr(pe->pe_dir, '/');
1972 2027 *nodename++ = 0;
1973 2028 pe->pe_nodename = nodename;
1974 2029 list_insert_tail(&wargs->wa_pathlist, pe);
1975 2030
1976 2031 return (INST_WALK_CONTINUE);
1977 2032 }
1978 2033
1979 2034 /*
1980 2035 * /devices attribute nodes clean-up optionally performed
1981 2036 * when removing a driver (rem_drv -C).
1982 2037 *
1983 2038 * Removing attribute nodes allows a machine to be reprovisioned
1984 2039 * without the side-effect of inadvertently picking up stale
1985 2040 * device node ownership or permissions.
1986 2041 *
1987 2042 * Preserving attributes (not performing cleanup) allows devices
1988 2043 * attribute changes to be preserved across upgrades, as
1989 2044 * upgrade rather heavy-handedly does a rem_drv/add_drv cycle.
1990 2045 */
1991 2046 static int
1992 2047 modctl_remdrv_cleanup(const char *u_drvname)
1993 2048 {
1994 2049 struct walk_args *wargs;
1995 2050 struct path_elem *pe;
1996 2051 char *drvname;
1997 2052 int err, rval = 0;
1998 2053
1999 2054 drvname = kmem_alloc(MAXMODCONFNAME, KM_SLEEP);
2000 2055 if ((err = copyinstr(u_drvname, drvname, MAXMODCONFNAME, 0))) {
2001 2056 kmem_free(drvname, MAXMODCONFNAME);
2002 2057 return (err);
2003 2058 }
2004 2059
2005 2060 /*
2006 2061 * First go through the instance database. For each
2007 2062 * instance of a device bound to the driver being
2008 2063 * removed, remove any underlying devfs attribute nodes.
2009 2064 *
2010 2065 * This is a two-step process. First we go through
2011 2066 * the instance data itself, constructing a list of
2012 2067 * the nodes discovered. The second step is then
2013 2068 * to find and remove any devfs attribute nodes
2014 2069 * for the instances discovered in the first step.
2015 2070 * The two-step process avoids any difficulties
2016 2071 * which could arise by holding the instance data
2017 2072 * lock with simultaneous devfs operations.
2018 2073 */
2019 2074 wargs = kmem_zalloc(sizeof (*wargs), KM_SLEEP);
2020 2075
2021 2076 wargs->wa_drvname = drvname;
2022 2077 list_create(&wargs->wa_pathlist,
2023 2078 sizeof (struct path_elem), offsetof(struct path_elem, pe_node));
2024 2079
2025 2080 (void) e_ddi_walk_instances(modctl_inst_walker, (void *)wargs);
2026 2081
2027 2082 for (pe = list_head(&wargs->wa_pathlist); pe != NULL;
2028 2083 pe = list_next(&wargs->wa_pathlist, pe)) {
2029 2084 err = devfs_remdrv_cleanup((const char *)pe->pe_dir,
2030 2085 (const char *)pe->pe_nodename);
2031 2086 if (rval == 0)
2032 2087 rval = err;
2033 2088 }
2034 2089
2035 2090 while ((pe = list_head(&wargs->wa_pathlist)) != NULL) {
2036 2091 list_remove(&wargs->wa_pathlist, pe);
2037 2092 kmem_free(pe->pe_dir, pe->pe_dirlen);
2038 2093 kmem_free(pe, sizeof (*pe));
2039 2094 }
2040 2095 kmem_free(wargs, sizeof (*wargs));
2041 2096
2042 2097 /*
2043 2098 * Pseudo nodes aren't recorded in the instance database
2044 2099 * so any such nodes need to be handled separately.
2045 2100 */
2046 2101 err = devfs_remdrv_cleanup("pseudo", (const char *)drvname);
2047 2102 if (rval == 0)
2048 2103 rval = err;
2049 2104
2050 2105 kmem_free(drvname, MAXMODCONFNAME);
2051 2106 return (rval);
2052 2107 }
2053 2108
2054 2109 /*
2055 2110 * Perform a cleanup of non-existent /devices attribute nodes,
2056 2111 * similar to rem_drv -C, but for all drivers/devices.
2057 2112 * This is also optional, performed as part of devfsadm -C.
2058 2113 */
2059 2114 void
2060 2115 dev_devices_cleanup()
2061 2116 {
2062 2117 struct walk_args *wargs;
2063 2118 struct path_elem *pe;
2064 2119 dev_info_t *devi;
2065 2120 char *path;
2066 2121 int err;
2067 2122
2068 2123 /*
2069 2124 * It's expected that all drivers have been loaded and
2070 2125 * module unloading disabled while performing cleanup.
2071 2126 */
2072 2127 ASSERT(modunload_disable_count > 0);
2073 2128
2074 2129 wargs = kmem_zalloc(sizeof (*wargs), KM_SLEEP);
2075 2130 wargs->wa_drvname = NULL;
2076 2131 list_create(&wargs->wa_pathlist,
2077 2132 sizeof (struct path_elem), offsetof(struct path_elem, pe_node));
2078 2133
2079 2134 (void) e_ddi_walk_instances(modctl_inst_walker, (void *)wargs);
2080 2135
2081 2136 path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
2082 2137
2083 2138 for (pe = list_head(&wargs->wa_pathlist); pe != NULL;
2084 2139 pe = list_next(&wargs->wa_pathlist, pe)) {
2085 2140 (void) snprintf(path, MAXPATHLEN, "%s/%s",
2086 2141 pe->pe_dir, pe->pe_nodename);
2087 2142 devi = e_ddi_hold_devi_by_path(path, 0);
2088 2143 if (devi != NULL) {
2089 2144 ddi_release_devi(devi);
2090 2145 } else {
2091 2146 err = devfs_remdrv_cleanup((const char *)pe->pe_dir,
2092 2147 (const char *)pe->pe_nodename);
2093 2148 if (err) {
2094 2149 cmn_err(CE_CONT,
2095 2150 "devfs: %s: clean-up error %d\n",
2096 2151 path, err);
2097 2152 }
2098 2153 }
2099 2154 }
2100 2155
2101 2156 while ((pe = list_head(&wargs->wa_pathlist)) != NULL) {
2102 2157 list_remove(&wargs->wa_pathlist, pe);
2103 2158 kmem_free(pe->pe_dir, pe->pe_dirlen);
2104 2159 kmem_free(pe, sizeof (*pe));
2105 2160 }
2106 2161 kmem_free(wargs, sizeof (*wargs));
2107 2162 kmem_free(path, MAXPATHLEN);
2108 2163 }
2109 2164
2110 2165 static int
2111 2166 modctl_allocpriv(const char *name)
2112 2167 {
2113 2168 char *pstr = kmem_alloc(PRIVNAME_MAX, KM_SLEEP);
2114 2169 int error;
2115 2170
2116 2171 if ((error = copyinstr(name, pstr, PRIVNAME_MAX, 0))) {
2117 2172 kmem_free(pstr, PRIVNAME_MAX);
2118 2173 return (error);
2119 2174 }
2120 2175 error = priv_getbyname(pstr, PRIV_ALLOC);
2121 2176 if (error < 0)
2122 2177 error = -error;
2123 2178 else
2124 2179 error = 0;
2125 2180 kmem_free(pstr, PRIVNAME_MAX);
2126 2181 return (error);
2127 2182 }
2128 2183
2129 2184 static int
2130 2185 modctl_devexists(const char *upath, int pathlen)
2131 2186 {
2132 2187 char *path;
2133 2188 int ret;
2134 2189
2135 2190 /*
2136 2191 * copy in the path, including the terminating null
2137 2192 */
2138 2193 pathlen++;
2139 2194 if (pathlen <= 1 || pathlen > MAXPATHLEN)
2140 2195 return (EINVAL);
2141 2196 path = kmem_zalloc(pathlen + 1, KM_SLEEP);
2142 2197 if ((ret = copyinstr(upath, path, pathlen, NULL)) == 0) {
2143 2198 ret = sdev_modctl_devexists(path);
2144 2199 }
2145 2200
2146 2201 kmem_free(path, pathlen + 1);
2147 2202 return (ret);
2148 2203 }
2149 2204
2150 2205 static int
2151 2206 modctl_devreaddir(const char *udir, int udirlen,
2152 2207 char *upaths, int64_t *ulensp)
2153 2208 {
2154 2209 char *paths = NULL;
2155 2210 char **dirlist = NULL;
2156 2211 char *dir;
2157 2212 int64_t ulens;
2158 2213 int64_t lens;
2159 2214 int i, n;
2160 2215 int ret = 0;
2161 2216 char *p;
2162 2217 int npaths;
2163 2218 int npaths_alloc;
2164 2219
2165 2220 /*
2166 2221 * If upaths is NULL then we are only computing the amount of space
2167 2222 * needed to return the paths, with the value returned in *ulensp. If we
2168 2223 * are copying out paths then we get the amount of space allocated by
2169 2224 * the caller. If the actual space needed for paths is larger, or
2170 2225 * things are changing out from under us, then we return EAGAIN.
2171 2226 */
2172 2227 if (upaths) {
2173 2228 if (ulensp == NULL)
2174 2229 return (EINVAL);
2175 2230 if (copyin(ulensp, &ulens, sizeof (ulens)) != 0)
2176 2231 return (EFAULT);
2177 2232 }
2178 2233
2179 2234 /*
2180 2235 * copyin the /dev path including terminating null
2181 2236 */
2182 2237 udirlen++;
2183 2238 if (udirlen <= 1 || udirlen > MAXPATHLEN)
2184 2239 return (EINVAL);
2185 2240 dir = kmem_zalloc(udirlen + 1, KM_SLEEP);
2186 2241 if ((ret = copyinstr(udir, dir, udirlen, NULL)) != 0)
2187 2242 goto err;
2188 2243
2189 2244 if ((ret = sdev_modctl_readdir(dir, &dirlist,
2190 2245 &npaths, &npaths_alloc, 0)) != 0) {
2191 2246 ASSERT(dirlist == NULL);
2192 2247 goto err;
2193 2248 }
2194 2249
2195 2250 lens = 0;
2196 2251 for (i = 0; i < npaths; i++) {
2197 2252 lens += strlen(dirlist[i]) + 1;
2198 2253 }
2199 2254 lens++; /* add one for double termination */
2200 2255
2201 2256 if (upaths) {
2202 2257 if (lens > ulens) {
2203 2258 ret = EAGAIN;
2204 2259 goto out;
2205 2260 }
2206 2261
2207 2262 paths = kmem_alloc(lens, KM_SLEEP);
2208 2263
2209 2264 p = paths;
2210 2265 for (i = 0; i < npaths; i++) {
2211 2266 n = strlen(dirlist[i]) + 1;
2212 2267 bcopy(dirlist[i], p, n);
2213 2268 p += n;
2214 2269 }
2215 2270 *p = 0;
2216 2271
2217 2272 if (copyout(paths, upaths, lens)) {
2218 2273 ret = EFAULT;
2219 2274 goto err;
2220 2275 }
2221 2276 }
2222 2277
2223 2278 out:
2224 2279 /* copy out the amount of space needed to hold the paths */
2225 2280 if (copyout(&lens, ulensp, sizeof (lens)))
2226 2281 ret = EFAULT;
2227 2282
2228 2283 err:
2229 2284 if (dirlist)
2230 2285 sdev_modctl_readdir_free(dirlist, npaths, npaths_alloc);
2231 2286 if (paths)
2232 2287 kmem_free(paths, lens);
2233 2288 kmem_free(dir, udirlen + 1);
2234 2289 return (ret);
2235 2290 }
2236 2291
2237 2292 static int
2238 2293 modctl_devemptydir(const char *udir, int udirlen, int *uempty)
2239 2294 {
2240 2295 char *dir;
2241 2296 int ret;
2242 2297 char **dirlist = NULL;
2243 2298 int npaths;
2244 2299 int npaths_alloc;
2245 2300 int empty;
2246 2301
2247 2302 /*
2248 2303 * copyin the /dev path including terminating null
2249 2304 */
2250 2305 udirlen++;
2251 2306 if (udirlen <= 1 || udirlen > MAXPATHLEN)
2252 2307 return (EINVAL);
2253 2308 dir = kmem_zalloc(udirlen + 1, KM_SLEEP);
2254 2309 if ((ret = copyinstr(udir, dir, udirlen, NULL)) != 0)
2255 2310 goto err;
2256 2311
2257 2312 if ((ret = sdev_modctl_readdir(dir, &dirlist,
2258 2313 &npaths, &npaths_alloc, 1)) != 0) {
2259 2314 goto err;
2260 2315 }
2261 2316
2262 2317 empty = npaths ? 0 : 1;
2263 2318 if (copyout(&empty, uempty, sizeof (empty)))
2264 2319 ret = EFAULT;
2265 2320
2266 2321 err:
2267 2322 if (dirlist)
2268 2323 sdev_modctl_readdir_free(dirlist, npaths, npaths_alloc);
2269 2324 kmem_free(dir, udirlen + 1);
2270 2325 return (ret);
2271 2326 }
2272 2327
2273 2328 static int
2274 2329 modctl_hp(int subcmd, const char *path, char *cn_name, uintptr_t arg,
2275 2330 uintptr_t rval)
2276 2331 {
2277 2332 int error = 0;
2278 2333 size_t pathsz, namesz;
2279 2334 char *devpath, *cn_name_str;
2280 2335
2281 2336 if (path == NULL)
2282 2337 return (EINVAL);
2283 2338
2284 2339 devpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
2285 2340 error = copyinstr(path, devpath, MAXPATHLEN, &pathsz);
2286 2341 if (error != 0) {
2287 2342 kmem_free(devpath, MAXPATHLEN);
2288 2343 return (EFAULT);
2289 2344 }
2290 2345
2291 2346 cn_name_str = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
2292 2347 error = copyinstr(cn_name, cn_name_str, MAXNAMELEN, &namesz);
2293 2348 if (error != 0) {
2294 2349 kmem_free(devpath, MAXPATHLEN);
2295 2350 kmem_free(cn_name_str, MAXNAMELEN);
2296 2351
2297 2352 return (EFAULT);
2298 2353 }
2299 2354
2300 2355 switch (subcmd) {
2301 2356 case MODHPOPS_CHANGE_STATE:
2302 2357 error = ddihp_modctl(DDI_HPOP_CN_CHANGE_STATE, devpath,
2303 2358 cn_name_str, arg, NULL);
2304 2359 break;
2305 2360 case MODHPOPS_CREATE_PORT:
2306 2361 /* Create an empty PORT */
2307 2362 error = ddihp_modctl(DDI_HPOP_CN_CREATE_PORT, devpath,
2308 2363 cn_name_str, NULL, NULL);
2309 2364 break;
2310 2365 case MODHPOPS_REMOVE_PORT:
2311 2366 /* Remove an empty PORT */
2312 2367 error = ddihp_modctl(DDI_HPOP_CN_REMOVE_PORT, devpath,
2313 2368 cn_name_str, NULL, NULL);
2314 2369 break;
2315 2370 case MODHPOPS_BUS_GET:
2316 2371 error = ddihp_modctl(DDI_HPOP_CN_GET_PROPERTY, devpath,
2317 2372 cn_name_str, arg, rval);
2318 2373 break;
2319 2374 case MODHPOPS_BUS_SET:
2320 2375 error = ddihp_modctl(DDI_HPOP_CN_SET_PROPERTY, devpath,
2321 2376 cn_name_str, arg, rval);
2322 2377 break;
2323 2378 default:
2324 2379 error = ENOTSUP;
2325 2380 break;
2326 2381 }
2327 2382
2328 2383 kmem_free(devpath, MAXPATHLEN);
2329 2384 kmem_free(cn_name_str, MAXNAMELEN);
2330 2385
2331 2386 return (error);
2332 2387 }
2333 2388
2334 2389 int
2335 2390 modctl_moddevname(int subcmd, uintptr_t a1, uintptr_t a2)
2336 2391 {
2337 2392 int error = 0;
2338 2393
2339 2394 switch (subcmd) {
2340 2395 case MODDEVNAME_LOOKUPDOOR:
2341 2396 error = devname_filename_register((char *)a1);
2342 2397 break;
2343 2398 case MODDEVNAME_PROFILE:
2344 2399 error = devname_profile_update((char *)a1, (size_t)a2);
2345 2400 break;
2346 2401 case MODDEVNAME_RECONFIG:
2347 2402 i_ddi_set_reconfig();
2348 2403 break;
2349 2404 case MODDEVNAME_SYSAVAIL:
2350 2405 i_ddi_set_sysavail();
2351 2406 break;
2352 2407 default:
2353 2408 error = EINVAL;
2354 2409 break;
2355 2410 }
2356 2411
2357 2412 return (error);
2358 2413 }
2359 2414
2360 2415 /*ARGSUSED5*/
2361 2416 int
2362 2417 modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
2363 2418 uintptr_t a5)
2364 2419 {
2365 2420 int error = EINVAL;
2366 2421 dev_t dev;
2367 2422
2368 2423 if (secpolicy_modctl(CRED(), cmd) != 0)
2369 2424 return (set_errno(EPERM));
2370 2425
2371 2426 switch (cmd) {
2372 2427 case MODLOAD: /* load a module */
2373 2428 error = modctl_modload((int)a1, (char *)a2, (int *)a3);
2374 2429 break;
2375 2430
2376 2431 case MODUNLOAD: /* unload a module */
2377 2432 error = modctl_modunload((modid_t)a1);
2378 2433 break;
2379 2434
2380 2435 case MODINFO: /* get module status */
2381 2436 error = modctl_modinfo((modid_t)a1, (struct modinfo *)a2);
2382 2437 break;
2383 2438
2384 2439 case MODRESERVED: /* get last major number in range */
2385 2440 error = modctl_modreserve((modid_t)a1, (int *)a2);
2386 2441 break;
2387 2442
2388 2443 case MODSETMINIROOT: /* we are running in miniroot */
2389 2444 isminiroot = 1;
2390 2445 error = 0;
2391 2446 break;
2392 2447
2393 2448 case MODADDMAJBIND: /* add major / driver alias bindings */
2394 2449 error = modctl_add_driver_aliases((int *)a2);
2395 2450 break;
2396 2451
2397 2452 case MODGETPATHLEN: /* get modpath length */
2398 2453 error = modctl_getmodpathlen((int *)a2);
2399 2454 break;
2400 2455
2401 2456 case MODGETPATH: /* get modpath */
2402 2457 error = modctl_getmodpath((char *)a2);
2403 2458 break;
2404 2459
2405 2460 case MODREADSYSBIND: /* read system call binding file */
2406 2461 error = modctl_read_sysbinding_file();
2407 2462 break;
2408 2463
2409 2464 case MODGETMAJBIND: /* get major number for named device */
2410 2465 error = modctl_getmaj((char *)a1, (uint_t)a2, (int *)a3);
2411 2466 break;
2412 2467
2413 2468 case MODGETNAME: /* get name of device given major number */
2414 2469 error = modctl_getname((char *)a1, (uint_t)a2, (int *)a3);
2415 2470 break;
2416 2471
2417 2472 case MODDEVT2INSTANCE:
2418 2473 if (get_udatamodel() == DATAMODEL_NATIVE) {
2419 2474 dev = (dev_t)a1;
2420 2475 }
2421 2476 #ifdef _SYSCALL32_IMPL
2422 2477 else {
2423 2478 dev = expldev(a1);
2424 2479 }
2425 2480 #endif
2426 2481 error = modctl_devt2instance(dev, (int *)a2);
2427 2482 break;
2428 2483
2429 2484 case MODSIZEOF_DEVID: /* sizeof device id of device given dev_t */
2430 2485 if (get_udatamodel() == DATAMODEL_NATIVE) {
2431 2486 dev = (dev_t)a1;
2432 2487 }
2433 2488 #ifdef _SYSCALL32_IMPL
2434 2489 else {
2435 2490 dev = expldev(a1);
2436 2491 }
2437 2492 #endif
2438 2493 error = modctl_sizeof_devid(dev, (uint_t *)a2);
2439 2494 break;
2440 2495
2441 2496 case MODGETDEVID: /* get device id of device given dev_t */
2442 2497 if (get_udatamodel() == DATAMODEL_NATIVE) {
2443 2498 dev = (dev_t)a1;
2444 2499 }
2445 2500 #ifdef _SYSCALL32_IMPL
2446 2501 else {
2447 2502 dev = expldev(a1);
2448 2503 }
2449 2504 #endif
2450 2505 error = modctl_get_devid(dev, (uint_t)a2, (ddi_devid_t)a3);
2451 2506 break;
2452 2507
2453 2508 case MODSIZEOF_MINORNAME: /* sizeof minor nm (dev_t,spectype) */
2454 2509 if (get_udatamodel() == DATAMODEL_NATIVE) {
2455 2510 error = modctl_sizeof_minorname((dev_t)a1, (int)a2,
2456 2511 (uint_t *)a3);
2457 2512 }
2458 2513 #ifdef _SYSCALL32_IMPL
2459 2514 else {
2460 2515 error = modctl_sizeof_minorname(expldev(a1), (int)a2,
2461 2516 (uint_t *)a3);
2462 2517 }
2463 2518
2464 2519 #endif
2465 2520 break;
2466 2521
2467 2522 case MODGETMINORNAME: /* get minor name of (dev_t,spectype) */
2468 2523 if (get_udatamodel() == DATAMODEL_NATIVE) {
2469 2524 error = modctl_get_minorname((dev_t)a1, (int)a2,
2470 2525 (uint_t)a3, (char *)a4);
2471 2526 }
2472 2527 #ifdef _SYSCALL32_IMPL
2473 2528 else {
2474 2529 error = modctl_get_minorname(expldev(a1), (int)a2,
2475 2530 (uint_t)a3, (char *)a4);
2476 2531 }
2477 2532 #endif
2478 2533 break;
2479 2534
2480 2535 case MODGETDEVFSPATH_LEN: /* sizeof path nm of (dev_t,spectype) */
2481 2536 if (get_udatamodel() == DATAMODEL_NATIVE) {
2482 2537 error = modctl_devfspath_len((dev_t)a1, (int)a2,
2483 2538 (uint_t *)a3);
2484 2539 }
2485 2540 #ifdef _SYSCALL32_IMPL
2486 2541 else {
2487 2542 error = modctl_devfspath_len(expldev(a1), (int)a2,
2488 2543 (uint_t *)a3);
2489 2544 }
2490 2545
2491 2546 #endif
2492 2547 break;
2493 2548
2494 2549 case MODGETDEVFSPATH: /* get path name of (dev_t,spec) type */
2495 2550 if (get_udatamodel() == DATAMODEL_NATIVE) {
2496 2551 error = modctl_devfspath((dev_t)a1, (int)a2,
2497 2552 (uint_t)a3, (char *)a4);
2498 2553 }
2499 2554 #ifdef _SYSCALL32_IMPL
2500 2555 else {
2501 2556 error = modctl_devfspath(expldev(a1), (int)a2,
2502 2557 (uint_t)a3, (char *)a4);
2503 2558 }
2504 2559 #endif
2505 2560 break;
2506 2561
2507 2562 case MODGETDEVFSPATH_MI_LEN: /* sizeof path nm of (major,instance) */
2508 2563 error = modctl_devfspath_mi_len((major_t)a1, (int)a2,
2509 2564 (uint_t *)a3);
2510 2565 break;
2511 2566
2512 2567 case MODGETDEVFSPATH_MI: /* get path name of (major,instance) */
2513 2568 error = modctl_devfspath_mi((major_t)a1, (int)a2,
2514 2569 (uint_t)a3, (char *)a4);
2515 2570 break;
2516 2571
2517 2572
2518 2573 case MODEVENTS:
2519 2574 error = modctl_modevents((int)a1, a2, a3, a4, (uint_t)a5);
2520 2575 break;
2521 2576
2522 2577 case MODGETFBNAME: /* get the framebuffer name */
2523 2578 error = modctl_get_fbname((char *)a1);
2524 2579 break;
2525 2580
2526 2581 case MODREREADDACF: /* reread dacf rule database from given file */
2527 2582 error = modctl_reread_dacf((char *)a1);
2528 2583 break;
2529 2584
2530 2585 case MODLOADDRVCONF: /* load driver.conf file for major */
2531 2586 error = modctl_load_drvconf((major_t)a1, (int)a2);
2532 2587 break;
2533 2588
2534 2589 case MODUNLOADDRVCONF: /* unload driver.conf file for major */
2535 2590 error = modctl_unload_drvconf((major_t)a1);
2536 2591 break;
2537 2592
2538 2593 case MODREMMAJBIND: /* remove a major binding */
2539 2594 error = modctl_rem_major((major_t)a1);
2540 2595 break;
2541 2596
2542 2597 case MODREMDRVALIAS: /* remove a major/alias binding */
2543 2598 error = modctl_remove_driver_aliases((int *)a2);
2544 2599 break;
2545 2600
2546 2601 case MODDEVID2PATHS: /* get paths given devid */
2547 2602 error = modctl_devid2paths((ddi_devid_t)a1, (char *)a2,
2548 2603 (uint_t)a3, (size_t *)a4, (char *)a5);
2549 2604 break;
2550 2605
2551 2606 case MODSETDEVPOLICY: /* establish device policy */
2552 2607 error = devpolicy_load((int)a1, (size_t)a2, (devplcysys_t *)a3);
2553 2608 break;
2554 2609
2555 2610 case MODGETDEVPOLICY: /* get device policy */
2556 2611 error = devpolicy_get((int *)a1, (size_t)a2,
2557 2612 (devplcysys_t *)a3);
2558 2613 break;
2559 2614
2560 2615 case MODALLOCPRIV:
2561 2616 error = modctl_allocpriv((const char *)a1);
2562 2617 break;
2563 2618
2564 2619 case MODGETDEVPOLICYBYNAME:
2565 2620 error = devpolicy_getbyname((size_t)a1,
2566 2621 (devplcysys_t *)a2, (char *)a3);
2567 2622 break;
2568 2623
2569 2624 case MODLOADMINORPERM:
2570 2625 case MODADDMINORPERM:
2571 2626 case MODREMMINORPERM:
2572 2627 error = modctl_minorperm(cmd, (char *)a1, (size_t)a2);
2573 2628 break;
2574 2629
2575 2630 case MODREMDRVCLEANUP:
2576 2631 error = modctl_remdrv_cleanup((const char *)a1);
2577 2632 break;
2578 2633
2579 2634 case MODDEVEXISTS: /* non-reconfiguring /dev lookup */
2580 2635 error = modctl_devexists((const char *)a1, (size_t)a2);
2581 2636 break;
2582 2637
2583 2638 case MODDEVREADDIR: /* non-reconfiguring /dev readdir */
2584 2639 error = modctl_devreaddir((const char *)a1, (size_t)a2,
2585 2640 (char *)a3, (int64_t *)a4);
2586 2641 break;
2587 2642
2588 2643 case MODDEVEMPTYDIR: /* non-reconfiguring /dev emptydir */
2589 2644 error = modctl_devemptydir((const char *)a1, (size_t)a2,
2590 2645 (int *)a3);
2591 2646 break;
2592 2647
2593 2648 case MODDEVNAME:
2594 2649 error = modctl_moddevname((int)a1, a2, a3);
2595 2650 break;
2596 2651
2597 2652 case MODRETIRE: /* retire device named by physpath a1 */
2598 2653 error = modctl_retire((char *)a1, (char *)a2, (size_t)a3);
2599 2654 break;
2600 2655
2601 2656 case MODISRETIRED: /* check if a device is retired. */
2602 2657 error = modctl_is_retired((char *)a1, (int *)a2);
2603 2658 break;
2604 2659
2605 2660 case MODUNRETIRE: /* unretire device named by physpath a1 */
2606 2661 error = modctl_unretire((char *)a1);
2607 2662 break;
2608 2663
2609 2664 case MODHPOPS: /* hotplug operations */
2610 2665 /* device named by physpath a2 and Connection name a3 */
2611 2666 error = modctl_hp((int)a1, (char *)a2, (char *)a3, a4, a5);
2612 2667 break;
2613 2668
2614 2669 default:
2615 2670 error = EINVAL;
2616 2671 break;
2617 2672 }
2618 2673
2619 2674 return (error ? set_errno(error) : 0);
2620 2675 }
2621 2676
2622 2677 /*
2623 2678 * Calls to kobj_load_module()() are handled off to this routine in a
2624 2679 * separate thread.
2625 2680 */
2626 2681 static void
2627 2682 modload_thread(struct loadmt *ltp)
2628 2683 {
2629 2684 /* load the module and signal the creator of this thread */
2630 2685 kmutex_t cpr_lk;
2631 2686 callb_cpr_t cpr_i;
2632 2687
2633 2688 mutex_init(&cpr_lk, NULL, MUTEX_DEFAULT, NULL);
2634 2689 CALLB_CPR_INIT(&cpr_i, &cpr_lk, callb_generic_cpr, "modload");
2635 2690 /* borrow the devi lock from thread which invoked us */
2636 2691 pm_borrow_lock(ltp->owner);
2637 2692 ltp->retval = kobj_load_module(ltp->mp, ltp->usepath);
2638 2693 pm_return_lock();
2639 2694 sema_v(<p->sema);
2640 2695 mutex_enter(&cpr_lk);
2641 2696 CALLB_CPR_EXIT(&cpr_i);
2642 2697 mutex_destroy(&cpr_lk);
2643 2698 thread_exit();
2644 2699 }
2645 2700
2646 2701 /*
2647 2702 * load a module, adding a reference if caller specifies rmodp. If rmodp
2648 2703 * is specified then an errno is returned, otherwise a module index is
2649 2704 * returned (-1 on error).
2650 2705 */
2651 2706 static int
2652 2707 modrload(const char *subdir, const char *filename, struct modctl **rmodp)
2653 2708 {
2654 2709 struct modctl *modp;
2655 2710 size_t size;
2656 2711 char *fullname;
2657 2712 int retval = EINVAL;
2658 2713 int id = -1;
2659 2714
2660 2715 if (rmodp)
2661 2716 *rmodp = NULL; /* avoid garbage */
2662 2717
2663 2718 if (subdir != NULL) {
2664 2719 /*
2665 2720 * refuse / in filename to prevent "../" escapes.
2666 2721 */
2667 2722 if (strchr(filename, '/') != NULL)
2668 2723 return (rmodp ? retval : id);
2669 2724
2670 2725 /*
2671 2726 * allocate enough space for <subdir>/<filename><NULL>
2672 2727 */
2673 2728 size = strlen(subdir) + strlen(filename) + 2;
2674 2729 fullname = kmem_zalloc(size, KM_SLEEP);
2675 2730 (void) sprintf(fullname, "%s/%s", subdir, filename);
2676 2731 } else {
2677 2732 fullname = (char *)filename;
2678 2733 }
2679 2734
2680 2735 modp = mod_hold_installed_mod(fullname, 1, 0, &retval);
2681 2736 if (modp != NULL) {
2682 2737 id = modp->mod_id;
2683 2738 if (rmodp) {
2684 2739 /* add mod_ref and return *rmodp */
2685 2740 mutex_enter(&mod_lock);
2686 2741 modp->mod_ref++;
2687 2742 mutex_exit(&mod_lock);
2688 2743 *rmodp = modp;
2689 2744 }
2690 2745 mod_release_mod(modp);
2691 2746 CPU_STATS_ADDQ(CPU, sys, modload, 1);
2692 2747 }
2693 2748
2694 2749 done: if (subdir != NULL)
2695 2750 kmem_free(fullname, size);
2696 2751 return (rmodp ? retval : id);
2697 2752 }
2698 2753
2699 2754 /*
2700 2755 * This is the primary kernel interface to load a module. It loads and
2701 2756 * installs the named module. It does not hold mod_ref of the module, so
2702 2757 * a module unload attempt can occur at any time - it is up to the
2703 2758 * _fini/mod_remove implementation to determine if unload will succeed.
2704 2759 */
2705 2760 int
2706 2761 modload(const char *subdir, const char *filename)
2707 2762 {
2708 2763 return (modrload(subdir, filename, NULL));
2709 2764 }
2710 2765
2711 2766 /*
2712 2767 * Load a module using a series of qualified names from most specific to least
2713 2768 * specific, e.g. for subdir "foo", p1 "bar", p2 "baz", we might try:
2714 2769 * Value returned in *chosen
2715 2770 * foo/bar.baz.1.2.3 3
2716 2771 * foo/bar.baz.1.2 2
2717 2772 * foo/bar.baz.1 1
2718 2773 * foo/bar.baz 0
2719 2774 *
2720 2775 * Return the module ID on success; -1 if no module was loaded. On success
2721 2776 * and if 'chosen' is not NULL we also return the number of suffices that
2722 2777 * were in the module we chose to load.
2723 2778 */
2724 2779 int
2725 2780 modload_qualified(const char *subdir, const char *p1,
2726 2781 const char *p2, const char *delim, uint_t suffv[], int suffc, int *chosen)
2727 2782 {
2728 2783 char path[MOD_MAXPATH];
2729 2784 size_t n, resid = sizeof (path);
2730 2785 char *p = path;
2731 2786
2732 2787 char **dotv;
2733 2788 int i, rc, id;
2734 2789 modctl_t *mp;
2735 2790
2736 2791 if (p2 != NULL)
2737 2792 n = snprintf(p, resid, "%s/%s%s%s", subdir, p1, delim, p2);
2738 2793 else
2739 2794 n = snprintf(p, resid, "%s/%s", subdir, p1);
2740 2795
2741 2796 if (n >= resid)
2742 2797 return (-1);
2743 2798
2744 2799 p += n;
2745 2800 resid -= n;
2746 2801 dotv = kmem_alloc(sizeof (char *) * (suffc + 1), KM_SLEEP);
2747 2802
2748 2803 for (i = 0; i < suffc; i++) {
2749 2804 dotv[i] = p;
2750 2805 n = snprintf(p, resid, "%s%u", delim, suffv[i]);
2751 2806
2752 2807 if (n >= resid) {
2753 2808 kmem_free(dotv, sizeof (char *) * (suffc + 1));
2754 2809 return (-1);
2755 2810 }
2756 2811
2757 2812 p += n;
2758 2813 resid -= n;
2759 2814 }
2760 2815
2761 2816 dotv[suffc] = p;
2762 2817
2763 2818 for (i = suffc; i >= 0; i--) {
2764 2819 dotv[i][0] = '\0';
2765 2820 mp = mod_hold_installed_mod(path, 1, 1, &rc);
2766 2821
2767 2822 if (mp != NULL) {
2768 2823 kmem_free(dotv, sizeof (char *) * (suffc + 1));
2769 2824 id = mp->mod_id;
2770 2825 mod_release_mod(mp);
2771 2826 if (chosen != NULL)
2772 2827 *chosen = i;
2773 2828 return (id);
2774 2829 }
2775 2830 }
2776 2831
2777 2832 kmem_free(dotv, sizeof (char *) * (suffc + 1));
2778 2833 return (-1);
2779 2834 }
2780 2835
2781 2836 /*
2782 2837 * Load a module.
2783 2838 */
2784 2839 int
2785 2840 modloadonly(const char *subdir, const char *filename)
2786 2841 {
2787 2842 struct modctl *modp;
2788 2843 char *fullname;
2789 2844 size_t size;
2790 2845 int id, retval;
2791 2846
2792 2847 if (subdir != NULL) {
2793 2848 /*
2794 2849 * allocate enough space for <subdir>/<filename><NULL>
2795 2850 */
2796 2851 size = strlen(subdir) + strlen(filename) + 2;
2797 2852 fullname = kmem_zalloc(size, KM_SLEEP);
2798 2853 (void) sprintf(fullname, "%s/%s", subdir, filename);
2799 2854 } else {
2800 2855 fullname = (char *)filename;
2801 2856 }
2802 2857
2803 2858 modp = mod_hold_loaded_mod(NULL, fullname, &retval);
2804 2859 if (modp) {
2805 2860 id = modp->mod_id;
2806 2861 mod_release_mod(modp);
2807 2862 }
2808 2863
2809 2864 if (subdir != NULL)
2810 2865 kmem_free(fullname, size);
2811 2866
2812 2867 if (retval == 0)
2813 2868 return (id);
2814 2869 return (-1);
2815 2870 }
2816 2871
2817 2872 /*
2818 2873 * Try to uninstall and unload a module, removing a reference if caller
2819 2874 * specifies rmodp.
2820 2875 */
2821 2876 static int
2822 2877 modunrload(modid_t id, struct modctl **rmodp, int unload)
2823 2878 {
2824 2879 struct modctl *modp;
2825 2880 int retval;
2826 2881
2827 2882 if (rmodp)
2828 2883 *rmodp = NULL; /* avoid garbage */
2829 2884
2830 2885 if ((modp = mod_hold_by_id((modid_t)id)) == NULL)
2831 2886 return (EINVAL);
2832 2887
2833 2888 if (rmodp) {
2834 2889 mutex_enter(&mod_lock);
2835 2890 modp->mod_ref--;
2836 2891 if (modp->mod_ref == 0)
2837 2892 mod_uninstall_ref_zero++;
2838 2893 mutex_exit(&mod_lock);
2839 2894 *rmodp = modp;
2840 2895 }
2841 2896
2842 2897 if (unload) {
2843 2898 retval = moduninstall(modp);
2844 2899 if (retval == 0) {
2845 2900 mod_unload(modp);
2846 2901 CPU_STATS_ADDQ(CPU, sys, modunload, 1);
2847 2902 } else if (retval == EALREADY)
2848 2903 retval = 0; /* already unloaded, not an error */
2849 2904 } else
2850 2905 retval = 0;
2851 2906
2852 2907 mod_release_mod(modp);
2853 2908 return (retval);
2854 2909 }
2855 2910
2856 2911 /*
2857 2912 * Uninstall and unload a module.
2858 2913 */
2859 2914 int
2860 2915 modunload(modid_t id)
2861 2916 {
2862 2917 int retval;
2863 2918
2864 2919 /* synchronize with any active modunload_disable() */
2865 2920 modunload_begin();
2866 2921 if (ddi_root_node())
2867 2922 (void) devfs_clean(ddi_root_node(), NULL, 0);
2868 2923 retval = modunrload(id, NULL, 1);
2869 2924 modunload_end();
2870 2925 return (retval);
2871 2926 }
2872 2927
2873 2928 /*
2874 2929 * Return status of a loaded module.
2875 2930 */
2876 2931 static int
2877 2932 modinfo(modid_t id, struct modinfo *modinfop)
2878 2933 {
2879 2934 struct modctl *modp;
2880 2935 modid_t mid;
2881 2936 int i;
2882 2937
2883 2938 mid = modinfop->mi_id;
2884 2939 if (modinfop->mi_info & MI_INFO_ALL) {
2885 2940 while ((modp = mod_hold_next_by_id(mid++)) != NULL) {
2886 2941 if ((modinfop->mi_info & MI_INFO_CNT) ||
2887 2942 modp->mod_installed)
2888 2943 break;
2889 2944 mod_release_mod(modp);
2890 2945 }
2891 2946 if (modp == NULL)
2892 2947 return (EINVAL);
2893 2948 } else {
2894 2949 modp = mod_hold_by_id(id);
2895 2950 if (modp == NULL)
2896 2951 return (EINVAL);
2897 2952 if (!(modinfop->mi_info & MI_INFO_CNT) &&
2898 2953 (modp->mod_installed == 0)) {
2899 2954 mod_release_mod(modp);
2900 2955 return (EINVAL);
2901 2956 }
2902 2957 }
2903 2958
2904 2959 modinfop->mi_rev = 0;
2905 2960 modinfop->mi_state = 0;
2906 2961 for (i = 0; i < MODMAXLINK; i++) {
2907 2962 modinfop->mi_msinfo[i].msi_p0 = -1;
2908 2963 modinfop->mi_msinfo[i].msi_linkinfo[0] = 0;
2909 2964 }
2910 2965 if (modp->mod_loaded) {
2911 2966 modinfop->mi_state = MI_LOADED;
2912 2967 kobj_getmodinfo(modp->mod_mp, modinfop);
2913 2968 }
2914 2969 if (modp->mod_installed) {
2915 2970 modinfop->mi_state |= MI_INSTALLED;
2916 2971
2917 2972 (void) mod_getinfo(modp, modinfop);
2918 2973 }
2919 2974
2920 2975 modinfop->mi_id = modp->mod_id;
2921 2976 modinfop->mi_loadcnt = modp->mod_loadcnt;
2922 2977 (void) strcpy(modinfop->mi_name, modp->mod_modname);
2923 2978
2924 2979 mod_release_mod(modp);
2925 2980 return (0);
2926 2981 }
2927 2982
2928 2983 static char mod_stub_err[] = "mod_hold_stub: Couldn't load stub module %s";
2929 2984 static char no_err[] = "No error function for weak stub %s";
2930 2985
2931 2986 /*
2932 2987 * used by the stubs themselves to load and hold a module.
2933 2988 * Returns 0 if the module is successfully held;
2934 2989 * the stub needs to call mod_release_stub().
2935 2990 * -1 if the stub should just call the err_fcn.
2936 2991 * Note that this code is stretched out so that we avoid subroutine calls
2937 2992 * and optimize for the most likely case. That is, the case where the
2938 2993 * module is loaded and installed and not held. In that case we just inc
2939 2994 * the mod_ref count and continue.
2940 2995 */
2941 2996 int
2942 2997 mod_hold_stub(struct mod_stub_info *stub)
2943 2998 {
2944 2999 struct modctl *mp;
2945 3000 struct mod_modinfo *mip;
2946 3001
2947 3002 mip = stub->mods_modinfo;
2948 3003
2949 3004 mutex_enter(&mod_lock);
2950 3005
2951 3006 /* we do mod_hold_by_modctl inline for speed */
2952 3007
2953 3008 mod_check_again:
2954 3009 if ((mp = mip->mp) != NULL) {
2955 3010 if (mp->mod_busy == 0) {
2956 3011 if (mp->mod_installed) {
2957 3012 /* increment the reference count */
2958 3013 mp->mod_ref++;
2959 3014 ASSERT(mp->mod_ref && mp->mod_installed);
2960 3015 mutex_exit(&mod_lock);
2961 3016 return (0);
2962 3017 } else {
2963 3018 mp->mod_busy = 1;
2964 3019 mp->mod_inprogress_thread =
2965 3020 (curthread == NULL ?
2966 3021 (kthread_id_t)-1 : curthread);
2967 3022 }
2968 3023 } else {
2969 3024 /*
2970 3025 * wait one time and then go see if someone
2971 3026 * else has resolved the stub (set mip->mp).
2972 3027 */
2973 3028 if (mod_hold_by_modctl(mp,
2974 3029 MOD_WAIT_ONCE | MOD_LOCK_HELD))
2975 3030 goto mod_check_again;
2976 3031
2977 3032 /*
2978 3033 * what we have now may have been unloaded!, in
2979 3034 * that case, mip->mp will be NULL, we'll hit this
2980 3035 * module and load again..
2981 3036 */
2982 3037 cmn_err(CE_PANIC, "mod_hold_stub should have blocked");
2983 3038 }
2984 3039 mutex_exit(&mod_lock);
2985 3040 } else {
2986 3041 /* first time we've hit this module */
2987 3042 mutex_exit(&mod_lock);
2988 3043 mp = mod_hold_by_name(mip->modm_module_name);
2989 3044 mip->mp = mp;
2990 3045 }
2991 3046
2992 3047 /*
2993 3048 * If we are here, it means that the following conditions
2994 3049 * are satisfied.
2995 3050 *
2996 3051 * mip->mp != NULL
2997 3052 * this thread has set the mp->mod_busy = 1
2998 3053 * mp->mod_installed = 0
2999 3054 *
3000 3055 */
3001 3056 ASSERT(mp != NULL);
3002 3057 ASSERT(mp->mod_busy == 1);
3003 3058
3004 3059 if (mp->mod_installed == 0) {
3005 3060 /* Module not loaded, if weak stub don't load it */
3006 3061 if (stub->mods_flag & MODS_WEAK) {
3007 3062 if (stub->mods_errfcn == NULL) {
3008 3063 mod_release_mod(mp);
3009 3064 cmn_err(CE_PANIC, no_err,
3010 3065 mip->modm_module_name);
3011 3066 }
3012 3067 } else {
3013 3068 /* Not a weak stub so load the module */
3014 3069
3015 3070 if (mod_load(mp, 1) != 0 || modinstall(mp) != 0) {
3016 3071 /*
3017 3072 * If mod_load() was successful
3018 3073 * and modinstall() failed, then
3019 3074 * unload the module.
3020 3075 */
3021 3076 if (mp->mod_loaded)
3022 3077 mod_unload(mp);
3023 3078
3024 3079 mod_release_mod(mp);
3025 3080 if (stub->mods_errfcn == NULL) {
3026 3081 cmn_err(CE_PANIC, mod_stub_err,
3027 3082 mip->modm_module_name);
3028 3083 } else {
3029 3084 return (-1);
3030 3085 }
3031 3086 }
3032 3087 }
3033 3088 }
3034 3089
3035 3090 /*
3036 3091 * At this point module is held and loaded. Release
3037 3092 * the mod_busy and mod_inprogress_thread before
3038 3093 * returning. We actually call mod_release() here so
3039 3094 * that if another stub wants to access this module,
3040 3095 * it can do so. mod_ref is incremented before mod_release()
3041 3096 * is called to prevent someone else from snatching the
3042 3097 * module from this thread.
3043 3098 */
3044 3099 mutex_enter(&mod_lock);
3045 3100 mp->mod_ref++;
3046 3101 ASSERT(mp->mod_ref &&
3047 3102 (mp->mod_loaded || (stub->mods_flag & MODS_WEAK)));
3048 3103 mod_release(mp);
3049 3104 mutex_exit(&mod_lock);
3050 3105 return (0);
3051 3106 }
3052 3107
3053 3108 void
3054 3109 mod_release_stub(struct mod_stub_info *stub)
3055 3110 {
3056 3111 struct modctl *mp = stub->mods_modinfo->mp;
3057 3112
3058 3113 /* inline mod_release_mod */
3059 3114 mutex_enter(&mod_lock);
3060 3115 ASSERT(mp->mod_ref &&
3061 3116 (mp->mod_loaded || (stub->mods_flag & MODS_WEAK)));
3062 3117 mp->mod_ref--;
3063 3118 if (mp->mod_ref == 0)
3064 3119 mod_uninstall_ref_zero++;
3065 3120 if (mp->mod_want) {
3066 3121 mp->mod_want = 0;
3067 3122 cv_broadcast(&mod_cv);
3068 3123 }
3069 3124 mutex_exit(&mod_lock);
3070 3125 }
3071 3126
3072 3127 static struct modctl *
3073 3128 mod_hold_loaded_mod(struct modctl *dep, char *filename, int *status)
3074 3129 {
3075 3130 struct modctl *modp;
3076 3131 int retval;
3077 3132
3078 3133 /*
3079 3134 * Hold the module.
3080 3135 */
3081 3136 modp = mod_hold_by_name_requisite(dep, filename);
3082 3137 if (modp) {
3083 3138 retval = mod_load(modp, 1);
3084 3139 if (retval != 0) {
3085 3140 mod_release_mod(modp);
3086 3141 modp = NULL;
3087 3142 }
3088 3143 *status = retval;
3089 3144 } else {
3090 3145 *status = ENOSPC;
3091 3146 }
3092 3147
3093 3148 /*
3094 3149 * if dep is not NULL, clear the module dependency information.
3095 3150 * This information is set in mod_hold_by_name_common().
3096 3151 */
3097 3152 if (dep != NULL && dep->mod_requisite_loading != NULL) {
3098 3153 ASSERT(dep->mod_busy);
3099 3154 dep->mod_requisite_loading = NULL;
3100 3155 }
3101 3156
3102 3157 return (modp);
3103 3158 }
3104 3159
3105 3160 /*
3106 3161 * hold, load, and install the named module
3107 3162 */
3108 3163 static struct modctl *
3109 3164 mod_hold_installed_mod(char *name, int usepath, int forcecheck, int *r)
3110 3165 {
3111 3166 struct modctl *modp;
3112 3167 int retval;
3113 3168
3114 3169 /*
3115 3170 * Verify that that module in question actually exists on disk
3116 3171 * before allocation of module structure by mod_hold_by_name.
3117 3172 */
3118 3173 if (modrootloaded && swaploaded || forcecheck) {
3119 3174 if (!kobj_path_exists(name, usepath)) {
3120 3175 *r = ENOENT;
3121 3176 return (NULL);
3122 3177 }
3123 3178 }
3124 3179
3125 3180 /*
3126 3181 * Hold the module.
3127 3182 */
3128 3183 modp = mod_hold_by_name(name);
3129 3184 if (modp) {
3130 3185 retval = mod_load(modp, usepath);
3131 3186 if (retval != 0) {
3132 3187 mod_release_mod(modp);
3133 3188 modp = NULL;
3134 3189 *r = retval;
3135 3190 } else {
3136 3191 if ((*r = modinstall(modp)) != 0) {
3137 3192 /*
3138 3193 * We loaded it, but failed to _init() it.
3139 3194 * Be kind to developers -- force it
3140 3195 * out of memory now so that the next
3141 3196 * attempt to use the module will cause
3142 3197 * a reload. See 1093793.
3143 3198 */
3144 3199 mod_unload(modp);
3145 3200 mod_release_mod(modp);
3146 3201 modp = NULL;
3147 3202 }
3148 3203 }
3149 3204 } else {
3150 3205 *r = ENOSPC;
3151 3206 }
3152 3207 return (modp);
3153 3208 }
3154 3209
3155 3210 static char mod_excl_msg[] =
3156 3211 "module %s(%s) is EXCLUDED and will not be loaded\n";
3157 3212 static char mod_init_msg[] = "loadmodule:%s(%s): _init() error %d\n";
3158 3213
3159 3214 /*
3160 3215 * This routine is needed for dependencies. Users specify dependencies
3161 3216 * by declaring a character array initialized to filenames of dependents.
3162 3217 * So the code that handles dependents deals with filenames (and not
3163 3218 * module names) because that's all it has. We load by filename and once
3164 3219 * we've loaded a file we can get the module name.
3165 3220 * Unfortunately there isn't a single unified filename/modulename namespace.
3166 3221 * C'est la vie.
3167 3222 *
3168 3223 * We allow the name being looked up to be prepended by an optional
3169 3224 * subdirectory e.g. we can lookup (NULL, "fs/ufs") or ("fs", "ufs")
3170 3225 */
3171 3226 struct modctl *
3172 3227 mod_find_by_filename(char *subdir, char *filename)
3173 3228 {
3174 3229 struct modctl *mp;
3175 3230 size_t sublen;
3176 3231
3177 3232 ASSERT(!MUTEX_HELD(&mod_lock));
3178 3233 if (subdir != NULL)
3179 3234 sublen = strlen(subdir);
3180 3235 else
3181 3236 sublen = 0;
3182 3237
3183 3238 mutex_enter(&mod_lock);
3184 3239 mp = &modules;
3185 3240 do {
3186 3241 if (sublen) {
3187 3242 char *mod_filename = mp->mod_filename;
3188 3243
3189 3244 if (strncmp(subdir, mod_filename, sublen) == 0 &&
3190 3245 mod_filename[sublen] == '/' &&
3191 3246 strcmp(filename, &mod_filename[sublen + 1]) == 0) {
3192 3247 mutex_exit(&mod_lock);
3193 3248 return (mp);
3194 3249 }
3195 3250 } else if (strcmp(filename, mp->mod_filename) == 0) {
3196 3251 mutex_exit(&mod_lock);
3197 3252 return (mp);
3198 3253 }
3199 3254 } while ((mp = mp->mod_next) != &modules);
3200 3255 mutex_exit(&mod_lock);
3201 3256 return (NULL);
3202 3257 }
3203 3258
3204 3259 /*
3205 3260 * Check for circular dependencies. This is called from do_dependents()
3206 3261 * in kobj.c. If we are the thread already loading this module, then
3207 3262 * we're trying to load a dependent that we're already loading which
3208 3263 * means the user specified circular dependencies.
3209 3264 */
3210 3265 static int
3211 3266 mod_circdep(struct modctl *modp)
3212 3267 {
3213 3268 struct modctl *rmod;
3214 3269
3215 3270 ASSERT(MUTEX_HELD(&mod_lock));
3216 3271
3217 3272 /*
3218 3273 * Check the mod_inprogress_thread first.
3219 3274 * mod_inprogress_thread is used in mod_hold_stub()
3220 3275 * directly to improve performance.
3221 3276 */
3222 3277 if (modp->mod_inprogress_thread == curthread)
3223 3278 return (1);
3224 3279
3225 3280 /*
3226 3281 * Check the module circular dependencies.
3227 3282 */
3228 3283 for (rmod = modp; rmod != NULL; rmod = rmod->mod_requisite_loading) {
3229 3284 /*
3230 3285 * Check if there is a module circular dependency.
3231 3286 */
3232 3287 if (rmod->mod_requisite_loading == modp)
3233 3288 return (1);
3234 3289 }
3235 3290 return (0);
3236 3291 }
3237 3292
3238 3293 static int
3239 3294 mod_getinfo(struct modctl *modp, struct modinfo *modinfop)
3240 3295 {
3241 3296 int (*func)(struct modinfo *);
3242 3297 int retval;
3243 3298
3244 3299 ASSERT(modp->mod_busy);
3245 3300
3246 3301 /* primary modules don't do getinfo */
3247 3302 if (modp->mod_prim)
3248 3303 return (0);
3249 3304
3250 3305 func = (int (*)(struct modinfo *))kobj_lookup(modp->mod_mp, "_info");
3251 3306
3252 3307 if (kobj_addrcheck(modp->mod_mp, (caddr_t)func)) {
3253 3308 cmn_err(CE_WARN, "_info() not defined properly in %s",
3254 3309 modp->mod_filename);
3255 3310 /*
3256 3311 * The semantics of mod_info(9F) are that 0 is failure
3257 3312 * and non-zero is success.
3258 3313 */
3259 3314 retval = 0;
3260 3315 } else
3261 3316 retval = (*func)(modinfop); /* call _info() function */
3262 3317
3263 3318 if (moddebug & MODDEBUG_USERDEBUG)
3264 3319 printf("Returned from _info, retval = %x\n", retval);
3265 3320
3266 3321 return (retval);
3267 3322 }
3268 3323
3269 3324 static void
3270 3325 modadd(struct modctl *mp)
3271 3326 {
3272 3327 ASSERT(MUTEX_HELD(&mod_lock));
3273 3328
3274 3329 mp->mod_id = last_module_id++;
3275 3330 mp->mod_next = &modules;
3276 3331 mp->mod_prev = modules.mod_prev;
3277 3332 modules.mod_prev->mod_next = mp;
3278 3333 modules.mod_prev = mp;
3279 3334 }
3280 3335
3281 3336 /*ARGSUSED*/
3282 3337 static struct modctl *
3283 3338 allocate_modp(const char *filename, const char *modname)
3284 3339 {
3285 3340 struct modctl *mp;
3286 3341
3287 3342 mp = kobj_zalloc(sizeof (*mp), KM_SLEEP);
3288 3343 mp->mod_modname = kobj_zalloc(strlen(modname) + 1, KM_SLEEP);
3289 3344 (void) strcpy(mp->mod_modname, modname);
3290 3345 return (mp);
3291 3346 }
3292 3347
3293 3348 /*
3294 3349 * Get the value of a symbol. This is a wrapper routine that
3295 3350 * calls kobj_getsymvalue(). kobj_getsymvalue() may go away but this
3296 3351 * wrapper will prevent callers from noticing.
3297 3352 */
3298 3353 uintptr_t
3299 3354 modgetsymvalue(char *name, int kernelonly)
3300 3355 {
3301 3356 return (kobj_getsymvalue(name, kernelonly));
3302 3357 }
3303 3358
3304 3359 /*
3305 3360 * Get the symbol nearest an address. This is a wrapper routine that
3306 3361 * calls kobj_getsymname(). kobj_getsymname() may go away but this
3307 3362 * wrapper will prevent callers from noticing.
3308 3363 */
3309 3364 char *
3310 3365 modgetsymname(uintptr_t value, ulong_t *offset)
3311 3366 {
3312 3367 return (kobj_getsymname(value, offset));
3313 3368 }
3314 3369
3315 3370 /*
3316 3371 * Lookup a symbol in a specified module. These are wrapper routines that
3317 3372 * call kobj_lookup(). kobj_lookup() may go away but these wrappers will
3318 3373 * prevent callers from noticing.
3319 3374 */
3320 3375 uintptr_t
3321 3376 modlookup(const char *modname, const char *symname)
3322 3377 {
3323 3378 struct modctl *modp;
3324 3379 uintptr_t val;
3325 3380
3326 3381 if ((modp = mod_hold_by_name(modname)) == NULL)
3327 3382 return (0);
3328 3383 val = kobj_lookup(modp->mod_mp, symname);
3329 3384 mod_release_mod(modp);
3330 3385 return (val);
3331 3386 }
3332 3387
3333 3388 uintptr_t
3334 3389 modlookup_by_modctl(modctl_t *modp, const char *symname)
3335 3390 {
3336 3391 ASSERT(modp->mod_ref > 0 || modp->mod_busy);
3337 3392
3338 3393 return (kobj_lookup(modp->mod_mp, symname));
3339 3394 }
3340 3395
3341 3396 /*
3342 3397 * Ask the user for the name of the system file and the default path
3343 3398 * for modules.
3344 3399 */
3345 3400 void
3346 3401 mod_askparams()
3347 3402 {
3348 3403 static char s0[64];
3349 3404 intptr_t fd;
3350 3405
3351 3406 if ((fd = kobj_open(systemfile)) != -1L)
3352 3407 kobj_close(fd);
3353 3408 else
3354 3409 systemfile = NULL;
3355 3410
3356 3411 /*CONSTANTCONDITION*/
3357 3412 while (1) {
3358 3413 printf("Name of system file [%s]: ",
3359 3414 systemfile ? systemfile : "/dev/null");
3360 3415
3361 3416 console_gets(s0, sizeof (s0));
3362 3417
3363 3418 if (s0[0] == '\0')
3364 3419 break;
3365 3420 else if (strcmp(s0, "/dev/null") == 0) {
3366 3421 systemfile = NULL;
3367 3422 break;
3368 3423 } else {
3369 3424 if ((fd = kobj_open(s0)) != -1L) {
3370 3425 kobj_close(fd);
3371 3426 systemfile = s0;
3372 3427 break;
3373 3428 }
3374 3429 }
3375 3430 printf("can't find file %s\n", s0);
3376 3431 }
3377 3432 }
3378 3433
3379 3434 static char loading_msg[] = "loading '%s' id %d\n";
3380 3435 static char load_msg[] = "load '%s' id %d loaded @ 0x%p/0x%p size %d/%d\n";
3381 3436
3382 3437 /*
3383 3438 * Common code for loading a module (but not installing it).
3384 3439 * Handoff the task of module loading to a separate thread
3385 3440 * with a large stack if possible, since this code may recurse a few times.
3386 3441 * Return zero if there are no errors or an errno value.
3387 3442 */
3388 3443 static int
3389 3444 mod_load(struct modctl *mp, int usepath)
3390 3445 {
3391 3446 int retval;
3392 3447 struct modinfo *modinfop = NULL;
3393 3448 struct loadmt lt;
3394 3449
3395 3450 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3396 3451 ASSERT(mp->mod_busy);
3397 3452
3398 3453 if (mp->mod_loaded)
3399 3454 return (0);
3400 3455
3401 3456 if (mod_sysctl(SYS_CHECK_EXCLUDE, mp->mod_modname) != 0 ||
3402 3457 mod_sysctl(SYS_CHECK_EXCLUDE, mp->mod_filename) != 0) {
3403 3458 if (moddebug & MODDEBUG_LOADMSG) {
3404 3459 printf(mod_excl_msg, mp->mod_filename,
3405 3460 mp->mod_modname);
3406 3461 }
3407 3462 return (ENXIO);
3408 3463 }
3409 3464 if (moddebug & MODDEBUG_LOADMSG2)
3410 3465 printf(loading_msg, mp->mod_filename, mp->mod_id);
3411 3466
3412 3467 if (curthread != &t0) {
3413 3468 lt.mp = mp;
3414 3469 lt.usepath = usepath;
3415 3470 lt.owner = curthread;
3416 3471 sema_init(<.sema, 0, NULL, SEMA_DEFAULT, NULL);
3417 3472
3418 3473 /* create thread to hand of call to */
3419 3474 (void) thread_create(NULL, DEFAULTSTKSZ * 2,
3420 3475 modload_thread, <, 0, &p0, TS_RUN, maxclsyspri);
3421 3476
3422 3477 /* wait for thread to complete kobj_load_module */
3423 3478 sema_p(<.sema);
3424 3479
3425 3480 sema_destroy(<.sema);
3426 3481 retval = lt.retval;
3427 3482 } else
3428 3483 retval = kobj_load_module(mp, usepath);
3429 3484
3430 3485 if (mp->mod_mp) {
3431 3486 ASSERT(retval == 0);
3432 3487 mp->mod_loaded = 1;
3433 3488 mp->mod_loadcnt++;
3434 3489 if (moddebug & MODDEBUG_LOADMSG) {
3435 3490 printf(load_msg, mp->mod_filename, mp->mod_id,
3436 3491 (void *)((struct module *)mp->mod_mp)->text,
3437 3492 (void *)((struct module *)mp->mod_mp)->data,
3438 3493 ((struct module *)mp->mod_mp)->text_size,
3439 3494 ((struct module *)mp->mod_mp)->data_size);
3440 3495 }
3441 3496
3442 3497 /*
3443 3498 * XXX - There should be a better way to get this.
3444 3499 */
3445 3500 modinfop = kmem_zalloc(sizeof (struct modinfo), KM_SLEEP);
3446 3501 modinfop->mi_info = MI_INFO_LINKAGE;
3447 3502 if (mod_getinfo(mp, modinfop) == 0)
3448 3503 mp->mod_linkage = NULL;
3449 3504 else {
3450 3505 mp->mod_linkage = (void *)modinfop->mi_base;
3451 3506 ASSERT(mp->mod_linkage->ml_rev == MODREV_1);
3452 3507 }
3453 3508
3454 3509 /*
3455 3510 * DCS: bootstrapping code. If the driver is loaded
3456 3511 * before root mount, it is assumed that the driver
3457 3512 * may be used before mounting root. In order to
3458 3513 * access mappings of global to local minor no.'s
3459 3514 * during installation/open of the driver, we load
3460 3515 * them into memory here while the BOP_interfaces
3461 3516 * are still up.
3462 3517 */
3463 3518 if ((cluster_bootflags & CLUSTER_BOOTED) && !modrootloaded) {
3464 3519 retval = clboot_modload(mp);
3465 3520 }
3466 3521
3467 3522 kmem_free(modinfop, sizeof (struct modinfo));
3468 3523 (void) mod_sysctl(SYS_SET_MVAR, (void *)mp);
3469 3524 retval = install_stubs_by_name(mp, mp->mod_modname);
3470 3525
3471 3526 /*
3472 3527 * Now that the module is loaded, we need to give DTrace
3473 3528 * a chance to notify its providers. This is done via
3474 3529 * the dtrace_modload function pointer.
3475 3530 */
3476 3531 if (strcmp(mp->mod_modname, "dtrace") != 0) {
3477 3532 struct modctl *dmp = mod_hold_by_name("dtrace");
3478 3533
3479 3534 if (dmp != NULL && dtrace_modload != NULL)
3480 3535 (*dtrace_modload)(mp);
3481 3536
3482 3537 mod_release_mod(dmp);
3483 3538 }
3484 3539
3485 3540 } else {
3486 3541 /*
3487 3542 * If load failed then we need to release any requisites
3488 3543 * that we had established.
3489 3544 */
3490 3545 ASSERT(retval);
3491 3546 mod_release_requisites(mp);
3492 3547
3493 3548 if (moddebug & MODDEBUG_ERRMSG)
3494 3549 printf("error loading '%s', error %d\n",
3495 3550 mp->mod_filename, retval);
3496 3551 }
3497 3552 return (retval);
3498 3553 }
3499 3554
3500 3555 static char unload_msg[] = "unloading %s, module id %d, loadcnt %d.\n";
3501 3556
3502 3557 static void
3503 3558 mod_unload(struct modctl *mp)
3504 3559 {
3505 3560 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3506 3561 ASSERT(mp->mod_busy);
3507 3562 ASSERT((mp->mod_loaded && (mp->mod_installed == 0)) &&
3508 3563 ((mp->mod_prim == 0) && (mp->mod_ref >= 0)));
3509 3564
3510 3565 if (moddebug & MODDEBUG_LOADMSG)
3511 3566 printf(unload_msg, mp->mod_modname,
3512 3567 mp->mod_id, mp->mod_loadcnt);
3513 3568
3514 3569 /*
3515 3570 * If mod_ref is not zero, it means some modules might still refer
3516 3571 * to this module. Then you can't unload this module right now.
3517 3572 * Instead, set 1 to mod_delay_unload to notify the system of
3518 3573 * unloading this module later when it's not required any more.
3519 3574 */
3520 3575 if (mp->mod_ref > 0) {
3521 3576 mp->mod_delay_unload = 1;
3522 3577 if (moddebug & MODDEBUG_LOADMSG2) {
3523 3578 printf("module %s not unloaded,"
3524 3579 " non-zero reference count (%d)",
3525 3580 mp->mod_modname, mp->mod_ref);
3526 3581 }
3527 3582 return;
3528 3583 }
3529 3584
3530 3585 if (((mp->mod_loaded == 0) || mp->mod_installed) ||
3531 3586 (mp->mod_ref || mp->mod_prim)) {
3532 3587 /*
3533 3588 * A DEBUG kernel would ASSERT panic above, the code is broken
3534 3589 * if we get this warning.
3535 3590 */
3536 3591 cmn_err(CE_WARN, "mod_unload: %s in incorrect state: %d %d %d",
3537 3592 mp->mod_filename, mp->mod_installed, mp->mod_loaded,
3538 3593 mp->mod_ref);
3539 3594 return;
3540 3595 }
3541 3596
3542 3597 /* reset stub functions to call the binder again */
3543 3598 reset_stubs(mp);
3544 3599
3545 3600 /*
3546 3601 * mark module as unloaded before the modctl structure is freed.
3547 3602 * This is required not to reuse the modctl structure before
3548 3603 * the module is marked as unloaded.
3549 3604 */
3550 3605 mp->mod_loaded = 0;
3551 3606 mp->mod_linkage = NULL;
3552 3607
3553 3608 /* free the memory */
3554 3609 kobj_unload_module(mp);
3555 3610
3556 3611 if (mp->mod_delay_unload) {
3557 3612 mp->mod_delay_unload = 0;
3558 3613 if (moddebug & MODDEBUG_LOADMSG2) {
3559 3614 printf("deferred unload of module %s"
3560 3615 " (id %d) successful",
3561 3616 mp->mod_modname, mp->mod_id);
3562 3617 }
3563 3618 }
3564 3619
3565 3620 /* release hold on requisites */
3566 3621 mod_release_requisites(mp);
3567 3622
3568 3623 /*
3569 3624 * Now that the module is gone, we need to give DTrace a chance to
3570 3625 * remove any probes that it may have had in the module. This is
3571 3626 * done via the dtrace_modunload function pointer.
3572 3627 */
3573 3628 if (strcmp(mp->mod_modname, "dtrace") != 0) {
3574 3629 struct modctl *dmp = mod_hold_by_name("dtrace");
3575 3630
3576 3631 if (dmp != NULL && dtrace_modunload != NULL)
3577 3632 (*dtrace_modunload)(mp);
3578 3633
3579 3634 mod_release_mod(dmp);
3580 3635 }
3581 3636 }
3582 3637
3583 3638 static int
3584 3639 modinstall(struct modctl *mp)
3585 3640 {
3586 3641 int val;
3587 3642 int (*func)(void);
3588 3643
3589 3644 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3590 3645 ASSERT(mp->mod_busy && mp->mod_loaded);
3591 3646
3592 3647 if (mp->mod_installed)
3593 3648 return (0);
3594 3649 /*
3595 3650 * If mod_delay_unload is on, it means the system chose the deferred
3596 3651 * unload for this module. Then you can't install this module until
3597 3652 * it's unloaded from the system.
3598 3653 */
3599 3654 if (mp->mod_delay_unload)
3600 3655 return (ENXIO);
3601 3656
3602 3657 if (moddebug & MODDEBUG_LOADMSG)
3603 3658 printf("installing %s, module id %d.\n",
3604 3659 mp->mod_modname, mp->mod_id);
3605 3660
3606 3661 ASSERT(mp->mod_mp != NULL);
3607 3662 if (mod_install_requisites(mp) != 0) {
3608 3663 /*
3609 3664 * Note that we can't call mod_unload(mp) here since
3610 3665 * if modinstall() was called by mod_install_requisites(),
3611 3666 * we won't be able to hold the dependent modules
3612 3667 * (otherwise there would be a deadlock).
3613 3668 */
3614 3669 return (ENXIO);
3615 3670 }
3616 3671
3617 3672 if (moddebug & MODDEBUG_ERRMSG) {
3618 3673 printf("init '%s' id %d loaded @ 0x%p/0x%p size %lu/%lu\n",
3619 3674 mp->mod_filename, mp->mod_id,
3620 3675 (void *)((struct module *)mp->mod_mp)->text,
3621 3676 (void *)((struct module *)mp->mod_mp)->data,
3622 3677 ((struct module *)mp->mod_mp)->text_size,
3623 3678 ((struct module *)mp->mod_mp)->data_size);
3624 3679 }
3625 3680
3626 3681 func = (int (*)())kobj_lookup(mp->mod_mp, "_init");
3627 3682
3628 3683 if (kobj_addrcheck(mp->mod_mp, (caddr_t)func)) {
3629 3684 cmn_err(CE_WARN, "_init() not defined properly in %s",
3630 3685 mp->mod_filename);
3631 3686 return (EFAULT);
3632 3687 }
3633 3688
3634 3689 if (moddebug & MODDEBUG_USERDEBUG) {
3635 3690 printf("breakpoint before calling %s:_init()\n",
3636 3691 mp->mod_modname);
3637 3692 if (DEBUGGER_PRESENT)
3638 3693 debug_enter("_init");
3639 3694 }
3640 3695
3641 3696 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3642 3697 ASSERT(mp->mod_busy && mp->mod_loaded);
3643 3698 val = (*func)(); /* call _init */
3644 3699
3645 3700 if (moddebug & MODDEBUG_USERDEBUG)
3646 3701 printf("Returned from _init, val = %x\n", val);
3647 3702
3648 3703 if (val == 0) {
3649 3704 /*
3650 3705 * Set the MODS_INSTALLED flag to enable this module
3651 3706 * being called now.
3652 3707 */
3653 3708 install_stubs(mp);
3654 3709 mp->mod_installed = 1;
3655 3710 } else if (moddebug & MODDEBUG_ERRMSG)
3656 3711 printf(mod_init_msg, mp->mod_filename, mp->mod_modname, val);
3657 3712
3658 3713 return (val);
3659 3714 }
3660 3715
3661 3716 int detach_driver_unconfig = 0;
3662 3717
3663 3718 static int
3664 3719 detach_driver(char *name)
3665 3720 {
3666 3721 major_t major;
3667 3722 int error;
3668 3723
3669 3724 /*
3670 3725 * If being called from mod_uninstall_all() then the appropriate
3671 3726 * driver detaches (leaf only) have already been done.
3672 3727 */
3673 3728 if (mod_in_autounload())
3674 3729 return (0);
3675 3730
3676 3731 major = ddi_name_to_major(name);
3677 3732 if (major == DDI_MAJOR_T_NONE)
3678 3733 return (0);
3679 3734
3680 3735 error = ndi_devi_unconfig_driver(ddi_root_node(),
3681 3736 NDI_DETACH_DRIVER | detach_driver_unconfig, major);
3682 3737 return (error == NDI_SUCCESS ? 0 : -1);
3683 3738 }
3684 3739
3685 3740 static char finiret_msg[] = "Returned from _fini for %s, status = %x\n";
3686 3741
3687 3742 static int
3688 3743 moduninstall(struct modctl *mp)
3689 3744 {
3690 3745 int status = 0;
3691 3746 int (*func)(void);
3692 3747
3693 3748 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3694 3749 ASSERT(mp->mod_busy);
3695 3750
3696 3751 /*
3697 3752 * Verify that we need to do something and can uninstall the module.
3698 3753 *
3699 3754 * If we should not uninstall the module or if the module is not in
3700 3755 * the correct state to start an uninstall we return EBUSY to prevent
3701 3756 * us from progressing to mod_unload. If the module has already been
3702 3757 * uninstalled and unloaded we return EALREADY.
3703 3758 */
3704 3759 if (mp->mod_prim || mp->mod_ref || mp->mod_nenabled != 0)
3705 3760 return (EBUSY);
3706 3761 if ((mp->mod_installed == 0) || (mp->mod_loaded == 0))
3707 3762 return (EALREADY);
3708 3763
3709 3764 /*
3710 3765 * To avoid devinfo / module deadlock we must release this module
3711 3766 * prior to initiating the detach_driver, otherwise the detach_driver
3712 3767 * might deadlock on a devinfo node held by another thread
3713 3768 * coming top down and involving the module we have locked.
3714 3769 *
3715 3770 * When we regrab the module we must reverify that it is OK
3716 3771 * to proceed with the uninstall operation.
3717 3772 */
3718 3773 mod_release_mod(mp);
3719 3774 status = detach_driver(mp->mod_modname);
3720 3775 (void) mod_hold_by_modctl(mp, MOD_WAIT_FOREVER | MOD_LOCK_NOT_HELD);
3721 3776
3722 3777 /* check detach status and reverify state with lock */
3723 3778 mutex_enter(&mod_lock);
3724 3779 if ((status != 0) || mp->mod_prim || mp->mod_ref) {
3725 3780 mutex_exit(&mod_lock);
3726 3781 return (EBUSY);
3727 3782 }
3728 3783 if ((mp->mod_installed == 0) || (mp->mod_loaded == 0)) {
3729 3784 mutex_exit(&mod_lock);
3730 3785 return (EALREADY);
3731 3786 }
3732 3787 mutex_exit(&mod_lock);
3733 3788
3734 3789 if (moddebug & MODDEBUG_LOADMSG2)
3735 3790 printf("uninstalling %s\n", mp->mod_modname);
3736 3791
3737 3792 /*
3738 3793 * lookup _fini, return EBUSY if not defined.
3739 3794 *
3740 3795 * The MODDEBUG_FINI_EBUSY is usefull in resolving leaks in
3741 3796 * detach(9E) - it allows bufctl addresses to be resolved.
3742 3797 */
3743 3798 func = (int (*)())kobj_lookup(mp->mod_mp, "_fini");
3744 3799 if ((func == NULL) || (mp->mod_loadflags & MOD_NOUNLOAD) ||
3745 3800 (moddebug & MODDEBUG_FINI_EBUSY))
3746 3801 return (EBUSY);
3747 3802
3748 3803 /* verify that _fini is in this module */
3749 3804 if (kobj_addrcheck(mp->mod_mp, (caddr_t)func)) {
3750 3805 cmn_err(CE_WARN, "_fini() not defined properly in %s",
3751 3806 mp->mod_filename);
3752 3807 return (EFAULT);
3753 3808 }
3754 3809
3755 3810 /* call _fini() */
3756 3811 ASSERT(MUTEX_NOT_HELD(&mod_lock));
3757 3812 ASSERT(mp->mod_busy && mp->mod_loaded && mp->mod_installed);
3758 3813
3759 3814 status = (*func)();
3760 3815
3761 3816 if (status == 0) {
3762 3817 /* _fini returned success, the module is no longer installed */
3763 3818 if (moddebug & MODDEBUG_LOADMSG)
3764 3819 printf("uninstalled %s\n", mp->mod_modname);
3765 3820
3766 3821 /*
3767 3822 * Even though we only set mod_installed to zero here, a zero
3768 3823 * return value means we are committed to a code path were
3769 3824 * mod_loaded will also end up as zero - we have no other
3770 3825 * way to get the module data and bss back to the pre _init
3771 3826 * state except a reload. To ensure this, after return,
3772 3827 * mod_busy must stay set until mod_loaded is cleared.
3773 3828 */
3774 3829 mp->mod_installed = 0;
3775 3830
3776 3831 /*
3777 3832 * Clear the MODS_INSTALLED flag not to call functions
3778 3833 * in the module directly from now on.
3779 3834 */
3780 3835 uninstall_stubs(mp);
3781 3836 } else {
3782 3837 if (moddebug & MODDEBUG_USERDEBUG)
3783 3838 printf(finiret_msg, mp->mod_filename, status);
3784 3839 /*
3785 3840 * By definition _fini is only allowed to return EBUSY or the
3786 3841 * result of mod_remove (EBUSY or EINVAL). In the off chance
3787 3842 * that a driver returns EALREADY we convert this to EINVAL
3788 3843 * since to our caller EALREADY means module was already
3789 3844 * removed.
3790 3845 */
3791 3846 if (status == EALREADY)
3792 3847 status = EINVAL;
3793 3848 }
3794 3849
3795 3850 return (status);
3796 3851 }
3797 3852
3798 3853 /*
3799 3854 * Uninstall all modules.
3800 3855 */
3801 3856 static void
3802 3857 mod_uninstall_all(void)
3803 3858 {
3804 3859 struct modctl *mp;
3805 3860 int pass;
3806 3861 modid_t modid;
3807 3862
3808 3863 /* synchronize with any active modunload_disable() */
3809 3864 modunload_begin();
3810 3865
3811 3866 /* mark this thread as doing autounloading */
3812 3867 (void) tsd_set(mod_autounload_key, (void *)1);
3813 3868
3814 3869 (void) devfs_clean(ddi_root_node(), NULL, 0);
3815 3870 (void) ndi_devi_unconfig(ddi_root_node(), NDI_AUTODETACH);
3816 3871
3817 3872 /*
3818 3873 * Loop up to max times if we keep producing unreferenced modules.
3819 3874 * A new unreferenced module is an opportunity to unload.
3820 3875 */
3821 3876 for (pass = 0; pass < mod_uninstall_pass_max; pass++) {
3822 3877
3823 3878 /* zero count of modules that go unreferenced during pass */
3824 3879 mod_uninstall_ref_zero = 0;
3825 3880
3826 3881 modid = 0;
3827 3882 while ((mp = mod_hold_next_by_id(modid)) != NULL) {
3828 3883 modid = mp->mod_id;
3829 3884
3830 3885 /*
3831 3886 * Skip modules with the MOD_NOAUTOUNLOAD flag set
3832 3887 */
3833 3888 if (mp->mod_loadflags & MOD_NOAUTOUNLOAD) {
3834 3889 mod_release_mod(mp);
3835 3890 continue;
3836 3891 }
3837 3892
3838 3893 if (moduninstall(mp) == 0) {
3839 3894 mod_unload(mp);
3840 3895 CPU_STATS_ADDQ(CPU, sys, modunload, 1);
3841 3896 }
3842 3897 mod_release_mod(mp);
3843 3898 }
3844 3899
3845 3900 /* break if no modules went unreferenced during pass */
3846 3901 if (mod_uninstall_ref_zero == 0)
3847 3902 break;
3848 3903 }
3849 3904 if (pass >= mod_uninstall_pass_max)
3850 3905 mod_uninstall_pass_exc++;
3851 3906
3852 3907 (void) tsd_set(mod_autounload_key, NULL);
3853 3908 modunload_end();
3854 3909 }
3855 3910
3856 3911 /* wait for unloads that have begun before registering disable */
3857 3912 void
3858 3913 modunload_disable(void)
3859 3914 {
3860 3915 mutex_enter(&modunload_wait_mutex);
3861 3916 while (modunload_active_count) {
3862 3917 modunload_wait++;
3863 3918 cv_wait(&modunload_wait_cv, &modunload_wait_mutex);
3864 3919 modunload_wait--;
3865 3920 }
3866 3921 modunload_disable_count++;
3867 3922 mutex_exit(&modunload_wait_mutex);
3868 3923 }
3869 3924
3870 3925 /* mark end of disable and signal waiters */
3871 3926 void
3872 3927 modunload_enable(void)
3873 3928 {
3874 3929 mutex_enter(&modunload_wait_mutex);
3875 3930 modunload_disable_count--;
3876 3931 if ((modunload_disable_count == 0) && modunload_wait)
3877 3932 cv_broadcast(&modunload_wait_cv);
3878 3933 mutex_exit(&modunload_wait_mutex);
3879 3934 }
3880 3935
3881 3936 /* wait for disables to complete before begining unload */
3882 3937 void
3883 3938 modunload_begin()
3884 3939 {
3885 3940 mutex_enter(&modunload_wait_mutex);
3886 3941 while (modunload_disable_count) {
3887 3942 modunload_wait++;
3888 3943 cv_wait(&modunload_wait_cv, &modunload_wait_mutex);
3889 3944 modunload_wait--;
3890 3945 }
3891 3946 modunload_active_count++;
3892 3947 mutex_exit(&modunload_wait_mutex);
3893 3948 }
3894 3949
3895 3950 /* mark end of unload and signal waiters */
3896 3951 void
3897 3952 modunload_end()
3898 3953 {
3899 3954 mutex_enter(&modunload_wait_mutex);
3900 3955 modunload_active_count--;
3901 3956 if ((modunload_active_count == 0) && modunload_wait)
3902 3957 cv_broadcast(&modunload_wait_cv);
3903 3958 mutex_exit(&modunload_wait_mutex);
3904 3959 }
3905 3960
3906 3961 void
3907 3962 mod_uninstall_daemon(void)
3908 3963 {
3909 3964 callb_cpr_t cprinfo;
3910 3965 clock_t ticks;
3911 3966
3912 3967 mod_aul_thread = curthread;
3913 3968
3914 3969 CALLB_CPR_INIT(&cprinfo, &mod_uninstall_lock, callb_generic_cpr, "mud");
3915 3970 for (;;) {
3916 3971 mutex_enter(&mod_uninstall_lock);
3917 3972 CALLB_CPR_SAFE_BEGIN(&cprinfo);
3918 3973 /*
3919 3974 * In DEBUG kernels, unheld drivers are uninstalled periodically
3920 3975 * every mod_uninstall_interval seconds. Periodic uninstall can
3921 3976 * be disabled by setting mod_uninstall_interval to 0 which is
3922 3977 * the default for a non-DEBUG kernel.
3923 3978 */
3924 3979 if (mod_uninstall_interval) {
3925 3980 ticks = drv_usectohz(mod_uninstall_interval * 1000000);
3926 3981 (void) cv_reltimedwait(&mod_uninstall_cv,
3927 3982 &mod_uninstall_lock, ticks, TR_CLOCK_TICK);
3928 3983 } else {
3929 3984 cv_wait(&mod_uninstall_cv, &mod_uninstall_lock);
3930 3985 }
3931 3986 /*
3932 3987 * The whole daemon is safe for CPR except we don't want
3933 3988 * the daemon to run if FREEZE is issued and this daemon
3934 3989 * wakes up from the cv_wait above. In this case, it'll be
3935 3990 * blocked in CALLB_CPR_SAFE_END until THAW is issued.
3936 3991 *
3937 3992 * The reason of calling CALLB_CPR_SAFE_BEGIN twice is that
3938 3993 * mod_uninstall_lock is used to protect cprinfo and
3939 3994 * CALLB_CPR_SAFE_BEGIN assumes that this lock is held when
3940 3995 * called.
3941 3996 */
3942 3997 CALLB_CPR_SAFE_END(&cprinfo, &mod_uninstall_lock);
3943 3998 CALLB_CPR_SAFE_BEGIN(&cprinfo);
3944 3999 mutex_exit(&mod_uninstall_lock);
3945 4000 if ((modunload_disable_count == 0) &&
3946 4001 ((moddebug & MODDEBUG_NOAUTOUNLOAD) == 0)) {
3947 4002 mod_uninstall_all();
3948 4003 }
3949 4004 }
3950 4005 }
3951 4006
3952 4007 /*
3953 4008 * Unload all uninstalled modules.
3954 4009 */
3955 4010 void
3956 4011 modreap(void)
3957 4012 {
3958 4013 mutex_enter(&mod_uninstall_lock);
3959 4014 cv_broadcast(&mod_uninstall_cv);
3960 4015 mutex_exit(&mod_uninstall_lock);
3961 4016 }
3962 4017
3963 4018 /*
3964 4019 * Hold the specified module. This is the module holding primitive.
3965 4020 *
3966 4021 * If MOD_LOCK_HELD then the caller already holds the mod_lock.
3967 4022 *
3968 4023 * Return values:
3969 4024 * 0 ==> the module is held
3970 4025 * 1 ==> the module is not held and the MOD_WAIT_ONCE caller needs
3971 4026 * to determine how to retry.
3972 4027 */
3973 4028 int
3974 4029 mod_hold_by_modctl(struct modctl *mp, int f)
3975 4030 {
3976 4031 ASSERT((f & (MOD_WAIT_ONCE | MOD_WAIT_FOREVER)) &&
3977 4032 ((f & (MOD_WAIT_ONCE | MOD_WAIT_FOREVER)) !=
3978 4033 (MOD_WAIT_ONCE | MOD_WAIT_FOREVER)));
3979 4034 ASSERT((f & (MOD_LOCK_HELD | MOD_LOCK_NOT_HELD)) &&
3980 4035 ((f & (MOD_LOCK_HELD | MOD_LOCK_NOT_HELD)) !=
3981 4036 (MOD_LOCK_HELD | MOD_LOCK_NOT_HELD)));
3982 4037 ASSERT((f & MOD_LOCK_NOT_HELD) || MUTEX_HELD(&mod_lock));
3983 4038
3984 4039 if (f & MOD_LOCK_NOT_HELD)
3985 4040 mutex_enter(&mod_lock);
3986 4041
3987 4042 while (mp->mod_busy) {
3988 4043 mp->mod_want = 1;
3989 4044 cv_wait(&mod_cv, &mod_lock);
3990 4045 /*
3991 4046 * Module may be unloaded by daemon.
3992 4047 * Nevertheless, modctl structure is still in linked list
3993 4048 * (i.e., off &modules), not freed!
3994 4049 * Caller is not supposed to assume "mp" is valid, but there
3995 4050 * is no reasonable way to detect this but using
3996 4051 * mp->mod_modinfo->mp == NULL check (follow the back pointer)
3997 4052 * (or similar check depending on calling context)
3998 4053 * DON'T free modctl structure, it will be very very
3999 4054 * problematic.
4000 4055 */
4001 4056 if (f & MOD_WAIT_ONCE) {
4002 4057 if (f & MOD_LOCK_NOT_HELD)
4003 4058 mutex_exit(&mod_lock);
4004 4059 return (1); /* caller decides how to retry */
4005 4060 }
4006 4061 }
4007 4062
4008 4063 mp->mod_busy = 1;
4009 4064 mp->mod_inprogress_thread =
4010 4065 (curthread == NULL ? (kthread_id_t)-1 : curthread);
4011 4066
4012 4067 if (f & MOD_LOCK_NOT_HELD)
4013 4068 mutex_exit(&mod_lock);
4014 4069 return (0);
4015 4070 }
4016 4071
4017 4072 static struct modctl *
4018 4073 mod_hold_by_name_common(struct modctl *dep, const char *filename)
4019 4074 {
4020 4075 const char *modname;
4021 4076 struct modctl *mp;
4022 4077 char *curname, *newname;
4023 4078 int found = 0;
4024 4079
4025 4080 mutex_enter(&mod_lock);
4026 4081
4027 4082 if ((modname = strrchr(filename, '/')) == NULL)
4028 4083 modname = filename;
4029 4084 else
4030 4085 modname++;
4031 4086
4032 4087 mp = &modules;
4033 4088 do {
4034 4089 if (strcmp(modname, mp->mod_modname) == 0) {
4035 4090 found = 1;
4036 4091 break;
4037 4092 }
4038 4093 } while ((mp = mp->mod_next) != &modules);
4039 4094
4040 4095 if (found == 0) {
4041 4096 mp = allocate_modp(filename, modname);
4042 4097 modadd(mp);
4043 4098 }
4044 4099
4045 4100 /*
4046 4101 * if dep is not NULL, set the mp in mod_requisite_loading for
4047 4102 * the module circular dependency check. This field is used in
4048 4103 * mod_circdep(), but it's cleard in mod_hold_loaded_mod().
4049 4104 */
4050 4105 if (dep != NULL) {
4051 4106 ASSERT(dep->mod_busy && dep->mod_requisite_loading == NULL);
4052 4107 dep->mod_requisite_loading = mp;
4053 4108 }
4054 4109
4055 4110 /*
4056 4111 * If the module was held, then it must be us who has it held.
4057 4112 */
4058 4113 if (mod_circdep(mp))
4059 4114 mp = NULL;
4060 4115 else {
4061 4116 (void) mod_hold_by_modctl(mp, MOD_WAIT_FOREVER | MOD_LOCK_HELD);
4062 4117
4063 4118 /*
4064 4119 * If the name hadn't been set or has changed, allocate
4065 4120 * space and set it. Free space used by previous name.
4066 4121 *
4067 4122 * Do not change the name of primary modules, for primary
4068 4123 * modules the mod_filename was allocated in standalone mode:
4069 4124 * it is illegal to kobj_alloc in standalone mode and kobj_free
4070 4125 * in non-standalone mode.
4071 4126 */
4072 4127 curname = mp->mod_filename;
4073 4128 if (curname == NULL ||
4074 4129 ((mp->mod_prim == 0) &&
4075 4130 (curname != filename) &&
4076 4131 (modname != filename) &&
4077 4132 (strcmp(curname, filename) != 0))) {
4078 4133 newname = kobj_zalloc(strlen(filename) + 1, KM_SLEEP);
4079 4134 (void) strcpy(newname, filename);
4080 4135 mp->mod_filename = newname;
4081 4136 if (curname != NULL)
4082 4137 kobj_free(curname, strlen(curname) + 1);
4083 4138 }
4084 4139 }
4085 4140
4086 4141 mutex_exit(&mod_lock);
4087 4142 if (mp && moddebug & MODDEBUG_LOADMSG2)
4088 4143 printf("Holding %s\n", mp->mod_filename);
4089 4144 if (mp == NULL && moddebug & MODDEBUG_LOADMSG2)
4090 4145 printf("circular dependency loading %s\n", filename);
4091 4146 return (mp);
4092 4147 }
4093 4148
4094 4149 static struct modctl *
4095 4150 mod_hold_by_name_requisite(struct modctl *dep, char *filename)
4096 4151 {
4097 4152 return (mod_hold_by_name_common(dep, filename));
4098 4153 }
4099 4154
4100 4155 struct modctl *
4101 4156 mod_hold_by_name(const char *filename)
4102 4157 {
4103 4158 return (mod_hold_by_name_common(NULL, filename));
4104 4159 }
4105 4160
4106 4161 struct modctl *
4107 4162 mod_hold_by_id(modid_t modid)
4108 4163 {
4109 4164 struct modctl *mp;
4110 4165 int found = 0;
4111 4166
4112 4167 mutex_enter(&mod_lock);
4113 4168 mp = &modules;
4114 4169 do {
4115 4170 if (mp->mod_id == modid) {
4116 4171 found = 1;
4117 4172 break;
4118 4173 }
4119 4174 } while ((mp = mp->mod_next) != &modules);
4120 4175
4121 4176 if ((found == 0) || mod_circdep(mp))
4122 4177 mp = NULL;
4123 4178 else
4124 4179 (void) mod_hold_by_modctl(mp, MOD_WAIT_FOREVER | MOD_LOCK_HELD);
4125 4180
4126 4181 mutex_exit(&mod_lock);
4127 4182 return (mp);
4128 4183 }
4129 4184
4130 4185 static struct modctl *
4131 4186 mod_hold_next_by_id(modid_t modid)
4132 4187 {
4133 4188 struct modctl *mp;
4134 4189 int found = 0;
4135 4190
4136 4191 if (modid < -1)
4137 4192 return (NULL);
4138 4193
4139 4194 mutex_enter(&mod_lock);
4140 4195
4141 4196 mp = &modules;
4142 4197 do {
4143 4198 if (mp->mod_id > modid) {
4144 4199 found = 1;
4145 4200 break;
4146 4201 }
4147 4202 } while ((mp = mp->mod_next) != &modules);
4148 4203
4149 4204 if ((found == 0) || mod_circdep(mp))
4150 4205 mp = NULL;
4151 4206 else
4152 4207 (void) mod_hold_by_modctl(mp, MOD_WAIT_FOREVER | MOD_LOCK_HELD);
4153 4208
4154 4209 mutex_exit(&mod_lock);
4155 4210 return (mp);
4156 4211 }
4157 4212
4158 4213 static void
4159 4214 mod_release(struct modctl *mp)
4160 4215 {
4161 4216 ASSERT(MUTEX_HELD(&mod_lock));
4162 4217 ASSERT(mp->mod_busy);
4163 4218
4164 4219 mp->mod_busy = 0;
4165 4220 mp->mod_inprogress_thread = NULL;
4166 4221 if (mp->mod_want) {
4167 4222 mp->mod_want = 0;
4168 4223 cv_broadcast(&mod_cv);
4169 4224 }
4170 4225 }
4171 4226
4172 4227 void
4173 4228 mod_release_mod(struct modctl *mp)
4174 4229 {
4175 4230 if (moddebug & MODDEBUG_LOADMSG2)
4176 4231 printf("Releasing %s\n", mp->mod_filename);
4177 4232 mutex_enter(&mod_lock);
4178 4233 mod_release(mp);
4179 4234 mutex_exit(&mod_lock);
4180 4235 }
4181 4236
4182 4237 modid_t
4183 4238 mod_name_to_modid(char *filename)
4184 4239 {
4185 4240 char *modname;
4186 4241 struct modctl *mp;
4187 4242
4188 4243 mutex_enter(&mod_lock);
4189 4244
4190 4245 if ((modname = strrchr(filename, '/')) == NULL)
4191 4246 modname = filename;
4192 4247 else
4193 4248 modname++;
4194 4249
4195 4250 mp = &modules;
4196 4251 do {
4197 4252 if (strcmp(modname, mp->mod_modname) == 0) {
4198 4253 mutex_exit(&mod_lock);
4199 4254 return (mp->mod_id);
4200 4255 }
4201 4256 } while ((mp = mp->mod_next) != &modules);
4202 4257
4203 4258 mutex_exit(&mod_lock);
4204 4259 return (-1);
4205 4260 }
4206 4261
4207 4262
4208 4263 int
4209 4264 mod_remove_by_name(char *name)
4210 4265 {
4211 4266 struct modctl *mp;
4212 4267 int retval;
4213 4268
4214 4269 mp = mod_hold_by_name(name);
4215 4270
4216 4271 if (mp == NULL)
4217 4272 return (EINVAL);
4218 4273
4219 4274 if (mp->mod_loadflags & MOD_NOAUTOUNLOAD) {
4220 4275 /*
4221 4276 * Do not unload forceloaded modules
4222 4277 */
4223 4278 mod_release_mod(mp);
4224 4279 return (0);
4225 4280 }
4226 4281
4227 4282 if ((retval = moduninstall(mp)) == 0) {
4228 4283 mod_unload(mp);
4229 4284 CPU_STATS_ADDQ(CPU, sys, modunload, 1);
4230 4285 } else if (retval == EALREADY)
4231 4286 retval = 0; /* already unloaded, not an error */
4232 4287 mod_release_mod(mp);
4233 4288 return (retval);
4234 4289 }
4235 4290
4236 4291 /*
4237 4292 * Record that module "dep" is dependent on module "on_mod."
4238 4293 */
4239 4294 static void
4240 4295 mod_make_requisite(struct modctl *dependent, struct modctl *on_mod)
4241 4296 {
4242 4297 struct modctl_list **pmlnp; /* previous next pointer */
4243 4298 struct modctl_list *mlp;
4244 4299 struct modctl_list *new;
4245 4300
4246 4301 ASSERT(dependent->mod_busy && on_mod->mod_busy);
4247 4302 mutex_enter(&mod_lock);
4248 4303
4249 4304 /*
4250 4305 * Search dependent's requisite list to see if on_mod is recorded.
4251 4306 * List is ordered by id.
4252 4307 */
4253 4308 for (pmlnp = &dependent->mod_requisites, mlp = *pmlnp;
4254 4309 mlp; pmlnp = &mlp->modl_next, mlp = *pmlnp)
4255 4310 if (mlp->modl_modp->mod_id >= on_mod->mod_id)
4256 4311 break;
4257 4312
4258 4313 /* Create and insert if not already recorded */
4259 4314 if ((mlp == NULL) || (mlp->modl_modp->mod_id != on_mod->mod_id)) {
4260 4315 new = kobj_zalloc(sizeof (*new), KM_SLEEP);
4261 4316 new->modl_modp = on_mod;
4262 4317 new->modl_next = mlp;
4263 4318 *pmlnp = new;
4264 4319
4265 4320 /*
4266 4321 * Increment the mod_ref count in our new requisite module.
4267 4322 * This is what keeps a module that has other modules
4268 4323 * which are dependent on it from being uninstalled and
4269 4324 * unloaded. "on_mod"'s mod_ref count decremented in
4270 4325 * mod_release_requisites when the "dependent" module
4271 4326 * unload is complete. "on_mod" must be loaded, but may not
4272 4327 * yet be installed.
4273 4328 */
4274 4329 on_mod->mod_ref++;
4275 4330 ASSERT(on_mod->mod_ref && on_mod->mod_loaded);
4276 4331 }
4277 4332
4278 4333 mutex_exit(&mod_lock);
4279 4334 }
4280 4335
4281 4336 /*
4282 4337 * release the hold associated with mod_make_requisite mod_ref++
4283 4338 * as part of unload.
4284 4339 */
4285 4340 void
4286 4341 mod_release_requisites(struct modctl *modp)
4287 4342 {
4288 4343 struct modctl_list *modl;
4289 4344 struct modctl_list *next;
4290 4345 struct modctl *req;
4291 4346 struct modctl_list *start = NULL, *mod_garbage;
4292 4347
4293 4348 ASSERT(!quiesce_active);
4294 4349 ASSERT(modp->mod_busy);
4295 4350 ASSERT(MUTEX_NOT_HELD(&mod_lock));
4296 4351
4297 4352 mutex_enter(&mod_lock); /* needed for manipulation of req */
4298 4353 for (modl = modp->mod_requisites; modl; modl = next) {
4299 4354 next = modl->modl_next;
4300 4355 req = modl->modl_modp;
4301 4356 ASSERT(req->mod_ref >= 1 && req->mod_loaded);
4302 4357 req->mod_ref--;
4303 4358 if (req->mod_ref == 0)
4304 4359 mod_uninstall_ref_zero++;
4305 4360
4306 4361 /*
4307 4362 * Check if the module has to be unloaded or not.
4308 4363 */
4309 4364 if (req->mod_ref == 0 && req->mod_delay_unload) {
4310 4365 struct modctl_list *new;
4311 4366 /*
4312 4367 * Allocate the modclt_list holding the garbage
4313 4368 * module which should be unloaded later.
4314 4369 */
4315 4370 new = kobj_zalloc(sizeof (struct modctl_list),
4316 4371 KM_SLEEP);
4317 4372 new->modl_modp = req;
4318 4373
4319 4374 if (start == NULL)
4320 4375 mod_garbage = start = new;
4321 4376 else {
4322 4377 mod_garbage->modl_next = new;
4323 4378 mod_garbage = new;
4324 4379 }
4325 4380 }
4326 4381
4327 4382 /* free the list as we go */
4328 4383 kobj_free(modl, sizeof (*modl));
4329 4384 }
4330 4385 modp->mod_requisites = NULL;
4331 4386 mutex_exit(&mod_lock);
4332 4387
4333 4388 /*
4334 4389 * Unload the garbage modules.
4335 4390 */
4336 4391 for (mod_garbage = start; mod_garbage != NULL; /* nothing */) {
4337 4392 struct modctl_list *old = mod_garbage;
4338 4393 struct modctl *mp = mod_garbage->modl_modp;
4339 4394 ASSERT(mp != NULL);
4340 4395
4341 4396 /*
4342 4397 * Hold this module until it's unloaded completely.
4343 4398 */
4344 4399 (void) mod_hold_by_modctl(mp,
4345 4400 MOD_WAIT_FOREVER | MOD_LOCK_NOT_HELD);
4346 4401 /*
4347 4402 * Check if the module is not unloaded yet and nobody requires
4348 4403 * the module. If it's unloaded already or somebody still
4349 4404 * requires the module, don't unload it now.
4350 4405 */
4351 4406 if (mp->mod_loaded && mp->mod_ref == 0)
4352 4407 mod_unload(mp);
4353 4408 ASSERT((mp->mod_loaded == 0 && mp->mod_delay_unload == 0) ||
4354 4409 (mp->mod_ref > 0));
4355 4410 mod_release_mod(mp);
4356 4411
4357 4412 mod_garbage = mod_garbage->modl_next;
4358 4413 kobj_free(old, sizeof (struct modctl_list));
4359 4414 }
4360 4415 }
4361 4416
4362 4417 /*
4363 4418 * Process dependency of the module represented by "dep" on the
4364 4419 * module named by "on."
4365 4420 *
4366 4421 * Called from kobj_do_dependents() to load a module "on" on which
4367 4422 * "dep" depends.
4368 4423 */
4369 4424 struct modctl *
4370 4425 mod_load_requisite(struct modctl *dep, char *on)
4371 4426 {
4372 4427 struct modctl *on_mod;
4373 4428 int retval;
4374 4429
4375 4430 if ((on_mod = mod_hold_loaded_mod(dep, on, &retval)) != NULL) {
4376 4431 mod_make_requisite(dep, on_mod);
4377 4432 } else if (moddebug & MODDEBUG_ERRMSG) {
4378 4433 printf("error processing %s on which module %s depends\n",
4379 4434 on, dep->mod_modname);
4380 4435 }
4381 4436 return (on_mod);
4382 4437 }
4383 4438
4384 4439 static int
4385 4440 mod_install_requisites(struct modctl *modp)
4386 4441 {
4387 4442 struct modctl_list *modl;
4388 4443 struct modctl *req;
4389 4444 int status = 0;
4390 4445
4391 4446 ASSERT(MUTEX_NOT_HELD(&mod_lock));
4392 4447 ASSERT(modp->mod_busy);
4393 4448
4394 4449 for (modl = modp->mod_requisites; modl; modl = modl->modl_next) {
4395 4450 req = modl->modl_modp;
4396 4451 (void) mod_hold_by_modctl(req,
4397 4452 MOD_WAIT_FOREVER | MOD_LOCK_NOT_HELD);
4398 4453 status = modinstall(req);
4399 4454 mod_release_mod(req);
4400 4455
4401 4456 if (status != 0)
4402 4457 break;
4403 4458 }
4404 4459 return (status);
4405 4460 }
4406 4461
4407 4462 /*
4408 4463 * returns 1 if this thread is doing autounload, 0 otherwise.
4409 4464 * see mod_uninstall_all.
4410 4465 */
4411 4466 int
4412 4467 mod_in_autounload()
4413 4468 {
4414 4469 return ((int)(uintptr_t)tsd_get(mod_autounload_key));
4415 4470 }
4416 4471
4417 4472 /*
4418 4473 * gmatch adapted from libc, stripping the wchar stuff
4419 4474 */
4420 4475 #define popchar(p, c) { \
4421 4476 c = *p++; \
4422 4477 if (c == 0) { \
4423 4478 return (0); \
4424 4479 } \
4425 4480 }
4426 4481
4427 4482 int
4428 4483 gmatch(const char *s, const char *p)
4429 4484 {
4430 4485 int c, sc;
4431 4486 int ok, lc, notflag;
4432 4487
4433 4488 sc = *s++;
4434 4489 c = *p++;
4435 4490 if (c == 0)
4436 4491 return (sc == c); /* nothing matches nothing */
4437 4492
4438 4493 switch (c) {
4439 4494 case '\\':
4440 4495 /* skip to quoted character */
4441 4496 popchar(p, c);
4442 4497 /*FALLTHRU*/
4443 4498
4444 4499 default:
4445 4500 /* straight comparison */
4446 4501 if (c != sc)
4447 4502 return (0);
4448 4503 /*FALLTHRU*/
4449 4504
4450 4505 case '?':
4451 4506 /* first char matches, move to remainder */
4452 4507 return (sc != '\0' ? gmatch(s, p) : 0);
4453 4508
4454 4509
4455 4510 case '*':
4456 4511 while (*p == '*')
4457 4512 p++;
4458 4513
4459 4514 /* * matches everything */
4460 4515 if (*p == 0)
4461 4516 return (1);
4462 4517
4463 4518 /* undo skip at the beginning & iterate over substrings */
4464 4519 --s;
4465 4520 while (*s) {
4466 4521 if (gmatch(s, p))
4467 4522 return (1);
4468 4523 s++;
4469 4524 }
4470 4525 return (0);
4471 4526
4472 4527 case '[':
4473 4528 /* match any char within [] */
4474 4529 if (sc == 0)
4475 4530 return (0);
4476 4531
4477 4532 ok = lc = notflag = 0;
4478 4533
4479 4534 if (*p == '!') {
4480 4535 notflag = 1;
4481 4536 p++;
4482 4537 }
4483 4538 popchar(p, c);
4484 4539
4485 4540 do {
4486 4541 if (c == '-' && lc && *p != ']') {
4487 4542 /* test sc against range [c1-c2] */
4488 4543 popchar(p, c);
4489 4544 if (c == '\\') {
4490 4545 popchar(p, c);
4491 4546 }
4492 4547
4493 4548 if (notflag) {
4494 4549 /* return 0 on mismatch */
4495 4550 if (lc <= sc && sc <= c)
4496 4551 return (0);
4497 4552 ok++;
4498 4553 } else if (lc <= sc && sc <= c) {
4499 4554 ok++;
4500 4555 }
4501 4556 /* keep going, may get a match next */
4502 4557 } else if (c == '\\') {
4503 4558 /* skip to quoted character */
4504 4559 popchar(p, c);
4505 4560 }
4506 4561 lc = c;
4507 4562 if (notflag) {
4508 4563 if (sc == lc)
4509 4564 return (0);
4510 4565 ok++;
4511 4566 } else if (sc == lc) {
4512 4567 ok++;
4513 4568 }
4514 4569 popchar(p, c);
4515 4570 } while (c != ']');
4516 4571
4517 4572 /* recurse on remainder of string */
4518 4573 return (ok ? gmatch(s, p) : 0);
4519 4574 }
4520 4575 /*NOTREACHED*/
4521 4576 }
4522 4577
4523 4578
4524 4579 /*
4525 4580 * Get default perm for device from /etc/minor_perm. Return 0 if match found.
4526 4581 *
4527 4582 * Pure wild-carded patterns are handled separately so the ordering of
4528 4583 * these patterns doesn't matter. We're still dependent on ordering
4529 4584 * however as the first matching entry is the one returned.
4530 4585 * Not ideal but all existing examples and usage do imply this
4531 4586 * ordering implicitly.
4532 4587 *
4533 4588 * Drivers using the clone driver are always good for some entertainment.
4534 4589 * Clone nodes under pseudo have the form clone@0:<driver>. Some minor
4535 4590 * perm entries have the form clone:<driver>, others use <driver>:*
4536 4591 * Examples are clone:llc1 vs. llc2:*, for example.
4537 4592 *
4538 4593 * Minor perms in the clone:<driver> form are mapped to the drivers's
4539 4594 * mperm list, not the clone driver, as wildcard entries for clone
4540 4595 * reference only. In other words, a clone wildcard will match
4541 4596 * references for clone@0:<driver> but never <driver>@<minor>.
4542 4597 *
4543 4598 * Additional minor perms in the standard form are also supported,
4544 4599 * for mixed usage, ie a node with an entry clone:<driver> could
4545 4600 * provide further entries <driver>:<minor>.
4546 4601 *
4547 4602 * Finally, some uses of clone use an alias as the minor name rather
4548 4603 * than the driver name, with the alias as the minor perm entry.
4549 4604 * This case is handled by attaching the driver to bring its
4550 4605 * minor list into existence, then discover the alias via DDI_ALIAS.
4551 4606 * The clone device's minor perm list can then be searched for
4552 4607 * that alias.
4553 4608 */
4554 4609
4555 4610 static int
4556 4611 dev_alias_minorperm(dev_info_t *dip, char *minor_name, mperm_t *rmp)
4557 4612 {
4558 4613 major_t major;
4559 4614 struct devnames *dnp;
4560 4615 mperm_t *mp;
4561 4616 char *alias = NULL;
4562 4617 dev_info_t *cdevi;
4563 4618 int circ;
4564 4619 struct ddi_minor_data *dmd;
4565 4620
4566 4621 major = ddi_name_to_major(minor_name);
4567 4622
4568 4623 ASSERT(dip == clone_dip);
4569 4624 ASSERT(major != DDI_MAJOR_T_NONE);
4570 4625
4571 4626 /*
4572 4627 * Attach the driver named by the minor node, then
4573 4628 * search its first instance's minor list for an
4574 4629 * alias node.
4575 4630 */
4576 4631 if (ddi_hold_installed_driver(major) == NULL)
4577 4632 return (1);
4578 4633
4579 4634 dnp = &devnamesp[major];
4580 4635 LOCK_DEV_OPS(&dnp->dn_lock);
4581 4636
4582 4637 if ((cdevi = dnp->dn_head) != NULL) {
4583 4638 ndi_devi_enter(cdevi, &circ);
4584 4639 for (dmd = DEVI(cdevi)->devi_minor; dmd; dmd = dmd->next) {
4585 4640 if (dmd->type == DDM_ALIAS) {
4586 4641 alias = i_ddi_strdup(dmd->ddm_name, KM_SLEEP);
4587 4642 break;
4588 4643 }
4589 4644 }
4590 4645 ndi_devi_exit(cdevi, circ);
4591 4646 }
4592 4647
4593 4648 UNLOCK_DEV_OPS(&dnp->dn_lock);
4594 4649 ddi_rele_driver(major);
4595 4650
4596 4651 if (alias == NULL) {
4597 4652 if (moddebug & MODDEBUG_MINORPERM)
4598 4653 cmn_err(CE_CONT, "dev_minorperm: "
4599 4654 "no alias for %s\n", minor_name);
4600 4655 return (1);
4601 4656 }
4602 4657
4603 4658 major = ddi_driver_major(clone_dip);
4604 4659 dnp = &devnamesp[major];
4605 4660 LOCK_DEV_OPS(&dnp->dn_lock);
4606 4661
4607 4662 /*
4608 4663 * Go through the clone driver's mperm list looking
4609 4664 * for a match for the specified alias.
4610 4665 */
4611 4666 for (mp = dnp->dn_mperm; mp; mp = mp->mp_next) {
4612 4667 if (strcmp(alias, mp->mp_minorname) == 0) {
4613 4668 break;
4614 4669 }
4615 4670 }
4616 4671
4617 4672 if (mp) {
4618 4673 if (moddebug & MODDEBUG_MP_MATCH) {
4619 4674 cmn_err(CE_CONT,
4620 4675 "minor perm defaults: %s %s 0%o %d %d (aliased)\n",
4621 4676 minor_name, alias, mp->mp_mode,
4622 4677 mp->mp_uid, mp->mp_gid);
4623 4678 }
4624 4679 rmp->mp_uid = mp->mp_uid;
4625 4680 rmp->mp_gid = mp->mp_gid;
4626 4681 rmp->mp_mode = mp->mp_mode;
4627 4682 }
4628 4683 UNLOCK_DEV_OPS(&dnp->dn_lock);
4629 4684
4630 4685 kmem_free(alias, strlen(alias)+1);
4631 4686
4632 4687 return (mp == NULL);
4633 4688 }
4634 4689
4635 4690 int
4636 4691 dev_minorperm(dev_info_t *dip, char *name, mperm_t *rmp)
4637 4692 {
4638 4693 major_t major;
4639 4694 char *minor_name;
4640 4695 struct devnames *dnp;
4641 4696 mperm_t *mp;
4642 4697 int is_clone = 0;
4643 4698
4644 4699 if (!minorperm_loaded) {
4645 4700 if (moddebug & MODDEBUG_MINORPERM)
4646 4701 cmn_err(CE_CONT,
4647 4702 "%s: minor perm not yet loaded\n", name);
4648 4703 return (1);
4649 4704 }
4650 4705
4651 4706 minor_name = strchr(name, ':');
4652 4707 if (minor_name == NULL)
4653 4708 return (1);
4654 4709 minor_name++;
4655 4710
4656 4711 /*
4657 4712 * If it's the clone driver, search the driver as named
4658 4713 * by the minor. All clone minor perm entries other than
4659 4714 * alias nodes are actually installed on the real driver's list.
4660 4715 */
4661 4716 if (dip == clone_dip) {
4662 4717 major = ddi_name_to_major(minor_name);
4663 4718 if (major == DDI_MAJOR_T_NONE) {
4664 4719 if (moddebug & MODDEBUG_MINORPERM)
4665 4720 cmn_err(CE_CONT, "dev_minorperm: "
4666 4721 "%s: no such driver\n", minor_name);
4667 4722 return (1);
4668 4723 }
4669 4724 is_clone = 1;
4670 4725 } else {
4671 4726 major = ddi_driver_major(dip);
4672 4727 ASSERT(major != DDI_MAJOR_T_NONE);
4673 4728 }
4674 4729
4675 4730 dnp = &devnamesp[major];
4676 4731 LOCK_DEV_OPS(&dnp->dn_lock);
4677 4732
4678 4733 /*
4679 4734 * Go through the driver's mperm list looking for
4680 4735 * a match for the specified minor. If there's
4681 4736 * no matching pattern, use the wild card.
4682 4737 * Defer to the clone wild for clone if specified,
4683 4738 * otherwise fall back to the normal form.
4684 4739 */
4685 4740 for (mp = dnp->dn_mperm; mp; mp = mp->mp_next) {
4686 4741 if (gmatch(minor_name, mp->mp_minorname) != 0) {
4687 4742 break;
4688 4743 }
4689 4744 }
4690 4745 if (mp == NULL) {
4691 4746 if (is_clone)
4692 4747 mp = dnp->dn_mperm_clone;
4693 4748 if (mp == NULL)
4694 4749 mp = dnp->dn_mperm_wild;
4695 4750 }
4696 4751
4697 4752 if (mp) {
4698 4753 if (moddebug & MODDEBUG_MP_MATCH) {
4699 4754 cmn_err(CE_CONT,
4700 4755 "minor perm defaults: %s %s 0%o %d %d\n",
4701 4756 name, mp->mp_minorname, mp->mp_mode,
4702 4757 mp->mp_uid, mp->mp_gid);
4703 4758 }
4704 4759 rmp->mp_uid = mp->mp_uid;
4705 4760 rmp->mp_gid = mp->mp_gid;
4706 4761 rmp->mp_mode = mp->mp_mode;
4707 4762 }
4708 4763 UNLOCK_DEV_OPS(&dnp->dn_lock);
4709 4764
4710 4765 /*
4711 4766 * If no match can be found for a clone node,
4712 4767 * search for a possible match for an alias.
4713 4768 * One such example is /dev/ptmx -> /devices/pseudo/clone@0:ptm,
4714 4769 * with minor perm entry clone:ptmx.
4715 4770 */
4716 4771 if (mp == NULL && is_clone) {
4717 4772 return (dev_alias_minorperm(dip, minor_name, rmp));
4718 4773 }
4719 4774
4720 4775 return (mp == NULL);
4721 4776 }
4722 4777
4723 4778 /*
4724 4779 * dynamicaly reference load a dl module/library, returning handle
4725 4780 */
4726 4781 /*ARGSUSED*/
4727 4782 ddi_modhandle_t
4728 4783 ddi_modopen(const char *modname, int mode, int *errnop)
4729 4784 {
4730 4785 char *subdir;
4731 4786 char *mod;
4732 4787 int subdirlen;
4733 4788 struct modctl *hmodp = NULL;
4734 4789 int retval = EINVAL;
4735 4790
4736 4791 ASSERT(modname && (mode == KRTLD_MODE_FIRST));
4737 4792 if ((modname == NULL) || (mode != KRTLD_MODE_FIRST))
4738 4793 goto out;
4739 4794
4740 4795 /* find last '/' in modname */
4741 4796 mod = strrchr(modname, '/');
4742 4797
4743 4798 if (mod) {
4744 4799 /* for subdir string without modification to argument */
4745 4800 mod++;
4746 4801 subdirlen = mod - modname;
4747 4802 subdir = kmem_alloc(subdirlen, KM_SLEEP);
4748 4803 (void) strlcpy(subdir, modname, subdirlen);
4749 4804 } else {
4750 4805 subdirlen = 0;
4751 4806 subdir = "misc";
4752 4807 mod = (char *)modname;
4753 4808 }
4754 4809
4755 4810 /* reference load with errno return value */
4756 4811 retval = modrload(subdir, mod, &hmodp);
4757 4812
4758 4813 if (subdirlen)
4759 4814 kmem_free(subdir, subdirlen);
4760 4815
4761 4816 out: if (errnop)
4762 4817 *errnop = retval;
4763 4818
4764 4819 if (moddebug & MODDEBUG_DDI_MOD)
4765 4820 printf("ddi_modopen %s mode %x: %s %p %d\n",
4766 4821 modname ? modname : "<unknown>", mode,
4767 4822 hmodp ? hmodp->mod_filename : "<unknown>",
4768 4823 (void *)hmodp, retval);
4769 4824
4770 4825 return ((ddi_modhandle_t)hmodp);
4771 4826 }
4772 4827
4773 4828 /* lookup "name" in open dl module/library */
4774 4829 void *
4775 4830 ddi_modsym(ddi_modhandle_t h, const char *name, int *errnop)
4776 4831 {
4777 4832 struct modctl *hmodp = (struct modctl *)h;
4778 4833 void *f;
4779 4834 int retval;
4780 4835
4781 4836 ASSERT(hmodp && name && hmodp->mod_installed && (hmodp->mod_ref >= 1));
4782 4837 if ((hmodp == NULL) || (name == NULL) ||
4783 4838 (hmodp->mod_installed == 0) || (hmodp->mod_ref < 1)) {
4784 4839 f = NULL;
4785 4840 retval = EINVAL;
4786 4841 } else {
4787 4842 f = (void *)kobj_lookup(hmodp->mod_mp, (char *)name);
4788 4843 if (f)
4789 4844 retval = 0;
4790 4845 else
4791 4846 retval = ENOTSUP;
4792 4847 }
4793 4848
4794 4849 if (moddebug & MODDEBUG_DDI_MOD)
4795 4850 printf("ddi_modsym in %s of %s: %d %p\n",
4796 4851 hmodp ? hmodp->mod_modname : "<unknown>",
4797 4852 name ? name : "<unknown>", retval, f);
4798 4853
4799 4854 if (errnop)
4800 4855 *errnop = retval;
4801 4856 return (f);
4802 4857 }
4803 4858
4804 4859 /* dynamic (un)reference unload of an open dl module/library */
4805 4860 int
4806 4861 ddi_modclose(ddi_modhandle_t h)
4807 4862 {
4808 4863 struct modctl *hmodp = (struct modctl *)h;
4809 4864 struct modctl *modp = NULL;
4810 4865 int retval;
4811 4866
4812 4867 ASSERT(hmodp && hmodp->mod_installed && (hmodp->mod_ref >= 1));
4813 4868 if ((hmodp == NULL) ||
4814 4869 (hmodp->mod_installed == 0) || (hmodp->mod_ref < 1)) {
4815 4870 retval = EINVAL;
4816 4871 goto out;
4817 4872 }
4818 4873
4819 4874 retval = modunrload(hmodp->mod_id, &modp, ddi_modclose_unload);
4820 4875 if (retval == EBUSY)
4821 4876 retval = 0; /* EBUSY is not an error */
4822 4877
4823 4878 if (retval == 0) {
4824 4879 ASSERT(hmodp == modp);
4825 4880 if (hmodp != modp)
4826 4881 retval = EINVAL;
4827 4882 }
4828 4883
4829 4884 out: if (moddebug & MODDEBUG_DDI_MOD)
4830 4885 printf("ddi_modclose %s: %d\n",
4831 4886 hmodp ? hmodp->mod_modname : "<unknown>", retval);
4832 4887
4833 4888 return (retval);
4834 4889 }
|
↓ open down ↓ |
3678 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX