[Updated 2019-4-16]

nsysctl is a tool to get or set the FreeBSD kernel state, this post is a step-by-step tutorial.

Notes: The current version “0.2” is the stage for testing, ideas and feedback, I can not test “machdep.efi_map” on my laptop, README.md has a TODO list with TOFIX and future improvements.

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



Step "-1"
nsysctl was just the main() funtion to test sysctlmibinfo(3), it is not a replacement for the well-known/used/tested sysctl(8), you should use sysctl(8) for your production environment, instead you could use nsysctl to fully explore the sysctl-mib-tree, to print all the properties of a state, to show output via libxo in human and machine readable formats, finally you can use nsysctl as a lab for new features.



Step "0"
To install the port

# cd /usr/ports/sysutils/nsysctl/ && make install clean

To add the package:

# pkg install nsysctl


Step "1"
nsysctl to show usage

alfix@fbsd:~/% nsysctl
usage:
	nsysctl [--libxo=opts [-r tagname]] [-DdFIilmNpqTt[-V|v[h[b|o|x]]]Wy]
		[-e sep] [-B <bufsize>] [-f filename] name[=value] ...
	nsysctl [--libxo=opts [-r tagname]] [-DdFIlmNpqSTt[-V|v[h[b|o|x]]]Wy]
		[-e sep] [-B <bufsize>] -A|a|X


step "2"
nsysctl with a name

alfix@fbsd:~/% nsysctl kern.ostype
alfix@fbsd:~/% 

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



Step "3"
-N” for name and “-v” for value; note, also for the next steps, the options are not mutually exclusive

alfix@fbsd:~/% nsysctl -Nv kern.ostype
kern.ostype: FreeBSD
alfix@fbsd:~/% nsysctl -Nv kern.osrevision
kern.osrevision: 199506


Step "4"
-d” for description

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


Step "5"
-t” for type and “-m” for ‘format string’

alfix@fbsd:~/% nsysctl -Ndtmv kern.ostype
kern.ostype: Operating system type: string: A: FreeBSD
alfix@fbsd:~/% nsysctl -Ndtmv kern.osrevision
kern.osrevision: Operating system revision: integer: I: 199506


Step "6":
-x for (numeric) value in hex format

alfix@fbsd:~/% nsysctl -Ndtmvx kern.ostype
kern.ostype: Operating system type: string: A: FreeBSD
alfix@fbsd:~/% nsysctl -Ndtmvx kern.osrevision
kern.osrevision: Operating system revision: integer: I: 0x00030b52


Step "7"
-b” for value in binary format without newline

alfix@fbsd:~/% nsysctl -Ndtmvb kern.ostype
kern.ostype: Operating system type: string: A: FreeBSDalfix@fbsd:~/% 
alfix@fbsd:~/% 
alfix@fbsd:~/% nsysctl -Ndtmvb kern.osrevision
kern.osrevision: Operating system revision: integer: I: R
                                                         ?alfix@fbsd:~/% 
alfix@fbsd:~/% 


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

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


Step "9"
-l” for aggregation label

alfix@fbsd:~/% nsysctl -pNldtmv -e ', ' kern.ostype
[NAME]: kern.ostype, [LABEL]: (null), [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT STRING]: A, [VALUE]: FreeBSD

It’s ‘null’, to show states with label != ‘null’

alfix@fbsd:~/% nsysctl -aNl | grep -v null
kern.features.cuse: feature
kern.features.ufs_quota64: feature
........ extras .......
kern.features.compat_freebsd_32bit: feature
kern.features.scbus: feature


Step "10"
-y” for ID and “-F” for flags

alfix@fbsd:~/% nsysctl -pyNldtmFv -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: (null), [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT STRING]: A, [FLAGS]: 80048000, [VALUE]: FreeBSD


Step "11"
-D” Equivalent to: “-d” “-F” “-l” “-m” “-N” “-t” “-v” “-y

alfix@fbsd:~/% nsysctl -Dp -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: (null), [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT STRING]: A, [FLAGS]: 80048000, [VALUE]: FreeBSD


Step "12"
–libxo” for emitting text, XML, JSON, or HTML output (xo_parse_args(3))

text

alfix@fbsd:~/% nsysctl --libxo=text -pD kern.ostype
[ID]: 1.1: [NAME]: kern.ostype: [LABEL]: (null): [DESCRIPTION]: Operating system type: [TYPE]: string: [FORMAT STRING]: A: [FLAGS]: 80048000: [VALUE]: FreeBSD

XML

alfix@fbsd:~/% nsysctl --libxo=xml,pretty -D kern.ostype
<object>
  <id>
    <level1>1</level1>
    <level2>1</level2>
  </id>
  <name>kern.ostype</name>
  <label>(null)</label>
  <description>Operating system type</description>
  <type>string</type>
  <format>A</format>
  <flags>80048000</flags>
  <value>FreeBSD</value>
</object>

JSON

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

HTML

alfix@fbsd:~/% nsysctl --libxo=html,pretty -pNdtmv 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 "13"
-r” to specify a tag-root with libxo

alfix@fbsd:~/% nsysctl --libxo=xml,pretty -r ROOT -D kern.ostype
<ROOT>
  <object>
    <id>
      <level1>1</level1>
      <level2>1</level2>
    </id>
    <name>kern.ostype</name>
    <label>(null)</label>
    <description>Operating system type</description>
    <type>string</type>
    <format>A</format>
    <flags>80048000</flags>
    <value>FreeBSD</value>
  </object>
</ROOT>


Step "14"
sysctl name” shows only the descending-leaves of name

alfix@fbsd:~/% nsysctl -N compat
compat.ia32.maxvmem
compat.ia32.maxssiz
compat.ia32.maxdsiz
alfix@fbsd:~/%
alfix@fbsd:~/% 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

alfix@fbsd:~/% nsysctl -NI compat
compat
compat.ia32
compat.ia32.maxvmem
compat.ia32.maxssiz
compat.ia32.maxdsiz

”–libxo” adds “children” tag

alfix@fbsd:~/% 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 "15"
-a” to show all states

alfix@fbsd:~/% 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 2500 states, with “-a” you can use many of the previous options, see Step "1" usage



Step "16"
-S” to show (magical) states 0.[1-6] “sysctl.*”

alfix@fbsd:~/% nsysctl -ayNS
0.1: sysctl.name
0.2: sysctl.next
0.3: sysctl.name2oid
0.4: sysctl.oidfmt
0.5: sysctl.oiddescr
0.6: sysctl.oidlabel
..... extras .....


Step "17"
-V” Show value, if value is not “showable” hidden the state, it is default with “sysctl(8) -a”, see Step "21"

% nsysctl -aNV


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

alfix@fbsd:~/% 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

alfix@fbsd:~/% 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,loadavg
  • S,timeval
  • S,vmtotal


Step "19"

  • -A” equivalent to -a -o.
  • -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 -x.


Step "20"
setting a value, nsysctl name=value

alfix@fbsd:~/% su
Password:
root@fbsd:/home/alfix/# nsysctl -Nv kern.maxprocperuid=1000
kern.maxprocperuid: 8211 -> 1000
root@fbsd:/home/alfix/# nsysctl --libxo=xml,pretty -Nv kern.maxprocperuid=8211
<object>
  <name>kern.maxprocperuid</name>
  <value>1000</value>
  <newvalue>8211</newvalue>
</object>
root@fbsd:/home/alfix/# exit
exit
alfix@fbsd:~/% 

Note: you can choose how and what to output with name=value.



Step "21"
Comparison sysctl - nsysctl

/sbin/sysctl /usr/local/sbin/nsysctl
% sysctl name % nsysctl -Nv name
% sysctl name=value % nsysctl -Nv name=value
% sysctl -N name % nsysctl -N name
% sysctl -n name % nsysctl -v name
% sysctl -d name % nsysctl -Nd name
% sysctl -a % nsysctl -NVa
% sysctl -aN % nsysctl -aN
% sysctl -ad % nsysctl -aNd
% sysctl -at % nsysctl -aNt
% sysctl -ao % nsysctl -aNVo
% sysctl -ax % nsysctl -aNx



nsysctl improvements:

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


Step "22"
Frequently asked questions:

  • Manual Page? nsysctl(8)
  • Graphical User Interface? deskutils/sysctlview.
  • Can I write my sysctl-utility quickly? Yes, you can: examples.
  • Where is the source code? It’ s here: gitlab.com/alfix/nsysctl
  • Is it hard to customize nsysctl? No, it is very simple: sysctlmibinfo(3) is an easy API to the kernel sysctl MIB Tree, nsysctl.c for getting/setting basic types, opaque.c for opaque values and special_values.c for basic types splitted for xo-output.