37 #include <sys/cdefs.h>
40 #include <sys/param.h>
41 #include <sys/kernel.h>
42 #include <sys/hhook.h>
43 #include <sys/khelp.h>
45 #include <sys/malloc.h>
46 #include <sys/module.h>
47 #include <sys/module_khelp.h>
49 #include <sys/queue.h>
50 #include <sys/refcount.h>
51 #include <sys/rwlock.h>
52 #include <sys/systm.h>
57 static TAILQ_HEAD(helper_head, helper) helpers = TAILQ_HEAD_INITIALIZER(helpers);
63 #define KHELP_LIST_WLOCK() rw_wlock(&khelp_list_lock)
64 #define KHELP_LIST_WUNLOCK() rw_wunlock(&khelp_list_lock)
65 #define KHELP_LIST_RLOCK() rw_rlock(&khelp_list_lock)
66 #define KHELP_LIST_RUNLOCK() rw_runlock(&khelp_list_lock)
67 #define KHELP_LIST_LOCK_ASSERT() rw_assert(&khelp_list_lock, RA_LOCKED)
70 khelp_register_helper(
struct helper *h)
73 int error, i, inserted;
76 refcount_init(&h->h_refcount, 0);
80 for (i = 0; i < h->h_nhooks && !error; i++) {
82 h->h_hooks[i].hook_helper = h;
85 printf(
"%s: \"%s\" khelp module unable to "
86 "hook type %d id %d due to error %d\n", __func__,
87 h->h_name, h->h_hooks[i].hook_type,
88 h->h_hooks[i].hook_id, error);
92 for (i--; i >= 0; i--)
102 TAILQ_FOREACH(tmph, &helpers, h_next) {
103 if (tmph->h_id < h->h_id) {
104 TAILQ_INSERT_BEFORE(tmph, h, h_next);
111 TAILQ_INSERT_TAIL(&helpers, h, h_next);
125 if (h->h_refcount > 0)
129 TAILQ_FOREACH(tmph, &helpers, h_next) {
131 TAILQ_REMOVE(&helpers, h, h_next);
140 for (i = 0; i < h->h_nhooks; i++)
155 KASSERT(hosd != NULL, (
"struct osd not initialised!"));
160 TAILQ_FOREACH(h, &helpers, h_next) {
162 if (h->h_classes & classes && h->h_flags & HELPER_NEEDS_OSD) {
163 hdata = uma_zalloc(h->h_zone, M_NOWAIT);
168 osd_set(OSD_KHELP, hosd, h->h_id, hdata);
169 refcount_acquire(&h->h_refcount);
175 TAILQ_FOREACH(h, &helpers, h_next) {
176 if (h->h_classes & classes)
191 KASSERT(hosd != NULL, (
"struct osd not initialised!"));
202 TAILQ_FOREACH(h, &helpers, h_next)
214 if (h->h_flags & HELPER_NEEDS_OSD) {
220 hdata =
osd_get(OSD_KHELP, hosd, h->h_id);
222 uma_zfree(h->h_zone, hdata);
223 osd_del(OSD_KHELP, hosd, h->h_id);
224 refcount_release(&h->h_refcount);
233 return (
osd_get(OSD_KHELP, hosd,
id));
245 TAILQ_FOREACH(h, &helpers, h_next) {
246 if (strncmp(h->h_name, hname, HELPER_NAME_MAXLEN) == 0) {
295 TAILQ_FOREACH(h, &helpers, h_next) {
296 for (i = 0; i < h->h_nhooks; i++) {
297 if (hhh->hhh_type != h->h_hooks[i].hook_type ||
298 hhh->hhh_id != h->h_hooks[i].hook_id)
302 printf(
"%s: \"%s\" khelp module unable to "
303 "hook type %d id %d due to error %d\n",
305 h->h_hooks[i].hook_type,
306 h->h_hooks[i].hook_id, error);
317 struct khelp_modevent_data *kmd;
320 kmd = (
struct khelp_modevent_data *)data;
325 if (kmd->helper->h_flags & HELPER_NEEDS_OSD) {
326 if (kmd->uma_zsize <= 0) {
327 printf(
"Use KHELP_DECLARE_MOD_UMA() instead!\n");
331 kmd->helper->h_zone = uma_zcreate(kmd->name,
332 kmd->uma_zsize, kmd->umactor, kmd->umadtor, NULL,
334 if (kmd->helper->h_zone == NULL) {
339 strlcpy(kmd->helper->h_name, kmd->name, HELPER_NAME_MAXLEN);
340 kmd->helper->h_hooks = kmd->hooks;
341 kmd->helper->h_nhooks = kmd->nhooks;
342 if (kmd->helper->mod_init != NULL)
343 error = kmd->helper->mod_init();
345 error = khelp_register_helper(kmd->helper);
353 if (kmd->helper->h_flags & HELPER_NEEDS_OSD)
354 uma_zdestroy(kmd->helper->h_zone);
355 if (kmd->helper->mod_destroy != NULL)
356 kmd->helper->mod_destroy();
357 }
else if (error == ENOENT)
360 else if (error == EBUSY)
361 printf(
"Khelp module \"%s\" can't unload until its "
362 "refcount drops from %d to 0.\n", kmd->name,
363 kmd->helper->h_refcount);
int32_t khelp_get_id(char *hname)
int hhook_add_hook_lookup(struct hookinfo *hki, uint32_t flags)
void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags)
RW_SYSINIT(khelplistlock,&khelp_list_lock,"helper list lock")
int khelp_init_osd(uint32_t classes, struct osd *hosd)
int khelp_destroy_osd(struct osd *hosd)
#define KHELP_LIST_RUNLOCK()
void osd_deregister(u_int type, u_int slot)
static void khelp_remove_osd(struct helper *h, struct osd *hosd)
int khelp_remove_hhook(struct hookinfo *hki)
int hhook_add_hook(struct hhook_head *hhh, struct hookinfo *hki, uint32_t flags)
#define KHELP_LIST_WUNLOCK()
void * osd_get(u_int type, struct osd *osd, u_int slot)
static linker_class_list_t classes
int khelp_add_hhook(struct hookinfo *hki, uint32_t flags)
int osd_set(u_int type, struct osd *osd, u_int slot, void *value)
void * khelp_get_osd(struct osd *hosd, int32_t id)
int hhook_remove_hook_lookup(struct hookinfo *hki)
int khelp_deregister_helper(struct helper *h)
int printf(const char *fmt,...)
int osd_register(u_int type, osd_destructor_t destructor, osd_method_t *methods)
#define KHELP_LIST_RLOCK()
static TAILQ_HEAD(helper_head, helper)
void osd_del(u_int type, struct osd *osd, u_int slot)
int khelp_modevent(module_t mod, int event_type, void *data)
#define KHELP_LIST_WLOCK()
static struct rwlock khelp_list_lock