43#include <sys/kernel.h>
47#include <sys/malloc.h>
48#include <sys/module.h>
49#include <sys/module_khelp.h>
52#include <sys/refcount.h>
53#include <sys/rwlock.h>
59static TAILQ_HEAD(helper_head, helper) helpers = TAILQ_HEAD_INITIALIZER(helpers);
65#define KHELP_LIST_WLOCK() rw_wlock(&khelp_list_lock)
66#define KHELP_LIST_WUNLOCK() rw_wunlock(&khelp_list_lock)
67#define KHELP_LIST_RLOCK() rw_rlock(&khelp_list_lock)
68#define KHELP_LIST_RUNLOCK() rw_runlock(&khelp_list_lock)
69#define KHELP_LIST_LOCK_ASSERT() rw_assert(&khelp_list_lock, RA_LOCKED)
72khelp_register_helper(
struct helper *h)
75 int error, i, inserted;
78 refcount_init(&h->h_refcount, 0);
82 for (i = 0; i < h->h_nhooks && !error; i++) {
84 h->h_hooks[i].hook_helper = h;
87 printf(
"%s: \"%s\" khelp module unable to "
88 "hook type %d id %d due to error %d\n", __func__,
89 h->h_name, h->h_hooks[i].hook_type,
90 h->h_hooks[i].hook_id, error);
94 for (i--; i >= 0; i--)
104 TAILQ_FOREACH(tmph, &helpers, h_next) {
105 if (tmph->h_id < h->h_id) {
106 TAILQ_INSERT_BEFORE(tmph, h, h_next);
113 TAILQ_INSERT_TAIL(&helpers, h, h_next);
127 if (h->h_refcount > 0)
131 TAILQ_FOREACH(tmph, &helpers, h_next) {
133 TAILQ_REMOVE(&helpers, h, h_next);
142 for (i = 0; i < h->h_nhooks; i++)
157 KASSERT(hosd != NULL, (
"struct osd not initialised!"));
162 TAILQ_FOREACH(h, &helpers, h_next) {
164 if (h->h_classes &
classes && h->h_flags & HELPER_NEEDS_OSD) {
165 hdata = uma_zalloc(h->h_zone, M_NOWAIT);
170 osd_set(OSD_KHELP, hosd, h->h_id, hdata);
171 refcount_acquire(&h->h_refcount);
177 TAILQ_FOREACH(h, &helpers, h_next) {
193 KASSERT(hosd != NULL, (
"struct osd not initialised!"));
204 TAILQ_FOREACH(h, &helpers, h_next)
216 if (h->h_flags & HELPER_NEEDS_OSD) {
222 hdata =
osd_get(OSD_KHELP, hosd, h->h_id);
224 uma_zfree(h->h_zone, hdata);
225 osd_del(OSD_KHELP, hosd, h->h_id);
226 refcount_release(&h->h_refcount);
235 return (
osd_get(OSD_KHELP, hosd,
id));
247 TAILQ_FOREACH(h, &helpers, h_next) {
248 if (strncmp(h->h_name, hname, HELPER_NAME_MAXLEN) == 0) {
297 TAILQ_FOREACH(h, &helpers, h_next) {
298 for (i = 0; i < h->h_nhooks; i++) {
299 if (hhh->hhh_type != h->h_hooks[i].hook_type ||
300 hhh->hhh_id != h->h_hooks[i].hook_id)
304 printf(
"%s: \"%s\" khelp module unable to "
305 "hook type %d id %d due to error %d\n",
307 h->h_hooks[i].hook_type,
308 h->h_hooks[i].hook_id, error);
319 struct khelp_modevent_data *kmd;
322 kmd = (
struct khelp_modevent_data *)
data;
327 if (kmd->helper->h_flags & HELPER_NEEDS_OSD) {
328 if (kmd->uma_zsize <= 0) {
329 printf(
"Use KHELP_DECLARE_MOD_UMA() instead!\n");
333 kmd->helper->h_zone = uma_zcreate(kmd->name,
334 kmd->uma_zsize, kmd->umactor, kmd->umadtor, NULL,
336 if (kmd->helper->h_zone == NULL) {
341 strlcpy(kmd->helper->h_name, kmd->name, HELPER_NAME_MAXLEN);
342 kmd->helper->h_hooks = kmd->hooks;
343 kmd->helper->h_nhooks = kmd->nhooks;
344 if (kmd->helper->mod_init != NULL)
345 error = kmd->helper->mod_init();
347 error = khelp_register_helper(kmd->helper);
355 if (kmd->helper->h_flags & HELPER_NEEDS_OSD)
356 uma_zdestroy(kmd->helper->h_zone);
357 if (kmd->helper->mod_destroy != NULL)
358 kmd->helper->mod_destroy();
359 }
else if (error == ENOENT)
362 else if (error == EBUSY)
363 printf(
"Khelp module \"%s\" can't unload until its "
364 "refcount drops from %d to 0.\n", kmd->name,
365 kmd->helper->h_refcount);
int hhook_add_hook_lookup(struct hookinfo *hki, uint32_t flags)
int hhook_remove_hook_lookup(struct hookinfo *hki)
int hhook_add_hook(struct hhook_head *hhh, struct hookinfo *hki, uint32_t flags)
int khelp_init_osd(uint32_t classes, struct osd *hosd)
static void khelp_remove_osd(struct helper *h, struct osd *hosd)
static struct rwlock khelp_list_lock
RW_SYSINIT(khelplistlock, &khelp_list_lock, "helper list lock")
#define KHELP_LIST_WUNLOCK()
#define KHELP_LIST_RUNLOCK()
#define KHELP_LIST_WLOCK()
int khelp_destroy_osd(struct osd *hosd)
int khelp_modevent(module_t mod, int event_type, void *data)
#define KHELP_LIST_RLOCK()
static TAILQ_HEAD(helper_head, helper)
int khelp_remove_hhook(struct hookinfo *hki)
void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags)
int khelp_deregister_helper(struct helper *h)
void * khelp_get_osd(struct osd *hosd, int32_t id)
int khelp_add_hhook(struct hookinfo *hki, uint32_t flags)
int32_t khelp_get_id(char *hname)
static linker_class_list_t classes
int osd_register(u_int type, osd_destructor_t destructor, osd_method_t *methods)
int osd_set(u_int type, struct osd *osd, u_int slot, void *value)
void osd_deregister(u_int type, u_int slot)
void osd_del(u_int type, struct osd *osd, u_int slot)
void * osd_get(u_int type, struct osd *osd, u_int slot)
int printf(const char *fmt,...)