1.\" 2.\" Copyright (c) 2000, Andrzej Bialecki <abial@FreeBSD.org> 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in the 12.\" documentation and/or other materials provided with the distribution. 13.\" 3. The name of the author may not be used to endorse or promote products 14.\" derived from this software without specific prior written permission. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26.\" SUCH DAMAGE. 27.\" 28.\" 29.Dd December 2, 2019 30.Dt SYSCTL_ADD_OID 9 31.Os 32.Sh NAME 33.Nm sysctl_add_oid , 34.Nm sysctl_remove_oid , 35.Nm SYSCTL_CHILDREN , 36.Nm SYSCTL_STATIC_CHILDREN , 37.Nm SYSCTL_ADD_OID , 38.Nm SYSCTL_ADD_NODE , 39.Nm SYSCTL_ADD_STRING , 40.Nm SYSCTL_ADD_BIT32 , 41.Nm SYSCTL_ADD_BIT64 , 42.Nm SYSCTL_ADD_INT , 43.Nm SYSCTL_ADD_U32 , 44.Nm SYSCTL_ADD_UINT , 45.Nm SYSCTL_ADD_LONG , 46.Nm SYSCTL_ADD_ULONG , 47.Nm SYSCTL_ADD_QUAD , 48.Nm SYSCTL_ADD_UQUAD , 49.Nm SYSCTL_ADD_OPAQUE , 50.Nm SYSCTL_ADD_STRUCT , 51.Nm SYSCTL_ADD_PROC 52.Nd runtime sysctl tree manipulation 53.Sh SYNOPSIS 54.In sys/sysctl.h 55.Ft struct sysctl_oid * 56.Fo sysctl_add_oid 57.Fa "struct sysctl_ctx_list *ctx" 58.Fa "struct sysctl_oid_list *parent" 59.Fa "int number" 60.Fa "const char *name" 61.Fa "int kind" 62.Fa "void *arg1" 63.Fa "int arg2" 64.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)" 65.Fa "const char *format" 66.Fa "const char *descr" 67.Fc 68.Ft int 69.Fo sysctl_remove_oid 70.Fa "struct sysctl_oid *oidp" 71.Fa "int del" 72.Fa "int recurse" 73.Fc 74.Ft struct sysctl_oid_list * 75.Fo SYSCTL_CHILDREN 76.Fa "struct sysctl_oid *oidp" 77.Fc 78.Ft struct sysctl_oid_list * 79.Fo SYSCTL_STATIC_CHILDREN 80.Fa "struct sysctl_oid_list oid_name" 81.Fc 82.Ft struct sysctl_oid * 83.Fo SYSCTL_ADD_OID 84.Fa "struct sysctl_ctx_list *ctx" 85.Fa "struct sysctl_oid_list *parent" 86.Fa "int number" 87.Fa "const char *name" 88.Fa "int kind" 89.Fa "void *arg1" 90.Fa "int arg2" 91.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)" 92.Fa "const char *format" 93.Fa "const char *descr" 94.Fc 95.Ft struct sysctl_oid * 96.Fo SYSCTL_ADD_NODE 97.Fa "struct sysctl_ctx_list *ctx" 98.Fa "struct sysctl_oid_list *parent" 99.Fa "int number" 100.Fa "const char *name" 101.Fa "int access" 102.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)" 103.Fa "const char *descr" 104.Fc 105.Ft struct sysctl_oid * 106.Fo SYSCTL_ADD_S8 107.Fa "struct sysctl_ctx_list *ctx" 108.Fa "struct sysctl_oid_list *parent" 109.Fa "int number" 110.Fa "const char *name" 111.Fa "int access" 112.Fa "int8_t *arg" 113.Fa "int len" 114.Fa "const char *descr" 115.Fc 116.Ft struct sysctl_oid * 117.Fo SYSCTL_ADD_S16 118.Fa "struct sysctl_ctx_list *ctx" 119.Fa "struct sysctl_oid_list *parent" 120.Fa "int number" 121.Fa "const char *name" 122.Fa "int access" 123.Fa "int16_t *arg" 124.Fa "int len" 125.Fa "const char *descr" 126.Fc 127.Ft struct sysctl_oid * 128.Fo SYSCTL_ADD_S32 129.Fa "struct sysctl_ctx_list *ctx" 130.Fa "struct sysctl_oid_list *parent" 131.Fa "int number" 132.Fa "const char *name" 133.Fa "int access" 134.Fa "int32_t *arg" 135.Fa "int len" 136.Fa "const char *descr" 137.Fc 138.Ft struct sysctl_oid * 139.Fo SYSCTL_ADD_S64 140.Fa "struct sysctl_ctx_list *ctx" 141.Fa "struct sysctl_oid_list *parent" 142.Fa "int number" 143.Fa "const char *name" 144.Fa "int access" 145.Fa "int64_t *arg" 146.Fa "int len" 147.Fa "const char *descr" 148.Fc 149.Ft struct sysctl_oid * 150.Fo SYSCTL_ADD_STRING 151.Fa "struct sysctl_ctx_list *ctx" 152.Fa "struct sysctl_oid_list *parent" 153.Fa "int number" 154.Fa "const char *name" 155.Fa "int access" 156.Fa "char *arg" 157.Fa "int len" 158.Fa "const char *descr" 159.Fc 160.Ft struct sysctl_oid * 161.Fo SYSCTL_ADD_BIT32 162.Fa "struct sysctl_ctx_list *ctx" 163.Fa "struct sysctl_oid_list *parent" 164.Fa "int number" 165.Fa "const char *name" 166.Fa "int access" 167.Fa "uint32_t *arg" 168.Fa "uint32_t val" 169.Fa "int bit" 170.Fa "const char *descr" 171.Fc 172.Ft struct sysctl_oid * 173.Fo SYSCTL_ADD_BIT64 174.Fa "struct sysctl_ctx_list *ctx" 175.Fa "struct sysctl_oid_list *parent" 176.Fa "int number" 177.Fa "const char *name" 178.Fa "int access" 179.Fa "uint64_t *arg" 180.Fa "uint32_t val" 181.Fa "int bit" 182.Fa "const char *descr" 183.Fc 184.Ft struct sysctl_oid * 185.Fo SYSCTL_ADD_INT 186.Fa "struct sysctl_ctx_list *ctx" 187.Fa "struct sysctl_oid_list *parent" 188.Fa "int number" 189.Fa "const char *name" 190.Fa "int access" 191.Fa "int *arg" 192.Fa "int len" 193.Fa "const char *descr" 194.Fc 195.Ft struct sysctl_oid * 196.Fo SYSCTL_ADD_U8 197.Fa "struct sysctl_ctx_list *ctx" 198.Fa "struct sysctl_oid_list *parent" 199.Fa "int number" 200.Fa "const char *name" 201.Fa "int access" 202.Fa "uint8_t *arg" 203.Fa "int len" 204.Fa "const char *descr" 205.Fc 206.Ft struct sysctl_oid * 207.Fo SYSCTL_ADD_U16 208.Fa "struct sysctl_ctx_list *ctx" 209.Fa "struct sysctl_oid_list *parent" 210.Fa "int number" 211.Fa "const char *name" 212.Fa "int access" 213.Fa "uint16_t *arg" 214.Fa "int len" 215.Fa "const char *descr" 216.Fc 217.Ft struct sysctl_oid * 218.Fo SYSCTL_ADD_U32 219.Fa "struct sysctl_ctx_list *ctx" 220.Fa "struct sysctl_oid_list *parent" 221.Fa "int number" 222.Fa "const char *name" 223.Fa "int access" 224.Fa "uint32_t *arg" 225.Fa "const char *descr" 226.Fc 227.Ft struct sysctl_oid * 228.Fo SYSCTL_ADD_U64 229.Fa "struct sysctl_ctx_list *ctx" 230.Fa "struct sysctl_oid_list *parent" 231.Fa "int number" 232.Fa "const char *name" 233.Fa "int access" 234.Fa "uint64_t *arg" 235.Fa "int len" 236.Fa "const char *descr" 237.Fc 238.Ft struct sysctl_oid * 239.Fo SYSCTL_ADD_UINT 240.Fa "struct sysctl_ctx_list *ctx" 241.Fa "struct sysctl_oid_list *parent" 242.Fa "int number" 243.Fa "const char *name" 244.Fa "int access" 245.Fa "unsigned int *arg" 246.Fa "int val" 247.Fa "const char *descr" 248.Fc 249.Ft struct sysctl_oid * 250.Fo SYSCTL_ADD_LONG 251.Fa "struct sysctl_ctx_list *ctx" 252.Fa "struct sysctl_oid_list *parent" 253.Fa "int number" 254.Fa "const char *name" 255.Fa "int access" 256.Fa "long *arg" 257.Fa "const char *descr" 258.Fc 259.Ft struct sysctl_oid * 260.Fo SYSCTL_ADD_ULONG 261.Fa "struct sysctl_ctx_list *ctx" 262.Fa "struct sysctl_oid_list *parent" 263.Fa "int number" 264.Fa "const char *name" 265.Fa "int access" 266.Fa "unsigned long *arg" 267.Fa "const char *descr" 268.Fc 269.Ft struct sysctl_oid * 270.Fo SYSCTL_ADD_QUAD 271.Fa "struct sysctl_ctx_list *ctx" 272.Fa "struct sysctl_oid_list *parent" 273.Fa "int number" 274.Fa "const char *name" 275.Fa "int access" 276.Fa "quad_t *arg" 277.Fa "int val" 278.Fa "const char *descr" 279.Fc 280.Ft struct sysctl_oid * 281.Fo SYSCTL_ADD_UQUAD 282.Fa "struct sysctl_ctx_list *ctx" 283.Fa "struct sysctl_oid_list *parent" 284.Fa "int number" 285.Fa "const char *name" 286.Fa "int access" 287.Fa "u_quad_t *arg" 288.Fa "int val" 289.Fa "const char *descr" 290.Fc 291.Ft struct sysctl_oid * 292.Fo SYSCTL_ADD_OPAQUE 293.Fa "struct sysctl_ctx_list *ctx" 294.Fa "struct sysctl_oid_list *parent" 295.Fa "int number" 296.Fa "const char *name" 297.Fa "int access" 298.Fa "void *arg" 299.Fa "int len" 300.Fa "const char *format" 301.Fa "const char *descr" 302.Fc 303.Ft struct sysctl_oid * 304.Fo SYSCTL_ADD_STRUCT 305.Fa "struct sysctl_ctx_list *ctx" 306.Fa "struct sysctl_oid_list *parent" 307.Fa "int number" 308.Fa "const char *name" 309.Fa "int access" 310.Fa "void *arg" 311.Fa STRUCT_NAME 312.Fa "const char *descr" 313.Fc 314.Ft struct sysctl_oid * 315.Fo SYSCTL_ADD_PROC 316.Fa "struct sysctl_ctx_list *ctx" 317.Fa "struct sysctl_oid_list *parent" 318.Fa "int number" 319.Fa "const char *name" 320.Fa "int access" 321.Fa "void *arg1" 322.Fa "int arg2" 323.Fa "int (*handler) (SYSCTL_HANDLER_ARGS)" 324.Fa "const char *format" 325.Fa "const char *descr" 326.Fc 327.Sh DESCRIPTION 328These functions and macros provide an interface 329for creating and deleting sysctl oids at runtime 330(e.g.\& during lifetime of a module). 331The alternative method, 332based on linker sets (see 333.In sys/linker_set.h 334and 335.\" XXX Manual pages should avoid referencing source files 336.Pa /sys/kern/kern_sysctl.c 337for details), only allows creation and deletion 338on module load and unload respectively. 339.Pp 340Dynamic oids of type 341.Dv CTLTYPE_NODE 342are reusable 343so that several code sections can create and delete them, 344but in reality they are allocated and freed 345based on their reference count. 346As a consequence, 347it is possible for two or more code sections 348to create partially overlapping trees that they both can use. 349It is not possible to create overlapping leaves, 350nor to create different child types with the same name and parent. 351.Pp 352Newly created oids are connected to their parent nodes. 353In all these functions and macros 354(with the exception of 355.Fn sysctl_remove_oid ) , 356one of the required parameters is 357.Fa parent , 358which points to the head of the parent's list of children. 359.Pp 360Most top level categories are created statically. 361When connecting to existing static oids, 362this pointer can be obtained with the 363.Fn SYSCTL_STATIC_CHILDREN 364macro, where the 365.Fa OID_NAME 366argument is name of the parent oid of type 367.Dv CTLTYPE_NODE 368(i.e., the name displayed by 369.Xr sysctl 8 , 370preceded by underscore, and with all dots replaced with underscores). 371.Pp 372When connecting to an existing dynamic oid, this pointer 373can be obtained with the 374.Fn SYSCTL_CHILDREN 375macro, where the 376.Fa oidp 377argument points to the parent oid of type 378.Dv CTLTYPE_NODE . 379.Pp 380The 381.Fn sysctl_add_oid 382function creates raw oids of any type. 383If the oid is successfully created, 384the function returns a pointer to it; 385otherwise it returns 386.Dv NULL . 387Many of the arguments for 388.Fn sysctl_add_oid 389are common to the macros. 390The arguments are as follows: 391.Bl -tag -width handler 392.It Fa ctx 393A pointer to an optional sysctl context, or 394.Dv NULL . 395See 396.Xr sysctl_ctx_init 9 397for details. 398Programmers are strongly advised to use contexts 399to organize the dynamic oids which they create, 400unless special creation and deletion sequences are required. 401If 402.Fa ctx 403is not 404.Dv NULL , 405the newly created oid will be added to this context 406as its first entry. 407.It Fa parent 408A pointer to a 409.Li struct sysctl_oid_list , 410which is the head of the parent's list of children. 411.It Fa number 412The oid number that will be assigned to this oid. 413In almost all cases this should be set to 414.Dv OID_AUTO , 415which will result in the assignment of the next available oid number. 416.It Fa name 417The name of the oid. 418The newly created oid will contain a copy of the name. 419.It Fa kind 420The kind of oid, 421specified as a bit mask of the type and access values defined in the 422.In sys/sysctl.h 423header file. 424Oids created dynamically always have the 425.Dv CTLFLAG_DYN 426flag set. 427Access flags specify whether this oid is read-only or read-write, 428and whether it may be modified by all users 429or by the superuser only. 430.It Fa arg1 431A pointer to any data that the oid should reference, or 432.Dv NULL . 433.It Fa arg2 434The size of 435.Fa arg1 , 436or 0 if 437.Fa arg1 438is 439.Dv NULL . 440.It Fa handler 441A pointer to the function 442that is responsible for handling read and write requests 443to this oid. 444There are several standard handlers 445that support operations on nodes, 446integers, strings and opaque objects. 447It is possible also to define new handlers using the 448.Fn SYSCTL_ADD_PROC 449macro. 450.It Fa format 451A pointer to a string 452which specifies the format of the oid symbolically. 453This format is used as a hint by 454.Xr sysctl 8 455to apply proper data formatting for display purposes. 456Currently used format names are: 457.Dq N 458for node, 459.Dq A 460for 461.Li "char *" , 462.Dq I 463for 464.Li "int" , 465.Dq IU 466for 467.Li "unsigned int" , 468.Dq IK 469for temperature in tenths of kelvins, 470.Dq L 471for 472.Li "long" , 473.Dq LU 474for 475.Li "unsigned long" 476and 477.Dq S,TYPE 478for 479.Li "struct TYPE" 480structures. 481.It Fa descr 482A pointer to a textual description of the oid. 483.El 484.Pp 485The 486.Fn sysctl_remove_oid 487function removes a dynamically created oid from the tree, 488optionally freeing its resources. 489It takes the following arguments: 490.Bl -tag -width recurse 491.It Fa oidp 492A pointer to the dynamic oid to be removed. 493If the oid is not dynamic, or the pointer is 494.Dv NULL , 495the function returns 496.Er EINVAL . 497.It Fa del 498If non-zero, 499.Fn sysctl_remove_oid 500will try to free the oid's resources 501when the reference count of the oid becomes zero. 502However, if 503.Fa del 504is set to 0, 505the routine will only deregister the oid from the tree, 506without freeing its resources. 507This behaviour is useful when the caller expects to rollback 508(possibly partially failed) 509deletion of many oids later. 510.It Fa recurse 511If non-zero, attempt to remove the node and all its children. 512If 513.Fa recurse 514is set to 0, 515any attempt to remove a node that contains any children 516will result in a 517.Er ENOTEMPTY 518error. 519.Em WARNING : "use recursive deletion with extreme caution" ! 520Normally it should not be needed if contexts are used. 521Contexts take care of tracking inter-dependencies 522between users of the tree. 523However, in some extreme cases it might be necessary 524to remove part of the subtree no matter how it was created, 525in order to free some other resources. 526Be aware, though, that this may result in a system 527.Xr panic 9 528if other code sections continue to use removed subtrees. 529.El 530.Pp 531.\" XXX sheldonh finished up to here 532Again, in most cases the programmer should use contexts, 533as described in 534.Xr sysctl_ctx_init 9 , 535to keep track of created oids, 536and to delete them later in orderly fashion. 537.Pp 538There is a set of macros defined 539that helps to create oids of given type. 540.Pp 541They are as follows: 542.Bl -tag -width SYSCTL_ADD_STRINGXX 543.It Fn SYSCTL_ADD_OID 544creates a raw oid. 545This macro is functionally equivalent to the 546.Fn sysctl_add_oid 547function. 548.It Fn SYSCTL_ADD_NODE 549creates an oid of type 550.Dv CTLTYPE_NODE , 551to which child oids may be added. 552.It Fn SYSCTL_ADD_S8 553creates an oid that handles an 554.Li int8_t 555variable. 556.It Fn SYSCTL_ADD_S16 557creates an oid that handles an 558.Li int16_t 559variable. 560.It Fn SYSCTL_ADD_S32 561creates an oid that handles an 562.Li int16_t 563variable. 564.It Fn SYSCTL_ADD_S64 565creates an oid that handles an 566.Li int64_t 567variable. 568.It Fn SYSCTL_ADD_STRING 569creates an oid that handles a zero-terminated character string. 570.It Fn SYSCTL_ADD_BIT32 571creates an oid that can flip individual bits of an 572.Li uint32_t 573variable. 574.It Fn SYSCTL_ADD_BIT64 575creates an oid that can flip individual bits of an 576.Li uint64_t 577variable. 578.It Fn SYSCTL_ADD_INT 579creates an oid that handles an 580.Li int 581variable. 582.It Fn SYSCTL_ADD_U8 583creates an oid that handles a 584.Li uint8_t 585variable. 586.It Fn SYSCTL_ADD_U16 587creates an oid that handles a 588.Li uint16_t 589variable. 590.It Fn SYSCTL_ADD_U32 591creates an oid that handles a 592.Li uint32_t 593variable. 594.It Fn SYSCTL_ADD_U64 595creates an oid that handles a 596.Li uint64_t 597variable. 598.It Fn SYSCTL_ADD_UINT 599creates an oid that handles an 600.Li unsigned int 601variable. 602.It Fn SYSCTL_ADD_LONG 603creates an oid that handles a 604.Li long 605variable. 606.It Fn SYSCTL_ADD_ULONG 607creates an oid that handles an 608.Li unsigned long 609variable. 610.It Fn SYSCTL_ADD_QUAD 611creates an oid that handles a 64-bit 612.Li int 613variable. 614.It Fn SYSCTL_ADD_UQUAD 615creates an oid that handles a 64-bit 616.Li unsigned int 617variable. 618.It Fn SYSCTL_ADD_OPAQUE 619creates an oid that handles any chunk of opaque data 620of the size specified by the 621.Fa len 622argument, 623which is a pointer to a 624.Li "size_t *" . 625.It Fn SYSCTL_ADD_STRUCT 626creates an oid that handles a 627.Li "struct TYPE" 628structure. 629The 630.Fa format 631parameter will be set to 632.Dq S,TYPE 633to provide proper hints to the 634.Xr sysctl 8 635utility. 636.It Fn SYSCTL_ADD_PROC 637creates an oid with the specified 638.Fa handler 639function. 640The handler is responsible for handling read and write requests 641to the oid. 642This oid type is especially useful 643if the kernel data is not easily accessible, 644or needs to be processed before exporting. 645.El 646.Sh EXAMPLES 647The following is an example of 648how to create a new top-level category 649and how to hook up another subtree to an existing static node. 650This example does not use contexts, 651which results in tedious management of all intermediate oids, 652as they need to be freed later on: 653.Bd -literal 654#include <sys/sysctl.h> 655 ... 656/* Need to preserve pointers to newly created subtrees, to be able 657 * to free them later. 658 */ 659struct sysctl_oid *root1, *root2, *oidp; 660int a_int; 661char *string = "dynamic sysctl"; 662 ... 663 664root1 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(/* tree top */), 665 OID_AUTO, "newtree", CTLFLAG_RW, 0, "new top level tree"); 666oidp = SYSCTL_ADD_INT( NULL, SYSCTL_CHILDREN(root1), 667 OID_AUTO, "newint", CTLFLAG_RW, &a_int, 0, "new int leaf"); 668 ... 669root2 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(_debug), 670 OID_AUTO, "newtree", CTLFLAG_RW, 0, "new tree under debug"); 671oidp = SYSCTL_ADD_STRING( NULL, SYSCTL_CHILDREN(root2), 672 OID_AUTO, "newstring", CTLFLAG_RD, string, 0, "new string leaf"); 673.Ed 674.Pp 675This example creates the following subtrees: 676.Bd -literal -offset indent 677debug.newtree.newstring 678newtree.newint 679.Ed 680.Pp 681.Em "Care should be taken to free all oids once they are no longer needed!" 682.Sh SEE ALSO 683.Xr sysctl 8 , 684.Xr sysctl 9 , 685.Xr sysctl_ctx_free 9 , 686.Xr sysctl_ctx_init 9 687.Sh HISTORY 688These functions first appeared in 689.Fx 4.2 . 690.Sh AUTHORS 691.An Andrzej Bialecki Aq Mt abial@FreeBSD.org 692.Sh BUGS 693Sharing nodes between many code sections 694causes interdependencies that sometimes may lock the resources. 695For example, 696if module A hooks up a subtree to an oid created by module B, 697module B will be unable to delete that oid. 698These issues are handled properly by sysctl contexts. 699.Pp 700Many operations on the tree involve traversing linked lists. 701For this reason, oid creation and removal is relatively costly. 702