The nsysctl utility can get or set the state of the FreeBSD kernel at runtime. The system exposes its available parameters as objects of a “Management Information Base” (MIB). nsysctl can explore this MIB, print the properties of an object, get or set its value and display the output in both human-readable and machine-readable formats.
An object is identified by an Object Identifier (OID), which is a sequence of numbers. You can replace a number with a string to obtain an object name; for example, [1.1] becomes “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
Only “nsysctl” to 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> to display name: value:
user@bsd:~/% nsysctl kern.ostype kern.ostype: FreeBSD
step 5
“-e” to use = as a separator:
user@bsd:~/% nsysctl -e kern.ostype kern.ostype=FreeBSD
“-s <sep>” to use <sep> as a separator:
user@bsd:~/% nsysctl -s ' - ' kern.ostype kern.ostype - FreeBSD
Step 6
“-N” to hide the value:
user@bsd:~/% nsysctl -N kern.ostype kern.ostype
Step 7
“-n” to hide the 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 examples include: 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, which are 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 hexadecimal 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” to 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 examples include: 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 to disable a flag: Disable sysctl ANYBODY flag.
Step 17
“-H” for Handler, showing Defined if the object has a value,
and Undefined otherwise.
(Properly, the handler is the kernel function associated with the object,
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.2025”
Step 18
“-D” ie 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.
See 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>” to 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 also show 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 also handle a nvlist.
This feature allows the implementation of 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” to print 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” to 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”: to show objects with the SKIP flag with -a.
Step 27
“-V”: by default, -a hides an object without a value.
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 values (not defined in opaque.c) in hexadecimal 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 human-printable opaque values because their Format is handled:
- 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 hexadecimal 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” attempts 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” uses a buffer of bufsize bytes for a value.
- “-f filename” read object name/value from filename (example file.conf).
- “-i” ignore unknown objects.
- “-q avoids showing some warnings.
- “-T” shows only variables that are settable via loader.
- “-W” displays only writable variables that are not statistical.
- “-X” equivalent to -xa.
Step 32
“nsysctl name=value” sets 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 toggles a numeric or boolean value.
If the value is 0, it becomes 1; if it is not 0, it becomes 0.
If the value is an array, only the first index is affected.
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 this behavior 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. However, it provides options to explicitly show both internal and SKIP nodes.
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 for v, [-N | -Vh [b | o | x]]). It is important for the following steps.
Furthermore nsysctl uses the sysctlinfo interface, so it can handle an object up to 23/24 levels or an object with an empty level name (example “security.jail.param.allow.mount.”). Finally, the efficiency of retrieving all properties for 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 find useful properties to handle objects, printed 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.