table of contents
KHELP(9) | Kernel Developer's Manual | KHELP(9) |
NAME¶
khelp
, khelp_init_osd
,
khelp_destroy_osd
,
khelp_get_id
, khelp_get_osd
,
khelp_add_hhook
,
khelp_remove_hhook
,
KHELP_DECLARE_MOD
,
KHELP_DECLARE_MOD_UMA
—
SYNOPSIS¶
#include <sys/khelp.h>
#include <sys/module_khelp.h>
int
khelp_init_osd
(uint32_t
classes, struct osd
*hosd);
int
khelp_destroy_osd
(struct
osd *hosd);
int32_t
khelp_get_id
(char
*hname);
void *
khelp_get_osd
(struct
osd *hosd, int32_t
id);
int
khelp_add_hhook
(struct
hookinfo *hki, uint32_t
flags);
int
khelp_remove_hhook
(struct
hookinfo *hki);
KHELP_DECLARE_MOD
(hname,
hdata,
hhooks,
version);
KHELP_DECLARE_MOD_UMA
(hname,
hdata,
hhooks,
version,
ctor,
dtor);
DESCRIPTION¶
khelp
provides a framework for managing
khelp
modules, which indirectly use the
hhook(9) KPI to register their hook functions with hook
points of interest within the kernel. Khelp modules aim to provide a
structured way to dynamically extend the kernel at runtime in an ABI
preserving manner. Depending on the subsystem providing hook points, a
khelp
module may be able to associate per-object data
for maintaining relevant state between hook calls. The
hhook(9) and khelp
frameworks are
tightly integrated and anyone interested in khelp
should also read the hhook(9) manual page thoroughly.
Information for Khelp Module Implementors¶
khelp
modules are represented within the
khelp
framework by a struct
helper which has the following members:
struct helper { int (*mod_init) (void); int (*mod_destroy) (void); #define HELPER_NAME_MAXLEN 16 char h_name[HELPER_NAME_MAXLEN]; uma_zone_t h_zone; struct hookinfo *h_hooks; uint32_t h_nhooks; uint32_t h_classes; int32_t h_id; volatile uint32_t h_refcount; uint16_t h_flags; TAILQ_ENTRY(helper) h_next; };
Modules must instantiate a struct helper, but are only required to set the h_classes field, and may optionally set the h_flags, mod_init and mod_destroy fields where required. The framework takes care of all other fields and modules should refrain from manipulating them. Using the C99 designated initialiser feature to set fields is encouraged.
If specified, the mod_init function will be
run by the khelp
framework prior to completing the
registration process. Returning a non-zero value from the
mod_init function will abort the registration process
and fail to load the module. If specified, the
mod_destroy function will be run by the
khelp
framework during the deregistration process,
after the module has been deregistered by the khelp
framework. The return value is currently ignored. Valid
khelp
classes are defined in
<sys/khelp.h>
. Valid flags
are defined in
<sys/module_khelp.h>
. The
HELPER_NEEDS_OSD flag should be set in the h_flags
field if the khelp
module requires persistent
per-object data storage. There is no programmatic way (yet) to check if a
khelp
class provides the ability for
khelp
modules to associate persistent per-object
data, so a manual check is required.
The KHELP_DECLARE_MOD
() and
KHELP_DECLARE_MOD_UMA
() macros provide convenient
wrappers around the DECLARE_MODULE(9) macro, and are used
to register a khelp
module with the
khelp
framework.
KHELP_DECLARE_MOD_UMA
() should only be used by
modules which require the use of persistent per-object storage i.e. modules
which set the HELPER_NEEDS_OSD flag in their struct
helper's h_flags field.
The first four arguments common to both macros are as follows. The
hname argument specifies the unique
ascii(7) name for the khelp
module. It should be no longer than HELPER_NAME_MAXLEN-1 characters in
length. The hdata argument is a pointer to the
module's struct helper. The
hhooks argument points to a static array of
struct hookinfo structures. The array should contain a
struct hookinfo for each hhook(9)
point the module wishes to hook, even when using the same hook function
multiple times for different hhook(9) points. The
version argument specifies a version number for the
module which will be passed to MODULE_VERSION(9). The
KHELP_DECLARE_MOD_UMA
() macro takes the additional
ctor and dtor arguments, which
specify optional uma(9) constructor and destructor
functions. NULL should be passed where the functionality is not
required.
The khelp_get_id
() function returns the
numeric identifier for the khelp
module with name
hname.
The khelp_get_osd
() function is used to
obtain the per-object data pointer for a specified
khelp
module. The hosd
argument is a pointer to the underlying subsystem object's
struct osd. This is provided by the
hhook(9) framework when calling into a
khelp
module's hook function. The
id argument specifies the numeric identifier for the
khelp
module to extract the data pointer from
hosd for. The id is obtained
using the khelp_get_id
() function.
The khelp_add_hhook
() and
khelp_remove_hhook
() functions allow a
khelp
module to dynamically hook/unhook
hhook(9) points at run time. The hki
argument specifies a pointer to a struct hookinfo
which encapsulates the required information about the
hhook(9) point and hook function being manipulated. The
HHOOK_WAITOK flag may be passed in via the flags
argument of khelp_add_hhook
() if
malloc(9) is allowed to sleep waiting for memory to become
available.
Integrating Khelp Into a Kernel Subsystem¶
Most of the work required to allowkhelp
modules to do
useful things relates to defining and instantiating suitable
hhook(9) points for khelp
modules to
hook into. The only additional decision a subsystem needs to make is whether
it wants to allow khelp
modules to associate
persistent per-object data. Providing support for persistent data storage can
allow khelp
modules to perform more complex
functionality which may be desirable. Subsystems which want to allow Khelp
modules to associate persistent per-object data with one of the subsystem's
data structures need to make the following two key changes:
- Embed a struct osd pointer in the structure definition for the object.
- Add calls to
khelp_init_osd
() andkhelp_destroy_osd
() to the subsystem code paths which are responsible for respectively initialising and destroying the object.
The khelp_init_osd
() function initialises
the per-object data storage for all currently loaded
khelp
modules of appropriate classes which have set
the HELPER_NEEDS_OSD flag in their h_flags field. The
classes argument specifies a bitmask of
khelp
classes which this subsystem associates with.
If a khelp
module matches any of the classes in the
bitmask, that module will be associated with the object. The
hosd argument specifies the pointer to the object's
struct osd which will be used to provide the
persistent storage for use by khelp
modules.
The khelp_destroy_osd
() function frees all
memory that was associated with an object's struct osd
by a previous call to khelp_init_osd
(). The
hosd argument specifies the pointer to the object's
struct osd which will be purged in preparation for
destruction.
IMPLEMENTATION NOTES¶
khelp
modules are protected from being prematurely
unloaded by a reference count. The count is incremented each time a subsystem
calls khelp_init_osd
() causing persistent storage to
be allocated for the module, and decremented for each corresponding call to
khelp_destroy_osd
(). Only when a module's reference
count has dropped to zero can the module be unloaded.
RETURN VALUES¶
Thekhelp_init_osd
() function returns zero if no errors
occurred. It returns ENOMEM if a khelp
module which
requires per-object storage fails to allocate the necessary memory.
The khelp_destroy_osd
() function only
returns zero to indicate that no errors occurred.
The khelp_get_id
() function returns the
unique numeric identifier for the registered khelp
module with name hname. It return -1 if no module with
the specified name is currently registered.
The khelp_get_osd
() function returns the
pointer to the khelp
module's persistent object
storage memory. If the module identified by id does
not have persistent object storage registered with the object's
hosd struct osd, NULL is
returned.
The khelp_add_hhook
() function returns
zero if no errors occurred. It returns ENOENT if it could not find the
requested hhook(9) point. It returns ENOMEM if
malloc(9) failed to allocate memory. It returns EEXIST if
attempting to register the same hook function more than once for the same
hhook(9) point.
The khelp_remove_hhook
() function returns
zero if no errors occurred. It returns ENOENT if it could not find the
requested hhook(9) point.
EXAMPLES¶
A well commented example Khelp module can be found at: /usr/share/examples/kld/khelp/h_example.cThe Enhanced Round Trip Time (ERTT) h_ertt(4)
khelp
module provides a more complex example of what
is possible.
SEE ALSO¶
h_ertt(4), hhook(9), osd(9)ACKNOWLEDGEMENTS¶
Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley.HISTORY¶
Thekhelp
kernel helper framework first appeared in
FreeBSD 9.0.
The khelp
framework was first released in
2010 by Lawrence Stewart whilst studying at Swinburne University of
Technology's Centre for Advanced Internet Architectures, Melbourne,
Australia. More details are available at:
AUTHORS¶
Thekhelp
framework was written by
Lawrence Stewart
<lstewart@FreeBSD.org>.
This manual page was written by David Hayes <david.hayes@ieee.org> and Lawrence Stewart <lstewart@FreeBSD.org>.
February 15, 2011 | Linux 4.19.0-10-amd64 |