1.\" 2.\" Copyright (c) 2010-2011 The FreeBSD Foundation 3.\" All rights reserved. 4.\" 5.\" This documentation was written at the Centre for Advanced Internet 6.\" Architectures, Swinburne University, Melbourne, Australia by David Hayes and 7.\" Lawrence Stewart under sponsorship from the FreeBSD Foundation. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 22.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" SUCH DAMAGE. 29.\" 30.\" $FreeBSD$ 31.\" 32.Dd February 15, 2011 33.Dt khelp 9 34.Os 35.Sh NAME 36.Nm khelp , 37.Nm khelp_init_osd , 38.Nm khelp_destroy_osd , 39.Nm khelp_get_id , 40.Nm khelp_get_osd , 41.Nm khelp_add_hhook , 42.Nm khelp_remove_hhook , 43.Nm KHELP_DECLARE_MOD , 44.Nm KHELP_DECLARE_MOD_UMA 45.Nd Kernel Helper Framework 46.Sh SYNOPSIS 47.In sys/khelp.h 48.In sys/module_khelp.h 49.Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd" 50.Fn "int khelp_destroy_osd" "struct osd *hosd" 51.Fn "int32_t khelp_get_id" "char *hname" 52.Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id" 53.Fn "int khelp_add_hhook" "struct hookinfo *hki" "uint32_t flags" 54.Fn "int khelp_remove_hhook" "struct hookinfo *hki" 55.Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version" 56.Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor" 57.Sh DESCRIPTION 58.Nm 59provides a framework for managing 60.Nm 61modules, which indirectly use the 62.Xr hhook 9 63KPI to register their hook functions with hook points of interest within the 64kernel. 65Khelp modules aim to provide a structured way to dynamically extend the kernel 66at runtime in an ABI preserving manner. 67Depending on the subsystem providing hook points, a 68.Nm 69module may be able to associate per-object data for maintaining relevant state 70between hook calls. 71The 72.Xr hhook 9 73and 74.Nm 75frameworks are tightly integrated and anyone interested in 76.Nm 77should also read the 78.Xr hhook 9 79manual page thoroughly. 80.Ss Information for Khelp Module Implementors 81.Nm 82modules are represented within the 83.Nm 84framework by a 85.Vt struct helper 86which has the following members: 87.Bd -literal -offset indent 88struct helper { 89 int (*mod_init) (void); 90 int (*mod_destroy) (void); 91#define HELPER_NAME_MAXLEN 16 92 char h_name[HELPER_NAME_MAXLEN]; 93 uma_zone_t h_zone; 94 struct hookinfo *h_hooks; 95 uint32_t h_nhooks; 96 uint32_t h_classes; 97 int32_t h_id; 98 volatile uint32_t h_refcount; 99 uint16_t h_flags; 100 TAILQ_ENTRY(helper) h_next; 101}; 102.Ed 103.Pp 104Modules must instantiate a 105.Vt struct helper , 106but are only required to set the 107.Va h_classes 108field, and may optionally set the 109.Va h_flags , 110.Va mod_init 111and 112.Va mod_destroy 113fields where required. 114The framework takes care of all other fields and modules should refrain from 115manipulating them. 116Using the C99 designated initialiser feature to set fields is encouraged. 117.Pp 118If specified, the 119.Va mod_init 120function will be run by the 121.Nm 122framework prior to completing the registration process. 123Returning a non-zero value from the 124.Va mod_init 125function will abort the registration process and fail to load the module. 126If specified, the 127.Va mod_destroy 128function will be run by the 129.Nm 130framework during the deregistration process, after the module has been 131deregistered by the 132.Nm 133framework. 134The return value is currently ignored. 135Valid 136.Nm 137classes are defined in 138.In sys/khelp.h . 139Valid flags are defined in 140.In sys/module_khelp.h . 141The HELPER_NEEDS_OSD flag should be set in the 142.Va h_flags 143field if the 144.Nm 145module requires persistent per-object data storage. 146There is no programmatic way (yet) to check if a 147.Nm 148class provides the ability for 149.Nm 150modules to associate persistent per-object data, so a manual check is required. 151.Pp 152The 153.Fn KHELP_DECLARE_MOD 154and 155.Fn KHELP_DECLARE_MOD_UMA 156macros provide convenient wrappers around the 157.Xr DECLARE_MODULE 9 158macro, and are used to register a 159.Nm 160module with the 161.Nm 162framework. 163.Fn KHELP_DECLARE_MOD_UMA 164should only be used by modules which require the use of persistent per-object 165storage i.e. modules which set the HELPER_NEEDS_OSD flag in their 166.Vt struct helper Ns 's 167.Va h_flags 168field. 169.Pp 170The first four arguments common to both macros are as follows. 171The 172.Fa hname 173argument specifies the unique 174.Xr ascii 7 175name for the 176.Nm 177module. 178It should be no longer than HELPER_NAME_MAXLEN-1 characters in length. 179The 180.Fa hdata 181argument is a pointer to the module's 182.Vt struct helper . 183The 184.Fa hhooks 185argument points to a static array of 186.Vt struct hookinfo 187structures. 188The array should contain a 189.Vt struct hookinfo 190for each 191.Xr hhook 9 192point the module wishes to hook, even when using the same hook function multiple 193times for different 194.Xr hhook 9 195points. 196The 197.Fa version 198argument specifies a version number for the module which will be passed to 199.Xr MODULE_VERSION 9 . 200The 201.Fn KHELP_DECLARE_MOD_UMA 202macro takes the additional 203.Fa ctor 204and 205.Fa dtor 206arguments, which specify optional 207.Xr uma 9 208constructor and destructor functions. 209NULL should be passed where the functionality is not required. 210.Pp 211The 212.Fn khelp_get_id 213function returns the numeric identifier for the 214.Nm 215module with name 216.Fa hname . 217.Pp 218The 219.Fn khelp_get_osd 220function is used to obtain the per-object data pointer for a specified 221.Nm 222module. 223The 224.Fa hosd 225argument is a pointer to the underlying subsystem object's 226.Vt struct osd . 227This is provided by the 228.Xr hhook 9 229framework when calling into a 230.Nm 231module's hook function. 232The 233.Fa id 234argument specifies the numeric identifier for the 235.Nm 236module to extract the data pointer from 237.Fa hosd 238for. 239The 240.Fa id 241is obtained using the 242.Fn khelp_get_id 243function. 244.Pp 245The 246.Fn khelp_add_hhook 247and 248.Fn khelp_remove_hhook 249functions allow a 250.Nm 251module to dynamically hook/unhook 252.Xr hhook 9 253points at run time. 254The 255.Fa hki 256argument specifies a pointer to a 257.Vt struct hookinfo 258which encapsulates the required information about the 259.Xr hhook 9 260point and hook function being manipulated. 261The HHOOK_WAITOK flag may be passed in via the 262.Fa flags 263argument of 264.Fn khelp_add_hhook 265if 266.Xr malloc 9 267is allowed to sleep waiting for memory to become available. 268.Ss Integrating Khelp Into a Kernel Subsystem 269Most of the work required to allow 270.Nm 271modules to do useful things relates to defining and instantiating suitable 272.Xr hhook 9 273points for 274.Nm 275modules to hook into. 276The only additional decision a subsystem needs to make is whether it wants to 277allow 278.Nm 279modules to associate persistent per-object data. 280Providing support for persistent data storage can allow 281.Nm 282modules to perform more complex functionality which may be desirable. 283Subsystems which want to allow Khelp modules to associate 284persistent per-object data with one of the subsystem's data structures need to 285make the following two key changes: 286.Bl -bullet 287.It 288Embed a 289.Vt struct osd 290pointer in the structure definition for the object. 291.It 292Add calls to 293.Fn khelp_init_osd 294and 295.Fn khelp_destroy_osd 296to the subsystem code paths which are responsible for respectively initialising 297and destroying the object. 298.El 299.Pp 300The 301.Fn khelp_init_osd 302function initialises the per-object data storage for all currently loaded 303.Nm 304modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their 305.Va h_flags 306field. 307The 308.Fa classes 309argument specifies a bitmask of 310.Nm 311classes which this subsystem associates with. 312If a 313.Nm 314module matches any of the classes in the bitmask, that module will be associated 315with the object. 316The 317.Fa hosd 318argument specifies the pointer to the object's 319.Vt struct osd 320which will be used to provide the persistent storage for use by 321.Nm 322modules. 323.Pp 324The 325.Fn khelp_destroy_osd 326function frees all memory that was associated with an object's 327.Vt struct osd 328by a previous call to 329.Fn khelp_init_osd . 330The 331.Fa hosd 332argument specifies the pointer to the object's 333.Vt struct osd 334which will be purged in preparation for destruction. 335.Sh IMPLEMENTATION NOTES 336.Nm 337modules are protected from being prematurely unloaded by a reference count. 338The count is incremented each time a subsystem calls 339.Fn khelp_init_osd 340causing persistent storage to be allocated for the module, and decremented for 341each corresponding call to 342.Fn khelp_destroy_osd . 343Only when a module's reference count has dropped to zero can the module be 344unloaded. 345.Sh RETURN VALUES 346The 347.Fn khelp_init_osd 348function returns zero if no errors occurred. 349It returns ENOMEM if a 350.Nm 351module which requires per-object storage fails to allocate the necessary memory. 352.Pp 353The 354.Fn khelp_destroy_osd 355function only returns zero to indicate that no errors occurred. 356.Pp 357The 358.Fn khelp_get_id 359function returns the unique numeric identifier for the registered 360.Nm 361module with name 362.Fa hname . 363It return -1 if no module with the specified name is currently registered. 364.Pp 365The 366.Fn khelp_get_osd 367function returns the pointer to the 368.Nm 369module's persistent object storage memory. 370If the module identified by 371.Fa id 372does not have persistent object storage registered with the object's 373.Fa hosd 374.Vt struct osd , 375NULL is returned. 376.Pp 377The 378.Fn khelp_add_hhook 379function returns zero if no errors occurred. 380It returns ENOENT if it could not find the requested 381.Xr hhook 9 382point. 383It returns ENOMEM if 384.Xr malloc 9 385failed to allocate memory. 386It returns EEXIST if attempting to register the same hook function more than 387once for the same 388.Xr hhook 9 389point. 390.Pp 391The 392.Fn khelp_remove_hhook 393function returns zero if no errors occurred. 394It returns ENOENT if it could not find the requested 395.Xr hhook 9 396point. 397.Sh EXAMPLES 398A well commented example Khelp module can be found at: 399.Pa /usr/share/examples/kld/khelp/h_example.c 400.Pp 401The Enhanced Round Trip Time (ERTT) 402.Xr h_ertt 4 403.Nm 404module provides a more complex example of what is possible. 405.Sh SEE ALSO 406.Xr h_ertt 4 , 407.Xr hhook 9 , 408.Xr osd 9 409.Sh ACKNOWLEDGEMENTS 410Development and testing of this software were made possible in part by grants 411from the FreeBSD Foundation and Cisco University Research Program Fund at 412Community Foundation Silicon Valley. 413.Sh HISTORY 414The 415.Nm 416kernel helper framework first appeared in 417.Fx 9.0 . 418.Pp 419The 420.Nm 421framework was first released in 2010 by Lawrence Stewart whilst studying at 422Swinburne University's Centre for Advanced Internet Architectures, Melbourne, 423Australia. 424More details are available at: 425.Pp 426http://caia.swin.edu.au/urp/newtcp/ 427.Sh AUTHORS 428.An -nosplit 429The 430.Nm 431framework was written by 432.An Lawrence Stewart Aq lstewart@FreeBSD.org . 433.Pp 434This manual page was written by 435.An David Hayes Aq david.hayes@ieee.org 436and 437.An Lawrence Stewart Aq lstewart@FreeBSD.org . 438