[Updated 2019-6-14]

nsysctl is a tool to get or set the FreeBSD kernel state. You could use nsysctl to explore the sysctl MIB, to print all the properties of a state and to show output via libxo in human and machine readable formats. This post is a step-by-step tutorial.

Legal notice: FreeBSD is a registered trademark of the FreeBSD Foundation.



Step "1"
To install the port

# 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=opts [-r tagname]] [-DdFGgIilmNpqTt[V|v[h[b|o|x]]]Wy]
		[-e sep] [-B <bufsize>] [-f filename] name[=value[,value]] ...
	nsysctl [--libxo=opts [-r tagname]] [-DdFGgIlmNpqTt[V|v[h[b|o|x]]]Wy]
		[-e sep] [-B <bufsize>] -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 states

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 states, with “-a” you can use many of the previous options, see Step "2".



Step "18"
-m” to show magical states 0.[1-6] “sysctl.*”

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:


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 states from filename (example file.conf).
  • -h” try to show values in a human-friendly format.
  • -i” ignore unknown state.
  • -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

/sbin/sysctl /usr/local/sbin/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).


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 states

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 state 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 states:

  • debug.witness.fullgraph
  • 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


Step "25"
Frequently asked questions:

  • Manual Page? nsysctl(8)
  • Graphical User Interface? deskutils/sysctlview.
  • Where is the source code? gitlab.com/alfix/nsysctl
  • Is it hard to customize nsysctl? No, it is very simple: 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-utility quickly? Yes, you can: sysctlmibinfo(3) is an easy API to the sysctl MIB, examples.