4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/systm.h>
28 #include <sys/param.h>
32 #include <sys/class.h>
34 #include <sys/vnode.h>
35 #include <sys/mount.h>
36 #include <sys/systm.h>
37 #include <sys/modctl.h>
39 #include <sys/exechdr.h>
40 #include <sys/devops.h>
42 #include <sys/sunddi.h>
43 #include <sys/cmn_err.h>
44 #include <sys/hwconf.h>
45 #include <sys/ddi_impldefs.h>
46 #include <sys/autoconf.h>
49 #include <sys/instance.h>
50 #include <sys/modhash.h>
52 #include <sys/debug.h>
54 #include <sys/strsubr.h>
56 #include <sys/brand.h>
57 #include <sys/cpc_pcbe.h>
58 #include <sys/kstat.h>
59 #include <sys/socketvar.h>
60 #include <sys/kiconv.h>
64 extern struct cb_ops no_cb_ops
;
65 extern struct dev_ops nodev_ops
;
66 extern struct dev_ops mod_nodev_ops
;
68 extern struct modctl
*mod_getctl(struct modlinkage
*);
69 extern int errsys(), nodev(), nulldev();
71 extern int findmodbyname(char *);
72 extern int mod_getsysnum(char *);
74 extern struct execsw execsw
[];
77 * Define dev_ops for unused devopsp entry.
79 struct dev_ops mod_nodev_ops
= {
80 DEVO_REV
, /* devo_rev */
82 ddi_no_info
, /* info */
83 nulldev
, /* identify */
88 &no_cb_ops
, /* character/block driver operations */
89 (struct bus_ops
*)0 /* bus operations for nexus drivers */
93 * Define mod_ops for each supported module type
97 * Null operations; used for uninitialized and "misc" modules.
99 static int mod_null(struct modldrv
*, struct modlinkage
*);
100 static int mod_infonull(void *, struct modlinkage
*, int *);
102 struct mod_ops mod_miscops
= {
103 mod_null
, mod_null
, mod_infonull
107 struct mod_ops mod_cpuops
= {
108 mod_null
, mod_null
, mod_infonull
112 * Cryptographic Modules
114 struct mod_ops mod_cryptoops
= {
115 mod_null
, mod_null
, mod_infonull
121 static int mod_installipp(struct modlipp
*, struct modlinkage
*);
122 static int mod_removeipp(struct modlipp
*, struct modlinkage
*);
123 static int mod_infoipp(struct modlipp
*, struct modlinkage
*, int *);
125 struct mod_ops mod_ippops
= {
126 mod_installipp
, mod_removeipp
, mod_infoipp
132 static int mod_infodrv(struct modldrv
*, struct modlinkage
*, int *);
133 static int mod_installdrv(struct modldrv
*, struct modlinkage
*);
134 static int mod_removedrv(struct modldrv
*, struct modlinkage
*);
136 struct mod_ops mod_driverops
= {
137 mod_installdrv
, mod_removedrv
, mod_infodrv
141 * System calls (new interface)
143 static int mod_infosys(struct modlsys
*, struct modlinkage
*, int *);
144 static int mod_installsys(struct modlsys
*, struct modlinkage
*);
145 static int mod_removesys(struct modlsys
*, struct modlinkage
*);
147 struct mod_ops mod_syscallops
= {
148 mod_installsys
, mod_removesys
, mod_infosys
151 #ifdef _SYSCALL32_IMPL
153 * 32-bit system calls in 64-bit kernel
155 static int mod_infosys32(struct modlsys
*, struct modlinkage
*, int *);
156 static int mod_installsys32(struct modlsys
*, struct modlinkage
*);
157 static int mod_removesys32(struct modlsys
*, struct modlinkage
*);
159 struct mod_ops mod_syscallops32
= {
160 mod_installsys32
, mod_removesys32
, mod_infosys32
162 #endif /* _SYSCALL32_IMPL */
167 static int mod_infofs(struct modlfs
*, struct modlinkage
*, int *);
168 static int mod_installfs(struct modlfs
*, struct modlinkage
*);
169 static int mod_removefs(struct modlfs
*, struct modlinkage
*);
171 struct mod_ops mod_fsops
= {
172 mod_installfs
, mod_removefs
, mod_infofs
178 static int mod_infostrmod(struct modlstrmod
*, struct modlinkage
*, int *);
179 static int mod_installstrmod(struct modlstrmod
*, struct modlinkage
*);
180 static int mod_removestrmod(struct modlstrmod
*, struct modlinkage
*);
182 struct mod_ops mod_strmodops
= {
183 mod_installstrmod
, mod_removestrmod
, mod_infostrmod
189 static int mod_infosockmod(struct modlsockmod
*, struct modlinkage
*, int *);
190 static int mod_installsockmod(struct modlsockmod
*, struct modlinkage
*);
191 static int mod_removesockmod(struct modlsockmod
*, struct modlinkage
*);
193 struct mod_ops mod_sockmodops
= {
194 mod_installsockmod
, mod_removesockmod
, mod_infosockmod
198 * Scheduling classes.
200 static int mod_infosched(struct modlsched
*, struct modlinkage
*, int *);
201 static int mod_installsched(struct modlsched
*, struct modlinkage
*);
202 static int mod_removesched(struct modlsched
*, struct modlinkage
*);
204 struct mod_ops mod_schedops
= {
205 mod_installsched
, mod_removesched
, mod_infosched
209 * Exec file type (like ELF, ...).
211 static int mod_infoexec(struct modlexec
*, struct modlinkage
*, int *);
212 static int mod_installexec(struct modlexec
*, struct modlinkage
*);
213 static int mod_removeexec(struct modlexec
*, struct modlinkage
*);
215 struct mod_ops mod_execops
= {
216 mod_installexec
, mod_removeexec
, mod_infoexec
220 * Dacf (Dynamic Autoconfiguration) modules.
222 static int mod_infodacf(struct modldacf
*, struct modlinkage
*, int *);
223 static int mod_installdacf(struct modldacf
*, struct modlinkage
*);
224 static int mod_removedacf(struct modldacf
*, struct modlinkage
*);
226 struct mod_ops mod_dacfops
= {
227 mod_installdacf
, mod_removedacf
, mod_infodacf
231 * PCBE (Performance Counter BackEnd) modules.
233 static int mod_installpcbe(struct modlpcbe
*, struct modlinkage
*);
234 static int mod_removepcbe(struct modlpcbe
*, struct modlinkage
*);
236 struct mod_ops mod_pcbeops
= {
237 mod_installpcbe
, mod_removepcbe
, mod_infonull
243 static int mod_installbrand(struct modlbrand
*, struct modlinkage
*);
244 static int mod_removebrand(struct modlbrand
*, struct modlinkage
*);
246 struct mod_ops mod_brandops
= {
247 mod_installbrand
, mod_removebrand
, mod_infonull
253 static int mod_installkiconv(struct modlkiconv
*, struct modlinkage
*);
254 static int mod_removekiconv(struct modlkiconv
*, struct modlinkage
*);
256 struct mod_ops mod_kiconvops
= {
257 mod_installkiconv
, mod_removekiconv
, mod_infonull
260 static struct sysent
*mod_getsysent(struct modlinkage
*, struct sysent
*);
262 static char uninstall_err
[] = "Cannot uninstall %s; not installed";
267 #define DRV_DBG MODDEBUG_LOADMSG2
270 static void mod_dprintf(int flag
, const char *format
, ...) __KPRINTFLIKE(2);
273 mod_dprintf(int flag
, const char *format
, ...)
277 if ((moddebug
& flag
) != 0) {
278 va_start(alist
, format
);
279 (void) vprintf(format
, alist
);
286 * (This routine is in the Solaris SPARC DDI/DKI)
289 mod_install(struct modlinkage
*modlp
)
291 int retval
= -1; /* No linkage structures */
292 struct modlmisc
**linkpp
;
293 struct modlmisc
**linkpp1
;
295 if (modlp
->ml_rev
!= MODREV_1
) {
296 printf("mod_install: modlinkage structure is not MODREV_1\n");
299 linkpp
= (struct modlmisc
**)&modlp
->ml_linkage
[0];
301 while (*linkpp
!= NULL
) {
302 if ((retval
= MODL_INSTALL(*linkpp
, modlp
)) != 0) {
303 linkpp1
= (struct modlmisc
**)&modlp
->ml_linkage
[0];
305 while (linkpp1
!= linkpp
) {
306 MODL_REMOVE(*linkpp1
, modlp
); /* clean up */
316 static char *reins_err
=
317 "Could not reinstall %s\nReboot to correct the problem";
320 * Remove a module. This is called by the module wrapper routine.
321 * (This routine is in the Solaris SPARC DDI/DKI)
324 mod_remove(struct modlinkage
*modlp
)
327 struct modlmisc
**linkpp
, *last_linkp
;
329 linkpp
= (struct modlmisc
**)&modlp
->ml_linkage
[0];
331 while (*linkpp
!= NULL
) {
332 if ((retval
= MODL_REMOVE(*linkpp
, modlp
)) != 0) {
333 last_linkp
= *linkpp
;
334 linkpp
= (struct modlmisc
**)&modlp
->ml_linkage
[0];
335 while (*linkpp
!= last_linkp
) {
336 if (MODL_INSTALL(*linkpp
, modlp
) != 0) {
337 cmn_err(CE_WARN
, reins_err
,
338 (*linkpp
)->misc_linkinfo
);
352 * (This routine is in the Solaris SPARC DDI/DKI)
355 mod_info(struct modlinkage
*modlp
, struct modinfo
*modinfop
)
359 struct modspecific_info
*msip
;
360 struct modlmisc
**linkpp
;
362 modinfop
->mi_rev
= modlp
->ml_rev
;
364 linkpp
= (struct modlmisc
**)modlp
->ml_linkage
;
365 msip
= &modinfop
->mi_msinfo
[0];
367 for (i
= 0; i
< MODMAXLINK
; i
++) {
368 if (*linkpp
== NULL
) {
369 msip
->msi_linkinfo
[0] = '\0';
371 (void) strncpy(msip
->msi_linkinfo
,
372 (*linkpp
)->misc_linkinfo
, MODMAXLINKINFOLEN
);
373 retval
= MODL_INFO(*linkpp
, modlp
, &msip
->msi_p0
);
381 if (modinfop
->mi_info
== MI_INFO_LINKAGE
) {
383 * Slight kludge used to extract the address of the
384 * modlinkage structure from the module (just after
385 * loading a module for the very first time)
387 modinfop
->mi_base
= (void *)modlp
;
399 mod_modname(struct modlinkage
*modlp
)
403 if ((mcp
= mod_getctl(modlp
)) == NULL
)
406 return (mcp
->mod_modname
);
410 * Null operation; return 0.
414 mod_null(struct modldrv
*modl
, struct modlinkage
*modlp
)
420 * Status for User modules.
424 mod_infonull(void *modl
, struct modlinkage
*modlp
, int *p0
)
426 *p0
= -1; /* for modinfo display */
435 mod_infodrv(struct modldrv
*modl
, struct modlinkage
*modlp
, int *p0
)
440 if ((mcp
= mod_getctl(modlp
)) == NULL
) {
442 return (0); /* driver is not yet installed */
445 mod_name
= mcp
->mod_modname
;
447 *p0
= ddi_name_to_major(mod_name
);
452 * Manage dacf (device autoconfiguration) modules
457 mod_infodacf(struct modldacf
*modl
, struct modlinkage
*modlp
, int *p0
)
459 if (mod_getctl(modlp
) == NULL
) {
461 return (0); /* module is not yet installed */
469 mod_installdacf(struct modldacf
*modl
, struct modlinkage
*modlp
)
473 if ((mcp
= mod_getctl(modlp
)) == NULL
)
475 return (dacf_module_register(mcp
->mod_modname
, modl
->dacf_dacfsw
));
480 mod_removedacf(struct modldacf
*modl
, struct modlinkage
*modlp
)
484 if ((mcp
= mod_getctl(modlp
)) == NULL
)
486 return (dacf_module_unregister(mcp
->mod_modname
));
490 * Manage PCBE (Performance Counter BackEnd) modules.
494 mod_installpcbe(struct modlpcbe
*modl
, struct modlinkage
*modlp
)
496 if (modl
->pcbe_ops
->pcbe_ver
!= PCBE_VER_1
) {
497 cmn_err(CE_WARN
, "pcbe '%s' version mismatch",
498 modl
->pcbe_linkinfo
);
502 kcpc_register_pcbe(modl
->pcbe_ops
);
507 * PCBEs may not be unloaded. It would make CPC locking too complex, and since
508 * PCBEs are loaded once and used for life, there is no harm done in leaving
509 * them in the system.
513 mod_removepcbe(struct modlpcbe
*modl
, struct modlinkage
*modlp
)
519 * Manage BrandZ modules.
523 mod_installbrand(struct modlbrand
*modl
, struct modlinkage
*modlp
)
525 return (brand_register(modl
->brand_branddef
));
530 mod_removebrand(struct modlbrand
*modl
, struct modlinkage
*modlp
)
532 return (brand_unregister(modl
->brand_branddef
));
536 * Install a new driver
539 mod_installdrv(struct modldrv
*modl
, struct modlinkage
*modlp
)
546 struct devnames
*dnp
;
547 struct streamtab
*str
;
554 /* sanity check module */
555 if ((mcp
= mod_getctl(modlp
)) == NULL
) {
556 cmn_err(CE_WARN
, "mod_install: bad module linkage data");
560 modname
= mcp
->mod_modname
;
562 /* Sanity check modname */
563 if ((major
= ddi_name_to_major(modname
)) == DDI_MAJOR_T_NONE
) {
566 "mod_installdrv: no major number for %s", modname
);
572 /* Verify MP safety flag */
573 ops
= modl
->drv_dev_ops
;
574 if (ops
->devo_bus_ops
== NULL
&& ops
->devo_cb_ops
!= NULL
&&
575 !(ops
->devo_cb_ops
->cb_flag
& D_MP
)) {
577 "mod_installdrv: MT-unsafe driver '%s' rejected", modname
);
583 /* Is bus_map_fault signature correct (version 8 and higher)? */
584 if (ops
->devo_bus_ops
!= NULL
&&
585 ops
->devo_bus_ops
->bus_map_fault
!= NULL
&&
586 ops
->devo_bus_ops
->bus_map_fault
!= i_ddi_map_fault
&&
587 ops
->devo_bus_ops
->busops_rev
< BUSO_REV_8
) {
590 "mod_installdrv: busops' revision of '%s' is too low"
591 " (must be at least 8)", modname
);
597 /* Make sure the driver is uninstalled */
598 dnp
= &devnamesp
[major
];
599 LOCK_DEV_OPS(&dnp
->dn_lock
);
602 if (dnp
->dn_flags
& (DN_DRIVER_REMOVED
|DN_DRIVER_INACTIVE
)) {
605 "mod_installdrv: driver %s not installed", modname
);
611 if (dp
!= &nodev_ops
&& dp
!= &mod_nodev_ops
) {
613 "mod_installdrv: driver already installed %s", modname
);
618 devopsp
[major
] = ops
; /* setup devopsp */
620 if ((str
= STREAMSTAB(major
)) != NULL
) { /* streams driver */
621 flag
= CBFLAG(major
);
622 if ((err
= devflg_to_qflag(str
, flag
, &qflag
, &sqtype
)) != 0)
624 cdp
= &devimpl
[major
];
625 ASSERT(cdp
->d_str
== NULL
);
627 cdp
->d_qflag
= qflag
| QISDRV
;
628 cdp
->d_sqtype
= sqtype
;
631 if (ops
->devo_bus_ops
== NULL
)
632 dnp
->dn_flags
|= DN_LEAF_DRIVER
;
635 UNLOCK_DEV_OPS(&dnp
->dn_lock
);
641 mod_removedrv(struct modldrv
*modl
, struct modlinkage
*modlp
)
645 struct devnames
*dnp
;
649 extern kthread_id_t mod_aul_thread
;
650 struct streamtab
*str
;
654 /* Don't auto unload modules on if moddebug flag is set */
655 if ((moddebug
& MODDEBUG_NOAUL_DRV
) && (mod_aul_thread
== curthread
)) {
660 /* Verify modname has a driver major */
661 mcp
= mod_getctl(modlp
);
663 modname
= mcp
->mod_modname
;
665 if ((major
= ddi_name_to_major(modname
)) == -1) {
666 cmn_err(CE_WARN
, uninstall_err
, modname
);
671 ops
= modl
->drv_dev_ops
;
672 dnp
= &(devnamesp
[major
]);
673 LOCK_DEV_OPS(&(dnp
->dn_lock
));
678 cmn_err(CE_NOTE
, "mod_removedrv: mismatched driver for %s",
685 * A driver is not unloadable if its dev_ops are held
687 if (!DRV_UNLOADABLE(dp
)) {
688 mod_dprintf(DRV_DBG
, "Cannot unload device driver <%s>,"
689 " refcnt %d\n", modname
, dp
->devo_refcnt
);
697 if ((str
= STREAMSTAB(major
)) != NULL
) { /* streams driver */
698 cdp
= &devimpl
[major
];
699 ASSERT(cdp
->d_str
== str
);
702 /* check for reference to per-dev syncq */
703 if (cdp
->d_dmp
!= NULL
) {
709 devopsp
[major
] = &mod_nodev_ops
;
710 dnp
->dn_flags
&= ~(DN_DRIVER_HELD
|DN_NO_AUTODETACH
);
713 UNLOCK_DEV_OPS(&(dnp
->dn_lock
));
719 * System call subroutines
723 * Compute system call number for given sysent and sysent table
726 mod_infosysnum(struct modlinkage
*modlp
, struct sysent table
[])
730 if ((sysp
= mod_getsysent(modlp
, table
)) == NULL
)
732 return ((int)(sysp
- table
));
736 * Put a loadable system call entry into a sysent table.
739 mod_installsys_sysent(
740 struct modlsys
*modl
,
741 struct modlinkage
*modlp
,
742 struct sysent table
[])
749 * Before we even play with the sysent table, sanity check the
750 * incoming flags to make sure the entry is valid
752 switch (modl
->sys_sysent
->sy_flags
& SE_RVAL_MASK
) {
754 /* only r_val1 returned */
755 case SE_32RVAL1
| SE_32RVAL2
:
756 /* r_val1 and r_val2 returned */
758 /* 64-bit rval returned */
761 cmn_err(CE_WARN
, "loadable syscall: %p: bad rval flags %x",
762 (void *)modl
, modl
->sys_sysent
->sy_flags
);
766 if ((sysp
= mod_getsysent(modlp
, table
)) == NULL
)
770 * We should only block here until the reader in syscall gives
771 * up the lock. Multiple writers are prevented in the mod layer.
773 rw_enter(sysp
->sy_lock
, RW_WRITER
);
774 mp
= modl
->sys_sysent
;
775 sysp
->sy_narg
= mp
->sy_narg
;
776 sysp
->sy_call
= mp
->sy_call
;
779 * clear the old call method flag, and get the new one from the module.
781 sysp
->sy_flags
&= ~SE_ARGC
;
782 sysp
->sy_flags
|= SE_LOADED
|
783 (mp
->sy_flags
& (SE_ARGC
| SE_NOUNLOAD
| SE_RVAL_MASK
));
786 * If the syscall doesn't need or want unloading, it can avoid
787 * the locking overhead on each entry. Convert the sysent to a
788 * normal non-loadable entry in that case.
790 if (mp
->sy_flags
& SE_NOUNLOAD
) {
791 if (mp
->sy_flags
& SE_ARGC
) {
792 sysp
->sy_callc
= (int64_t (*)())mp
->sy_call
;
794 sysp
->sy_callc
= syscall_ap
;
796 sysp
->sy_flags
&= ~SE_LOADABLE
;
798 rw_exit(sysp
->sy_lock
);
803 * Remove a loadable system call entry from a sysent table.
806 mod_removesys_sysent(
807 struct modlsys
*modl
,
808 struct modlinkage
*modlp
,
809 struct sysent table
[])
813 if ((sysp
= mod_getsysent(modlp
, table
)) == NULL
||
814 (sysp
->sy_flags
& (SE_LOADABLE
| SE_NOUNLOAD
)) == 0 ||
815 sysp
->sy_call
!= modl
->sys_sysent
->sy_call
) {
817 struct modctl
*mcp
= mod_getctl(modlp
);
818 char *modname
= mcp
->mod_modname
;
820 cmn_err(CE_WARN
, uninstall_err
, modname
);
824 /* If we can't get the write lock, we can't unlink from the system */
826 if (!(moddebug
& MODDEBUG_NOAUL_SYS
) &&
827 rw_tryenter(sysp
->sy_lock
, RW_WRITER
)) {
829 * Check the flags to be sure the syscall is still
831 * If SE_NOUNLOAD is set, SE_LOADABLE will not be.
833 if ((sysp
->sy_flags
& (SE_LOADED
| SE_LOADABLE
)) ==
834 (SE_LOADED
| SE_LOADABLE
)) {
835 sysp
->sy_flags
&= ~SE_LOADED
;
836 sysp
->sy_callc
= loadable_syscall
;
837 sysp
->sy_call
= (int (*)())nosys
;
838 rw_exit(sysp
->sy_lock
);
841 rw_exit(sysp
->sy_lock
);
847 * System call status info
851 mod_infosys(struct modlsys
*modl
, struct modlinkage
*modlp
, int *p0
)
853 *p0
= mod_infosysnum(modlp
, sysent
);
858 * Link a system call into the system by setting the proper sysent entry.
859 * Called from the module's _init routine.
862 mod_installsys(struct modlsys
*modl
, struct modlinkage
*modlp
)
864 return (mod_installsys_sysent(modl
, modlp
, sysent
));
868 * Unlink a system call from the system.
869 * Called from a modules _fini routine.
872 mod_removesys(struct modlsys
*modl
, struct modlinkage
*modlp
)
874 return (mod_removesys_sysent(modl
, modlp
, sysent
));
877 #ifdef _SYSCALL32_IMPL
880 * 32-bit system call status info
884 mod_infosys32(struct modlsys
*modl
, struct modlinkage
*modlp
, int *p0
)
886 *p0
= mod_infosysnum(modlp
, sysent32
);
891 * Link the 32-bit syscall into the system by setting the proper sysent entry.
892 * Also called from the module's _init routine.
895 mod_installsys32(struct modlsys
*modl
, struct modlinkage
*modlp
)
897 return (mod_installsys_sysent(modl
, modlp
, sysent32
));
901 * Unlink the 32-bit flavor of a system call from the system.
902 * Also called from a module's _fini routine.
905 mod_removesys32(struct modlsys
*modl
, struct modlinkage
*modlp
)
907 return (mod_removesys_sysent(modl
, modlp
, sysent32
));
910 #endif /* _SYSCALL32_IMPL */
913 * Filesystem status info
917 mod_infofs(struct modlfs
*modl
, struct modlinkage
*modlp
, int *p0
)
922 if ((vswp
= vfs_getvfsswbyname(modl
->fs_vfsdef
->name
)) == NULL
)
926 vfs_unrefvfssw(vswp
);
933 * Install a filesystem.
937 mod_installfs(struct modlfs
*modl
, struct modlinkage
*modlp
)
942 char ksname
[KSTAT_STRLEN
+ 1];
943 int fstype
; /* index into vfssw[] and vsanchor_fstype[] */
946 int vsw_stats_enabled
;
947 /* Not for public consumption so these aren't in a header file */
948 extern int vopstats_enabled
;
949 extern vopstats_t
**vopstats_fstype
;
950 extern kstat_t
*new_vskstat(char *, vopstats_t
*);
951 extern void initialize_vopstats(vopstats_t
*);
953 if (modl
->fs_vfsdef
->def_version
== VFSDEF_VERSION
) {
954 /* Version matched */
955 fsname
= modl
->fs_vfsdef
->name
;
957 if ((modl
->fs_vfsdef
->def_version
> 0) &&
958 (modl
->fs_vfsdef
->def_version
< VFSDEF_VERSION
)) {
959 /* Older VFSDEF_VERSION */
960 fsname
= modl
->fs_vfsdef
->name
;
961 } else if ((mcp
= mod_getctl(modlp
)) != NULL
) {
962 /* Pre-VFSDEF_VERSION */
963 fsname
= mcp
->mod_modname
;
965 /* If all else fails... */
966 fsname
= "<unknown file system type>";
969 cmn_err(CE_WARN
, "file system '%s' version mismatch", fsname
);
976 if ((vswp
= vfs_getvfsswbyname(fsname
)) == NULL
) {
977 if ((vswp
= allocate_vfssw(fsname
)) == NULL
) {
980 * See 1095689. If this message appears, then
981 * we either need to make the vfssw table bigger
982 * statically, or make it grow dynamically.
984 cmn_err(CE_WARN
, "no room for '%s' in vfssw!", fsname
);
989 ASSERT(vswp
!= NULL
);
991 fstype
= vswp
- vfssw
; /* Pointer arithmetic to get the fstype */
993 /* Turn on everything by default *except* VSW_STATS */
994 vswp
->vsw_flag
= modl
->fs_vfsdef
->flags
& ~(VSW_STATS
);
996 if (modl
->fs_vfsdef
->flags
& VSW_HASPROTO
) {
997 vfs_mergeopttbl(&vfs_mntopts
, modl
->fs_vfsdef
->optproto
,
998 &vswp
->vsw_optproto
);
1000 vfs_copyopttbl(&vfs_mntopts
, &vswp
->vsw_optproto
);
1003 if (modl
->fs_vfsdef
->flags
& VSW_CANRWRO
) {
1005 * This obviously implies VSW_CANREMOUNT.
1007 vswp
->vsw_flag
|= VSW_CANREMOUNT
;
1011 * If stats are enabled system wide and for this fstype, then
1012 * set the VSW_STATS flag in the proper vfssw[] table entry.
1014 if (vopstats_enabled
&& modl
->fs_vfsdef
->flags
& VSW_STATS
) {
1015 vswp
->vsw_flag
|= VSW_STATS
;
1018 if (modl
->fs_vfsdef
->init
== NULL
)
1021 err
= (*(modl
->fs_vfsdef
->init
))(fstype
, fsname
);
1025 kmem_free(vswp
->vsw_name
, strlen(vswp
->vsw_name
)+1);
1026 vswp
->vsw_name
= "";
1029 vswp
->vsw_init
= NULL
;
1032 /* We don't want to hold the vfssw[] write lock over a kmem_alloc() */
1033 vsw_stats_enabled
= vswp
->vsw_flag
& VSW_STATS
;
1035 vfs_unrefvfssw(vswp
);
1038 /* If everything is on, set up the per-fstype vopstats */
1039 if (vsw_stats_enabled
&& vopstats_enabled
&&
1040 vopstats_fstype
&& vopstats_fstype
[fstype
] == NULL
) {
1041 (void) strlcpy(ksname
, VOPSTATS_STR
, sizeof (ksname
));
1042 (void) strlcat(ksname
, vfssw
[fstype
].vsw_name
, sizeof (ksname
));
1043 vopstats_fstype
[fstype
] =
1044 kmem_alloc(sizeof (vopstats_t
), KM_SLEEP
);
1045 initialize_vopstats(vopstats_fstype
[fstype
]);
1046 (void) new_vskstat(ksname
, vopstats_fstype
[fstype
]);
1052 * Remove a filesystem
1055 mod_removefs(struct modlfs
*modl
, struct modlinkage
*modlp
)
1061 if (moddebug
& MODDEBUG_NOAUL_FS
)
1065 if ((vswp
= vfs_getvfsswbyname(modl
->fs_vfsdef
->name
)) == NULL
) {
1066 mcp
= mod_getctl(modlp
);
1067 ASSERT(mcp
!= NULL
);
1068 modname
= mcp
->mod_modname
;
1070 cmn_err(CE_WARN
, uninstall_err
, modname
);
1073 if (vswp
->vsw_count
!= 1) {
1074 vfs_unrefvfssw(vswp
);
1080 * A mounted filesystem could still have vsw_count = 0
1081 * so we must check whether anyone is actually using our ops
1083 if (vfs_opsinuse(&vswp
->vsw_vfsops
)) {
1084 vfs_unrefvfssw(vswp
);
1089 vfs_freeopttbl(&vswp
->vsw_optproto
);
1090 vswp
->vsw_optproto
.mo_count
= 0;
1093 vswp
->vsw_init
= NULL
;
1094 vfs_unrefvfssw(vswp
);
1100 * Get status of a streams module.
1104 mod_infostrmod(struct modlstrmod
*modl
, struct modlinkage
*modlp
, int *p0
)
1106 *p0
= -1; /* no useful info */
1112 * Install a streams module.
1116 mod_installstrmod(struct modlstrmod
*modl
, struct modlinkage
*modlp
)
1118 struct fmodsw
*fp
= modl
->strmod_fmodsw
;
1120 if (!(fp
->f_flag
& D_MP
)) {
1121 cmn_err(CE_WARN
, "mod_install: MT-unsafe strmod '%s' rejected",
1126 return (fmodsw_register(fp
->f_name
, fp
->f_str
, fp
->f_flag
));
1130 * Remove a streams module.
1134 mod_removestrmod(struct modlstrmod
*modl
, struct modlinkage
*modlp
)
1136 if (moddebug
& MODDEBUG_NOAUL_STR
)
1139 return (fmodsw_unregister(modl
->strmod_fmodsw
->f_name
));
1143 * Get status of a socket module.
1147 mod_infosockmod(struct modlsockmod
*modl
, struct modlinkage
*modlp
, int *p0
)
1149 *p0
= -1; /* no useful info */
1154 * Install a socket module.
1158 mod_installsockmod(struct modlsockmod
*modl
, struct modlinkage
*modlp
)
1163 mcp
= mod_getctl(modlp
);
1164 ASSERT(mcp
!= NULL
);
1165 mod_name
= mcp
->mod_modname
;
1166 if (strcmp(mod_name
, modl
->sockmod_reg_info
->smod_name
) != 0) {
1168 cmn_err(CE_CONT
, "mod_installsockmod: different names"
1169 " %s != %s \n", mod_name
,
1170 modl
->sockmod_reg_info
->smod_name
);
1178 return (smod_register(modl
->sockmod_reg_info
));
1182 * Remove a socket module.
1186 mod_removesockmod(struct modlsockmod
*modl
, struct modlinkage
*modlp
)
1189 * unregister from the global socket creation table
1190 * check the refcnt in the lookup table
1192 return (smod_unregister(modl
->sockmod_reg_info
->smod_name
));
1196 * Get status of a scheduling class module.
1200 mod_infosched(struct modlsched
*modl
, struct modlinkage
*modlp
, int *p0
)
1205 status
= getcidbyname(modl
->sched_class
->cl_name
, &cid
);
1216 * Install a scheduling class module.
1220 mod_installsched(struct modlsched
*modl
, struct modlinkage
*modlp
)
1227 * See if module is already installed.
1229 mutex_enter(&class_lock
);
1230 status
= alloc_cid(modl
->sched_class
->cl_name
, &cid
);
1231 mutex_exit(&class_lock
);
1232 ASSERT(status
== 0);
1234 rw_enter(clp
->cl_lock
, RW_WRITER
);
1235 if (SCHED_INSTALLED(clp
)) {
1236 printf("scheduling class %s is already installed\n",
1237 modl
->sched_class
->cl_name
);
1238 rw_exit(clp
->cl_lock
);
1239 return (EBUSY
); /* it's already there */
1242 clp
->cl_init
= modl
->sched_class
->cl_init
;
1243 clp
->cl_funcs
= modl
->sched_class
->cl_funcs
;
1244 modl
->sched_class
= clp
;
1246 loaded_classes
++; /* for priocntl system call */
1247 rw_exit(clp
->cl_lock
);
1252 * Remove a scheduling class module.
1254 * we only null out the init func and the class functions because
1255 * once a class has been loaded it has that slot in the class
1256 * array until the next reboot. We don't decrement loaded_classes
1257 * because this keeps count of the number of classes that have
1258 * been loaded for this session. It will have to be this way until
1259 * we implement the class array as a linked list and do true
1260 * dynamic allocation.
1263 mod_removesched(struct modlsched
*modl
, struct modlinkage
*modlp
)
1271 status
= getcidbyname(modl
->sched_class
->cl_name
, &cid
);
1273 mcp
= mod_getctl(modlp
);
1274 ASSERT(mcp
!= NULL
);
1275 modname
= mcp
->mod_modname
;
1276 cmn_err(CE_WARN
, uninstall_err
, modname
);
1280 if (moddebug
& MODDEBUG_NOAUL_SCHED
||
1281 !rw_tryenter(clp
->cl_lock
, RW_WRITER
))
1284 clp
->cl_init
= NULL
;
1285 clp
->cl_funcs
= NULL
;
1286 rw_exit(clp
->cl_lock
);
1291 * Get status of an exec module.
1295 mod_infoexec(struct modlexec
*modl
, struct modlinkage
*modlp
, int *p0
)
1297 struct execsw
*eswp
;
1299 if ((eswp
= findexecsw(modl
->exec_execsw
->exec_magic
)) == NULL
)
1302 *p0
= eswp
- execsw
;
1308 * Install an exec module.
1311 mod_installexec(struct modlexec
*modl
, struct modlinkage
*modlp
)
1313 struct execsw
*eswp
;
1320 * See if execsw entry is already allocated. Can't use findexectype()
1321 * because we may get a recursive call to here.
1324 if ((eswp
= findexecsw(modl
->exec_execsw
->exec_magic
)) == NULL
) {
1325 mcp
= mod_getctl(modlp
);
1326 ASSERT(mcp
!= NULL
);
1327 modname
= mcp
->mod_modname
;
1328 magic
= modl
->exec_execsw
->exec_magic
;
1329 magic_size
= modl
->exec_execsw
->exec_maglen
;
1330 if ((eswp
= allocate_execsw(modname
, magic
, magic_size
)) ==
1332 printf("no unused entries in 'execsw'\n");
1336 if (eswp
->exec_func
!= NULL
) {
1337 printf("exec type %x is already installed\n",
1339 return (EBUSY
); /* it's already there! */
1342 rw_enter(eswp
->exec_lock
, RW_WRITER
);
1343 eswp
->exec_func
= modl
->exec_execsw
->exec_func
;
1344 eswp
->exec_core
= modl
->exec_execsw
->exec_core
;
1345 rw_exit(eswp
->exec_lock
);
1351 * Remove an exec module.
1354 mod_removeexec(struct modlexec
*modl
, struct modlinkage
*modlp
)
1356 struct execsw
*eswp
;
1360 eswp
= findexecsw(modl
->exec_execsw
->exec_magic
);
1362 mcp
= mod_getctl(modlp
);
1363 ASSERT(mcp
!= NULL
);
1364 modname
= mcp
->mod_modname
;
1365 cmn_err(CE_WARN
, uninstall_err
, modname
);
1368 if (moddebug
& MODDEBUG_NOAUL_EXEC
||
1369 !rw_tryenter(eswp
->exec_lock
, RW_WRITER
))
1371 eswp
->exec_func
= NULL
;
1372 eswp
->exec_core
= NULL
;
1373 rw_exit(eswp
->exec_lock
);
1378 * Find a free sysent entry or check if the specified one is free.
1380 static struct sysent
*
1381 mod_getsysent(struct modlinkage
*modlp
, struct sysent
*se
)
1387 if ((mcp
= mod_getctl(modlp
)) == NULL
) {
1389 * This happens when we're looking up the module
1390 * pointer as part of a stub installation. So
1391 * there's no need to whine at this point.
1396 mod_name
= mcp
->mod_modname
;
1398 if ((sysnum
= mod_getsysnum(mod_name
)) == -1) {
1399 cmn_err(CE_WARN
, "system call missing from bind file");
1403 if (sysnum
> 0 && sysnum
< NSYSCALL
&&
1404 (se
[sysnum
].sy_flags
& (SE_LOADABLE
| SE_NOUNLOAD
)))
1405 return (se
+ sysnum
);
1407 cmn_err(CE_WARN
, "system call entry %d is already in use", sysnum
);
1412 * IP Policy Modules.
1416 mod_infoipp(struct modlipp
*modl
, struct modlinkage
*modlp
, int *p0
)
1418 struct modctl
*mcp
= mod_getctl(modlp
);
1423 return (0); /* module is not yet installed */
1426 mid
= ipp_mod_lookup(mcp
->mod_modname
);
1433 mod_installipp(struct modlipp
*modl
, struct modlinkage
*modlp
)
1435 struct modctl
*mcp
= mod_getctl(modlp
);
1437 ASSERT(mcp
!= NULL
);
1438 return (ipp_mod_register(mcp
->mod_modname
, modl
->ipp_ops
));
1443 mod_removeipp(struct modlipp
*modl
, struct modlinkage
*modlp
)
1445 struct modctl
*mcp
= mod_getctl(modlp
);
1446 extern kthread_id_t mod_aul_thread
;
1449 ASSERT(mcp
!= NULL
);
1451 if ((moddebug
& MODDEBUG_NOAUL_IPP
) && (mod_aul_thread
== curthread
))
1454 mid
= ipp_mod_lookup(mcp
->mod_modname
);
1455 ASSERT(mid
!= IPP_MOD_INVAL
);
1457 return (ipp_mod_unregister(mid
));
1461 * Manage kiconv modules.
1465 mod_installkiconv(struct modlkiconv
*modl
, struct modlinkage
*modlp
)
1467 return (kiconv_register_module(modl
->kiconv_moddef
));
1472 mod_removekiconv(struct modlkiconv
*modl
, struct modlinkage
*modlp
)
1474 return (kiconv_unregister_module(modl
->kiconv_moddef
));