The nsysctl utility can get or set the state of the FreeBSD kernel at runtime. The system exposes the available parameters as objects of a “Management Information Base” (MIB), nsysctl can explore the MIB, print the properties of an object, get or set its value and show the output in human and machine readable formats.
An object is identified by an Object Identifier (OID), a series of numbers, it is possible to replace a number with a string to obtain an object name, example [1.1] -> “kern.ostype”.
Step 1
To install the port
sysutils/nsysctl:
# cd /usr/ports/sysutils/nsysctl/ && make install clean
To add the package:
# pkg install nsysctl
Step 2
“nsysctl” show usage
user@bsd:~/% nsysctl
usage: nsysctl [--libxo options [-r tagroot]] [-DdeFGgHIilnOpqTtvW]
[-N | -h [b | o | x]] [-B bufsize] [-f filename] [-s sep]
name[=value[,value]] ...
nsysctl [--libxo options [-r tagroot]] [-DdeFGgHIklnOpqSTtvW] [-N | -Vh [b | o | x]] [-B bufsize] [-s sep] -a
step 3
“-v” for version
user@bsd:~/% nsysctl -v nsysctl 2.1
This tutorial is for nsysctl >= 2.0 (old version: 2019-02-19-nsysctl-tutorial.html).
step 4
“nsysctl” with a name
user@bsd:~/% nsysctl kern.ostype kern.ostype: FreeBSD
The output is name: value
step 5
“-e” use = separator
user@bsd:~/% nsysctl -e kern.ostype kern.ostype=FreeBSD
“-s <sep>” use <sep> separator
user@bsd:~/% nsysctl -s ' - ' kern.ostype kern.ostype - FreeBSD
Step 6
“-N” hide value
user@bsd:~/% nsysctl -N kern.ostype kern.ostype
Step 7
“-n” hide name
user@bsd:~/% nsysctl -n kern.ostype FreeBSD
Step 8
“-d” for description
user@bsd:~/% nsysctl -d kern.ostype
kern.ostype: Operating system type: FreeBSD
user@bsd:~/% nsysctl -d kern.osrevision kern.osrevision: Operating system revision: 199506
Step 9
“-t” for type, defined in sys/sysctl.h and documented in
sysctl(9) “CONTROL FLAGS” Section, some
example: node, integer, opaque, string, and so on
user@bsd:~/% nsysctl -dt kern.ostype
kern.ostype: Operating system type: string: FreeBSD
user@bsd:~/% nsysctl -dt kern.osrevision kern.osrevision: Operating system revision: integer: 199506
Step 10
“-F” for the format, for example an integer could represent a simple
integer, a deciKelvin, a milliKelvin, and so on; the format is important also
for opaque values described later
user@bsd:~/% nsysctl -dtF kern.osrevision
kern.osrevision: Operating system revision: integer: I: 199506
user@bsd:~/% nsysctl -dtF dev.cpu.0.temperature dev.cpu.0.temperature: integer: IK: 27.950006C
They are documented in sysctl(9) -> “DESCRIPTION OF ARGUMENTS” Section -> format.
Step 11
“-x for (numeric) value in hex format
user@bsd:~/% nsysctl -dtFx kern.ostype
kern.ostype: Operating system type: string: A: FreeBSD
user@bsd:~/% nsysctl -dtFx kern.osrevision kern.osrevision: Operating system revision: integer: I: 0x00030b52
Step 12
“-b” for value in binary format without newline
user@bsd:~/% nsysctl -dtFb kern.ostype
kern.ostype: Operating system type: string: A: FreeBSDuser@bsd:~/%
user@bsd:~/%
user@bsd:~/% nsysctl -dtFb kern.osrevision
kern.osrevision: Operating system revision: integer: I: R
?user@bsd:~/% user@bsd:~/%
Step 13
“-p” show “[PROPERTY-NAME]:”
user@bsd:~/% nsysctl -pdtF -s ', ' kern.ostype
[NAME]: kern.ostype, [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT]: A, [VALUE]: FreeBSD
Step 14
“-l” for aggregation label, useful for the
prometheus_sysctl_exporter
utility
user@bsd:~/% nsysctl -pldtF -s ', ' kern.features.scbus
[NAME]: kern.features.scbus, [LABEL]: feature, [DESCRIPTION]: SCSI devices support, [TYPE]: integer, [FORMAT]: I, [VALUE]: 1
Step 15
“-O” for OID (the sysctl system call
finds an object matching its OID)
user@bsd:~/% nsysctl -pOldtF -s ', ' kern.ostype
[OID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT]: A, [VALUE]: FreeBSD
Step 16
“-g” for flags (number) and “-G” for true flags list, they are defined
in sys/sysctl.h and documented in
sysctl(9) “CONTROL FLAGS” Section, some
example: RD, WR, ANYBODY, TUN, SKIP, and so on
user@bsd:~/% nsysctl -pyldtFgG -s ', ' kern.ostype
[OID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system
type, [TYPE]: string, [FORMAT]: A, [FLAGS-RAW]: 2147778560, [FLAGS]: RD MPSAFE CAPRD, [VALUE]: FreeBSD
Example: Disable sysctl ANYBODY flag.
Step 17
“-H” for Handler, Defined if the object has a value, Undefined otherwise
(properly the handler is the object kernel function, mainly, used to read or
write a value)
user@bsd:~/% nsysctl -pyldtFgGH -s ', ' kern.ostype
[OID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system
type, [TYPE]: string, [FORMAT]: A, [FLAGS-RAW]: 2147778560, [FLAGS]: RD MPSAFE CAPRD, [HANDLER]: Defined, [VALUE]: FreeBSD
Furthermore, the OID of a node object with a Defined handler can be extended, example [1.14.1.<pid>] (“kern.proc.pid”) in the sysctl(3) manual
user@bsd:~/% nsysctl -tH kern.proc.pid nkern.proc.pid: node: Defined
sysctlbyname-improved can handle an extended name like “kern.proc.pid.2021”
Step 18
“-D” Equivalent to: “-d” “-F” “-G” “-H” “-l” “-O”
“-t”
user@bsd:~/% nsysctl -pD -s ', ' kern.ostype
[OID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system
type, [TYPE]: string, [FORMAT]: A, [FLAGS]: RD MPSAFE CAPRD, [HANDLER]: Defined, [VALUE]: FreeBSD
Step 19
“--libxo” for emitting: text, XML, JSON, or HTML output,
xo_parse_args(3),
text
user@bsd:~/% nsysctl --libxo=text -pD kern.ostype
[OID]: 1.1: [NAME]: kern.ostype: [LABEL]: : [DESCRIPTION]: Operating system
type: [TYPE]: string: [FORMAT]: A: [FLAGS]: RD MPSAFE CAPRD: [HANDLER]: Defined: [VALUE]: FreeBSD
XML
user@bsd:~/% nsysctl --libxo=xml,pretty -D kern.ostype
<object>
<OID>1.1</OID>
<name>kern.ostype</name>
<label></label>
<description>Operating system type</description>
<type>string</type>
<format>A</format>
<flags>
<flag>RD</flag>
<flag>MPSAFE</flag>
<flag>CAPRD</flag>
</flags>
<handler>Defined</handler>
<value>FreeBSD</value> </object>
JSON
user@bsd:~/% nsysctl --libxo=json,pretty -dtF kern.ostype
{
"object": [
{
"name": "kern.ostype",
"description": "Operating system type",
"type": "string",
"format": "A",
"value": "FreeBSD"
}
] }
HTML (the sysctl-mib-html project provides an ad-hoc solution for html)
user@bsd:~/% nsysctl --libxo=html,pretty -dtF kern.ostype
<div class="line">
<div class="data" data-tag="name">kern.ostype</div>
<div class="label">: </div>
<div class="data" data-tag="description">Operating system type</div>
<div class="label">: </div>
<div class="data" data-tag="type">string</div>
<div class="label">: </div>
<div class="data" data-tag="format">A</div>
<div class="label">: </div>
<div class="data" data-tag="value">FreeBSD</div>
<div class="label"> </div>
Step 20
“-r <tag-root>” specify a tag-root with libxo
user@bsd:~/% nsysctl --libxo=xml,pretty -r "MIB" kern.ostype
<MIB>
<object>
<name>kern.ostype</name>
<value>FreeBSD</value>
</object> </MIB>
Step 21
“nsysctl name” shows only the descendant leaves of name by default
user@bsd:~/% nsysctl -N compat
compat.ia32.maxvmem
compat.ia32.maxssiz
compat.ia32.maxdsiz
user@bsd:~/%
user@bsd:~/% nsysctl --libxo=xml,pretty -N compat
<object>
<name>compat.ia32.maxvmem</name>
</object>
<object>
<name>compat.ia32.maxssiz</name>
</object>
<object>
<name>compat.ia32.maxdsiz</name> </object>
“-I” to show also internal nodes, libxo adds <children> tag
user@bsd:~/% nsysctl -NI compat
compat
compat.ia32
compat.ia32.maxvmem
compat.ia32.maxssiz
compat.ia32.maxdsiz
user@bsd:~/% nsysctl --libxo=xml,pretty -NI compat
<object>
<name>compat</name>
<children>
<object>
<name>compat.ia32</name>
<children>
<object>
<name>compat.ia32.maxvmem</name>
</object>
<object>
<name>compat.ia32.maxssiz</name>
</object>
<object>
<name>compat.ia32.maxdsiz</name>
</object>
</children>
</object>
</children> </object>
Step 22
The string value of some object is parsed to show structured output via libxo
user@bsd:~/% nsysctl --libxo=xml,pretty vm.phys_free
List of parsed objects:
- debug.witness.fullgraph
- kern.conftxt
- vm.phys_free
Step 23
nsysctl can handle also a nvlist,
libnv(9). This feature allows to implement a
non-primitive object value without hardcoding its C structure, see opaque
later;
example to build a nvlist object:
sysctl-libnv.
% nsysctl -dF nv.campania
nv.campania: Administrative region of Italy: NV:
Capital=Napoli
Population=5869029
Cities=Avellino Benevento Caserta Napoli Salerno
% nsysctl --libxo=xml,pretty -dtF nv.campania
<object>
<name>nv.campania</name>
<description>Administrative region of Italy</description>
<type>opaque</type>
<format>NV</format>
<value>
<nvlist>
<nv>
<name>Capital</name>
<value>Napoli</value>
<nvtype>NV_TYPE_STRING</nvtype>
</nv>
<nv>
<name>Population</name>
<value>5869029</value>
<nvtype>NV_TYPE_NUMBER</nvtype>
</nv>
<nv>
<name>Cities</name>
<value>Avellino</value>
<value>Benevento</value>
<value>Caserta</value>
<value>Napoli</value>
<value>Salerno</value>
<nvtype>NV_TYPE_STRING_ARRAY</nvtype>
</nv>
</nvlist>
</value> </object>
Step 24
“-a” All objects
user@bsd:~/% nsysctl -a
kern.ostype: FreeBSD
kern.osrelease: 13.0-CURRENT
kern.osrevision: 199506 ...
FreeBSD provides thousands of objects.
Step 25
“-S” show “sysctl.*” subtree with -a, these objects are useful to write
a software to explore the MIB
user@bsd:~/% nsysctl -SOdNa | less
0.1: sysctl.name:
0.2: sysctl.next:
0.3: sysctl.name2oid:
0.4: sysctl.oidfmt:
0.5: sysctl.oiddescr:
0.6: sysctl.oidlabel:
0.7: sysctl.nextnoskip:
0.10: sysctl.objidextended_byname: Object ID by its name eventually extended
0.11: sysctl.objname: Object name by its OID
0.12: sysctl.objid_byname: Object ID by its name
0.13: sysctl.objfakename: Object (possible fake) name
0.14: sysctl.objfakeid_byname: Object (possible fake) ID by its name
0.15: sysctl.objdesc: Object description string
0.16: sysctl.objdesc_byname: Object description by its name
0.17: sysctl.objlabel: Object label
0.18: sysctl.objlabel_byname: Object label by its name
0.19: sysctl.objkind: Object kind (flags and type)
0.20: sysctl.objkind_byname: Object kind by its name
0.21: sysctl.objfmt: Object format string
0.22: sysctl.objfmt_byname: object format string by its name
0.23: sysctl.nextobjnode: Next object (internal node or leaf)
0.24: sysctl.nextobjnode_byname: Next object name (internal node or leaf)
0.25: sysctl.nextobjleaf: Next object (only leaf)
0.26: sysctl.nextobjleaf_byname: Next object name (only leaf)
0.27: sysctl.serobj: Serialize object properties
0.28: sysctl.serobj_byname: Serialize object by its name
0.29: sysctl.serobjnextnode: Serialize object with next-node-OID
0.30: sysctl.serobjnextnode_byname: Serialize object by its name with next-node-
name
0.31: sysctl.serobjnextleaf: Serialize object with next-leaf-OID
0.32: sysctl.serobjnextleaf_byname: Serialize object by its name with next-leaf-
name
0.33: sysctl.objhashandler: Object has a handler
0.34: sysctl.objhashandler_byname: Object has a handler by its name 0.35: sysctl.fakenextobjleafnoskip: Next object (only leaf) avoiding SKIP flag
Step 26
“-k”: show objects with the SKIP flag with -a.
Step 27
“-V”: -a hides an object without a value by default, this option disable
this feature.
user@bsd:~/% nsysctl -aV
Tip: -a hides nodes without value so -I is useless without -V
user@bsd:~/% nsysctl -aIV
Step 28
“-o” to show opaque value (not defined in opaque.c) in hex format up to
16 bytes
user@bsd:~/% nsysctl -ato | grep opaque
kern.clockrate: opaque: { hz = 1000, tick = 1000, profhz = 8128, stathz = 127 }
kern.proc.all: opaque: Format:S,proc Length:490688 Dump:0x4004000000000000000000
0000000000...
kern.file: opaque: Format:S,xfile Length:197632 Dump:0x80000000000000007b0a0000e
9030000...
kern.boottime: opaque: { sec = 1614296786, usec = 464261 } Fri Feb 26 00:46:26
2021
kern.ipc.shmsegs: opaque: Format: Length:19968 Dump:0xe9030000e9030000e9030000e9
030000... ...
without “-o” values not defined in opaque.c are hidden by -a
user@bsd:~/% nsysctl -at | grep opaque
kern.clockrate: opaque: { hz = 1000, tick = 1000, profhz = 8128, stathz = 127 }
kern.boottime: opaque: { sec = 1614296786, usec = 464261 } Fri Feb 26 00:46:26
2021 ...
List of defined opaque, properly Formats for type opaque:
- S,clockinfo
- S,bios_smap_xattr
- S,efi_map_header
- S,input_id
- S,loadavg
- S,pagesizes
- S,timeval
- S,vmtotal
- NV (libnv)
Step 29
-x is equivalent to -o but print all the bytes, moreover OID and flags
are shown in hex format
user@bsd:~/% nsysctl -ONg compat.ia32.maxvmem
2147482900.2147481617.2147481614: compat.ia32.maxvmem: 3222016000
user@bsd:~/% nsysctl -ONgx compat.ia32.maxvmem 7ffffd14.7ffff811.7ffff80e: compat.ia32.maxvmem: c00c1000
Step 30
“-h” try to show values in a human-friendly format, it depends on the ‘h’
field modifier of libxo, please refer to
the-humanize-modifier-h
for a more thorough description.
Step 31
- “-A” equivalent to -oa.
- “-B bufsize” use a buffer of bufsize bytes for a value.
- “-f filename” read object name/value from filename (example file.conf).
- “-i” ignore unknown objects.
- “-q avoid to show some warning.
- “-T” show only variables that are settable via loader.
- “-W” display only writable variables that are not statistical.
- “-X” equivalent to -xa.
Step 32
“nsysctl name=value” set a new value
user@bsd:~/% su
Password:
root@bsd:/home/user/# nsysctl kern.maxprocperuid=1000
kern.maxprocperuid: 8211 -> 1000
root@bsd:/home/user/# nsysctl --libxo=xml,pretty kern.maxprocperuid=8211
<object>
<name>kern.maxprocperuid</name>
<value>1000</value>
<newvalue>8211</newvalue>
</object>
root@bsd:/home/user/# exit
exit user@bsd:~/%
To set a numeric array: “nsysctl name=value,value,value,value”.
Step 33
-z Toggle numeric or boolean value, if the value is 0 becomes 1, if it is
not 0 becomes 0, if the value is an array only the first index takes effect
user@bsd:~/% nsysctl -z hw.snd.default_unit hw.snd.default_unit: 0 -> 1
Step 34
nsysctl can get a list of objects
root@bsd:/home/user/# nsysctl kern.ostype vm.loadavg kern.maxprocperuid=9000
kern.ostype: FreeBSD
vm.loadavg: { 0.15 0.13 0.18 }
kern.maxprocperuid: 8211 -> 9000 root@fbsd:/home/user/#
Step 35
Comparison sysctl - nsysctl
sysctl(8), prints internal and SKIP nodes with -aN, -ad and -at, only leaves avoiding SKIP nodes otherwise, to reproduce with nsysctl:
sysctl | nsysctl |
---|---|
% sysctl -aN | % nsysctl -aNIk |
% sysctl -ad | % nsysctl -adIk |
% sysctl -at | % nsysctl -atIk |
Internal nodes have not a value (Undefined Handler), so nsysctl hides them by default, it gives the possibility to choose explicitly to show them and SKIP nodes via options.
Extra nsysctl options: --libxo, -D, -F, -G, -g, -H, -I, -k, -l, -O, -r, -p, -S, -s, -V, -v and -z.
The options are not mutually exclusive (except v, [-N | -Vh [b | o | x]]), this feature is important for the next steps.
Furthermore nsysctl uses the sysctlinfo interface, so it can handle an object with 23/24 levels or an object with an empty level name (example “security.jail.param.allow.mount.”), finally the efficiency to get all the properties about an object is improved.
user@bsd:~/% nsysctl x1
x1.x2.x3.x4.x5.x6.x7.x8.x9.x10.x11.x12.x13.x14.x15.x16.x17.x18.x19.x20.x21.x22.
x23.x24: 24
user@bsd:~/% nsysctl security.jail.param.allow.mount. security.jail.param.allow.mount.: 0
Step 36
To know useful properties to handle objects in “tabular” form
user@bsd:~/% nsysctl -pdtFGH -s " - " hw.snd
Screenshot to configure Elantech Touchpad
user@bsd:~/% nsysctl -adtFG -s ", " | grep elantech
Step 37/
To debug, printing everything, avoiding to recompile the kernel with
SYSCTL_DEBUG
user@bsd:~/% nsysctl -pDIkVgSa -s " - " user@bsd:~/% nsysctl --libxo=xml,pretty -r "MIB" -DIkVgSa
Step 38
Frequently Asked Questions:
- Manual Page?
- nsysctl(8).
- Source code?
- https://gitlab.com/alfix/nsysctl.
- How can I customize nsysctl?
- nsysctl.c for getting/setting basic types, opaque.c for opaque values and special_values.c for parsed strings.
- Can I write my sysctl-like utility?
- Yes, you can, https://gitlab.com/alfix/sysctlmibinfo2 is an easy API to explore the sysctl MIB.
- Graphical User Interface?
- https://gitlab.com/alfix/sysctlview.