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