nsysctl tutorial

Posted on 2019-02-19 - Updated on 2021-01-25

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 sysctl MIB, print the properties of an object, get or set its value and show the output via libxo in human and machine readable formats. This post is a step-by-step tutorial.

This tutorial is for nsysctl <= 1.2.1, for the new version Tutorial nsysctl version 2.


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” to show usage

user@bsd:~/% nsysctl
usage: nsysctl [--libxo options [-r tagroot]] [-DdFGgIilmNpqTtWy]
               [-V | -v [h [b | o | x]]] [-B bufsize] [-e sep] [-f filename]
               name[=value[,value]] ...
       nsysctl [--libxo options [-r tagroot]] [-DdFGgIlmNpqTtWy]
               [-V | -v [h [b | o | x]]] [-B bufsize] [-e sep] -A | -a | -X

step 3
nsysctl” with a name

user@bsd:~/% nsysctl kern.ostype
user@bsd:~/%

Nothing: it’s a feature, the output has to be explicitly indicated by the options.


Step 4
-N” for name and “-v” for value; note, also for the next steps, the options are not mutually exclusive except [v|V] and [b|o|x].

user@bsd:~/% nsysctl -Nv kern.ostype
kern.ostype: FreeBSD
user@bsd:~/% nsysctl -Nv kern.osrevision
kern.osrevision: 199506

Step 5
-d” for description

user@bsd:~/% nsysctl -Ndv kern.ostype
kern.ostype: Operating system type: FreeBSD
user@bsd:~/% nsysctl -Ndv kern.osrevision
kern.osrevision: Operating system revision: 199506

Step 6
-t” for type and “-F” for ‘format string’

user@bsd:~/% nsysctl -NdtFv kern.ostype
kern.ostype: Operating system type: string: A: FreeBSD
user@bsd:~/% nsysctl -NdtFv kern.osrevision
kern.osrevision: Operating system revision: integer: I: 199506

Step 7
-x for (numeric) value in hex format

user@bsd:~/% nsysctl -NdtFvx kern.ostype
kern.ostype: Operating system type: string: A: FreeBSD
user@bsd:~/% nsysctl -NdtFvx kern.osrevision
kern.osrevision: Operating system revision: integer: I: 0x00030b52

Step 8
-b” for value in binary format without newline

user@bsd:~/% nsysctl -NdtFvb kern.ostype
kern.ostype: Operating system type: string: A: FreeBSDuser@bsd:~/%
user@bsd:~/%
user@bsd:~/% nsysctl -NdtFvb kern.osrevision
kern.osrevision: Operating system revision: integer: I: R
                                                         ?user@bsd:~/%
user@bsd:~/%

Step 9
-p” to show “[property-name]:” and “-e sep” to specify a separator

user@bsd:~/% nsysctl -pNdtFv -e ', ' kern.ostype
[NAME]: kern.ostype, [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT-STRING]: A, [VALUE]: FreeBSD

Step 10
-l” for aggregation label

user@bsd:~/% nsysctl -pNldtFv -e ', ' kern.features.scbus
[NAME]: kern.features.scbus, [LABEL]: feature, [DESCRIPTION]: SCSI devices support, [TYPE]: integer, [FORMAT-STRING]: I, [VALUE]: 1

Step 11
-y” for ID

user@bsd:~/% nsysctl -pyNldtFv -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT-STRING]: A, [VALUE]: FreeBSD

Step 12
-g” for flags and “-G” for the list of true flags

user@bsd:~/% nsysctl -pyNldtFgGv -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT-STRING]: A, [FLAGS]: 2147778560, [TRUE-FLAGS]: RD MPSAFE CAPRD, [VALUE]: FreeBSD

Step 13
-D” Equivalent to: “-d” “-F” “-G” “-g” “-l” “-N” “-t” “-v” “-y

user@bsd:~/% nsysctl -Dp -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT-STRING]: A, [FLAGS]: 2147778560, [TRUE-FLAGS]: RD MPSAFE CAPRD, [VALUE]: FreeBSD

Step 14
--libxo” for emitting text, XML, JSON, or HTML output (xo_parse_args(3))

text

user@bsd:~/% nsysctl --libxo=text -pD kern.ostype
[ID]: 1.1: [NAME]: kern.ostype: [LABEL]: : [DESCRIPTION]: Operating system type: [TYPE]: string: [FORMAT-STRING]: A: [FLAGS]: 2147778560: [TRUE-FLAGS]: RD MPSAFE CAPRD: [VALUE]: FreeBSD

XML

user@bsd:~/% nsysctl --libxo=xml,pretty -D kern.ostype
<object>
  <id>
    <level1>1</level1>
    <level2>1</level2>
  </id>
  <name>kern.ostype</name>
  <label></label>
  <description>Operating system type</description>
  <type>string</type>
  <format>A</format>
  <flags>2147778560</flags>
  <true-flags>
    <flag>RD</flag>
    <flag>MPSAFE</flag>
    <flag>CAPRD</flag>
  </true-flags>
  <value>FreeBSD</value>
</object>

JSON

user@bsd:~/% nsysctl --libxo=json,pretty -pNdtFv kern.ostype
{
  "object": [
    {
      "name": "kern.ostype",
      "description": "Operating system type",
      "type": "string",
      "format": "A",
      "value": "FreeBSD"
    }
  ]}

HTML

user@bsd:~/% nsysctl --libxo=html,pretty -pNdtFv kern.ostype
<div class="line">
  <div class="label">[NAME]: </div>
  <div class="data" data-tag="name">kern.ostype</div>
  <div class="label">: </div>
  <div class="label">[DESCRIPTION]: </div>
  <div class="data" data-tag="description">Operating system type</div>
  <div class="label">: </div>
  <div class="label">[TYPE]: </div>
  <div class="data" data-tag="type">string</div>
  <div class="label">: </div>
  <div class="label">[FORMAT-STRING]: </div>
  <div class="data" data-tag="format">A</div>
  <div class="label">: </div>
  <div class="label">[VALUE]: </div>
  <div class="data" data-tag="value">FreeBSD</div>
  <div class="label">
</div>

Step 15
-r” to specify a tag-root with libxo

user@bsd:~/% nsysctl --libxo=xml,pretty -r ROOT -Nv kern.ostype
<ROOT>
  <object>
    <name>kern.ostype</name>
    <value>FreeBSD</value>
  </object>
</ROOT>

Step 16
nsysctl name” shows only the descending-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 internal nodes, too

user@bsd:~/% nsysctl -NI compat
compat
compat.ia32
compat.ia32.maxvmem
compat.ia32.maxssiz
compat.ia32.maxdsiz

“--libxo” adds “children” tag

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 17
-a” to show all MIB objects

user@bsd:~/% nsysctl -aNv
kern.ostype: FreeBSD
kern.osrelease: 13.0-CURRENT
kern.osrevision: 199506
...... extras .....
compat.ia32.maxvmem: 0
compat.ia32.maxssiz: 67108864
compat.ia32.maxdsiz: 536870912

I have over 3000 objects, with “-a” you can use many of the previous options, see Step “2”.


Step 18
-m” to show the “sysctl.*” subtree (OIDs 0.*)

user@bsd:~/% nsysctl -IyNdm sysctl
0: sysctl: Sysctl internal magic
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.8: sysctl.entryfakename: fake name of an object
0.9: sysctl.entryname: name of an object
0.10: sysctl.entrydesc: description of an object
0.11: sysctl.entrylabel: label of an object
0.12: sysctl.entrykind: kind (flags and type) of an object
0.13: sysctl.entryfmt: format string of an object
0.14: sysctl.entrynextnode: next mib object (internal node or leaf)
0.15: sysctl.entrynextleaf: next mib object (only leaf)
0.16: sysctl.entryallinfo: all info of an object
0.17: sysctl.entryallinfo_withnextnode: all info of an object with the next node
0.18: sysctl.entryallinfo_withnextleaf: all info of an object with next leaf
0.19: sysctl.entryidbyname: id of an object by its name
0.20: sysctl.entryfakeidbyname: fake id of an object by its name
0.21: sysctl.entrydescbyname: description of an object by its name
0.22: sysctl.entrylabelbyname: label of an object by its name
0.23: sysctl.entrykindbyname: kind of an object by its name
0.24: sysctl.entryfmtbyname: format of an object by its name
0.25: sysctl.entryallinfobyname: all info of an object by its name
0.26: sysctl.entryallinfobyname_withnextnode: all info of an object by its name
with the next node name
0.27: sysctl.entryallinfobyname_withnextleaf: all info of an object by its name
with next leaf name
0.28: sysctl.entryidinputbyname: id and eventually a handler input of a node by
its name

Step 19
-V” to shows the value if possible, otherwise the status is fully hidden; by default with “/sbin/sysctl -a”, see Step “23”

user@bsd:~/% nsysctl -aNV

Step 20
-o” to show opaque value (not defined in opaque.c) in hex format until 16 bytes

user@bsd:~/% nsysctl -aNtVo | grep opaque
kern.clockrate: opaque: { hz = 1000, tick = 1000, profhz = 8128, stathz = 127 }
kern.proc.all: opaque: Format:S,proc Length:490688 Dump:0x40040000000000000000000000000000...
kern.file: opaque: Format:S,xfile Length:197632 Dump:0x80000000000000007b0a0000e9030000...
kern.boottime: opaque: { sec = 1550607730, usec = 123913 } Tue Feb 19 21:22:10 2019
kern.ipc.shmsegs: opaque: Format: Length:19968 Dump:0xe9030000e9030000e9030000e9030000...
..... extras ......

without “-o” values not defined in opaque.c are hidden

user@bsd:~/% nsysctl -aNtV | grep opaque
kern.clockrate: opaque: { hz = 1000, tick = 1000, profhz = 8128, stathz = 127 }
kern.boottime: opaque: { sec = 1550847620, usec = 140187 } Fri Feb 22 16:00:20 2019
..... extras .....

List of “defined opaque”:

  • S,clockinfo
  • S,bios_smap_xattr
  • S,efi_map_header
  • S,input_id
  • S,loadavg
  • S,timeval
  • S,vmtotal

Step 21

  • -A” equivalent to -a -V -o.
  • -B bufsize” use a buffer of bufsize bytes for a value.
  • -f filename” read object name/value from filename (example file.conf).
  • -h” try to show values in a human-friendly format.
  • -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 -a -V -x.

Step 22
setting a value, “nsysctl name=value

user@bsd:~/% su
Password:
root@bsd:/home/user/# nsysctl -Nv kern.maxprocperuid=1000
kern.maxprocperuid: 8211 -> 1000
root@bsd:/home/user/# nsysctl --libxo=xml,pretty -Nv 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 23
Compatibility sysctl - nsysctl

sysctl nsysctl
% sysctl name=value % nsysctl -Nv name=value
% sysctl name % nsysctl -Nv name
% sysctl -d name % nsysctl -Nd name
% sysctl -e name % nsysctl -Nv -e ‘=’ name
% sysctl -N name % nsysctl -N name
% sysctl -n name % nsysctl -v name
% sysctl -t name % nsysctl -Nt name
% sysctl -a % nsysctl -aNV
% sysctl -aN % nsysctl -aN
% sysctl -an % nsysctl -aV
% sysctl -ad % nsysctl -aNd
% sysctl -at % nsysctl -aNt
% sysctl -ao % nsysctl -aNVo
% sysctl -ax % nsysctl -aNVx
% sysctl -A % nsysctl -AN
% sysctl -X % nsysctl -XN


Options:

  • new options --libxo, -D, -F, -G, -g, -I, -l, -m, -r, -p , -V, -v and -y.
  • updated options -e and -N.
  • deleted option -n (simply do not use -N).


Moreover nsysctl uses the sysctlinfo interface, if the kernel module is loaded, 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 the properties of an object is improved.


Step 24
Tips and Tricks:

To show everything

user@bsd:~/% nsysctl -e ", " -aIDp
user@bsd:~/% nsysctl --libxo=xml,pretty -r "ROOT" -aID

nsysctl can get a list of object names

root@bsd:/home/user/# nsysctl -Nv 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/#

The string value of some object is handled to show structured output

user@bsd:~/% nsysctl -Nv vm.phys_free
user@bsd:~/% nsysctl --libxo=xml,pretty -Nv vm.phys_free

List of handled objects:

  • debug.witness.fullgraph
  • kern.conftxt
  • vm.phys_free

The “-h” (human output) option depends on the ‘h’ field modifier of libxo
please refer to the-humanize-modifier-h for a more thorough description.

“-V” and “-I”, it is correct to use -V with -I but it hides the internal nodes without a value, then you should use “-v”:

user@bsd:~/% nsysctl -NIv

The “-x” option shows ID and flags in hex format

user@bsd:~/% nsysctl -yNg compat
2147482900.2147481617.2147481614: compat.ia32.maxvmem: 3222016000
2147482900.2147481617.2147481615: compat.ia32.maxssiz: 3222016000
2147482900.2147481617.2147481616: compat.ia32.maxdsiz: 3222016000
user@bsd:~/% nsysctl -yNgx compat
7ffffd14.7ffff811.7ffff80e: compat.ia32.maxvmem: c00c1000
7ffffd14.7ffff811.7ffff80f: compat.ia32.maxssiz: c00c1000
7ffffd14.7ffff811.7ffff810: compat.ia32.maxdsiz: c00c1000

Step 25
Frequently asked questions:

  • Manual Page? nsysctl(8)
  • Graphical User Interface? deskutils/sysctlview.
  • Where is the source code? 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 some basic type value splitted to show libxo structured output.
  • Can I write my sysctl-like utility quickly? Yes, you can: sysctlmibinfo2(3) is an easy API to explore the sysctl MIB.