1 /* $NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $");
34 #include <sys/module.h>
36 #include <prop/proplib.h>
50 static const char *classes
[] = {
58 static const char *sources
[] = {
64 /* comparison routine for qsort */
66 modcmp(const void *a
, const void *b
)
68 const modstat_t
*msa
, *msb
;
72 return strcmp(msa
->ms_name
, msb
->ms_name
);
75 /* function which "opens" a module */
77 openkmod(kernel_t
*kernel
)
81 kernel
->iov
.iov_base
= malloc(kernel
->size
);
82 kernel
->iov
.iov_len
= kernel
->size
;
83 if (modctl(MODCTL_STAT
, &kernel
->iov
)) {
84 warn("modctl(MODCTL_STAT)");
87 if (kernel
->size
>= kernel
->iov
.iov_len
) {
90 free(kernel
->iov
.iov_base
);
91 kernel
->size
= kernel
->iov
.iov_len
;
93 kernel
->size
= kernel
->iov
.iov_len
/ sizeof(modstat_t
);
94 qsort(kernel
->iov
.iov_base
, kernel
->size
, sizeof(modstat_t
), modcmp
);
98 /* return details on the module */
100 readkmod(kernel_t
*kernel
, kmod_t
*module
)
104 if (kernel
->c
* sizeof(*ms
) >= kernel
->iov
.iov_len
) {
107 ms
= kernel
->iov
.iov_base
;
109 (void) memset(module
, 0x0, sizeof(*module
));
110 module
->name
= strdup(ms
->ms_name
);
111 module
->class = strdup(classes
[ms
->ms_class
]);
112 module
->source
= strdup(sources
[ms
->ms_source
]);
113 module
->refcnt
= ms
->ms_refcnt
;
114 module
->size
= ms
->ms_size
;
115 if (ms
->ms_required
[0]) {
116 module
->required
= strdup(ms
->ms_required
);
121 /* free up all resources allocated in a module read */
123 freekmod(kmod_t
*module
)
125 (void) free(module
->name
);
126 (void) free(module
->class);
127 (void) free(module
->source
);
128 if (module
->required
) {
129 (void) free(module
->required
);
133 /* "close" the module */
135 closekmod(kernel_t
*kernel
)
137 (void) free(kernel
->iov
.iov_base
);
141 /* do the modstat operation */
143 kmodstat(const char *modname
, FILE *fp
)
149 (void) memset(&kernel
, 0x0, sizeof(kernel
));
150 (void) memset(&module
, 0x0, sizeof(module
));
151 if (!openkmod(&kernel
)) {
152 (void) fprintf(stderr
, "can't read kernel modules\n");
155 for (modc
= 0 ; readkmod(&kernel
, &module
) ; ) {
156 if (modname
== NULL
|| strcmp(modname
, module
.name
) == 0) {
160 "NAME\t\tCLASS\tSOURCE\tREFS"
161 "\tSIZE\tREQUIRES\n");
165 (void) fprintf(fp
, "%-16s%s\t%s\t%d\t%u\t%s\n",
171 (module
.required
) ? module
.required
: "-");
176 (void) closekmod(&kernel
);
180 /* load the named module into the kernel */
182 kmodload(const char *module
)
184 prop_dictionary_t props
;
185 modctl_load_t cmdargs
;
188 props
= prop_dictionary_create();
190 propsstr
= prop_dictionary_externalize(props
);
191 if (propsstr
== NULL
) {
192 (void) fprintf(stderr
, "Failed to process properties");
196 cmdargs
.ml_filename
= module
;
197 cmdargs
.ml_flags
= 0;
198 cmdargs
.ml_props
= propsstr
;
199 cmdargs
.ml_propslen
= strlen(propsstr
);
201 if (modctl(MODCTL_LOAD
, &cmdargs
)) {
202 (void) fprintf(stderr
, "modctl failure\n");
206 (void) free(propsstr
);
207 prop_object_release(props
);
212 /* and unload the module from the kernel */
214 kmodunload(const char *name
)
216 return modctl(MODCTL_UNLOAD
, __UNCONST(name
)) == 0;
219 #endif /* USE_LIBKMOD */