[Updated 2019-4-28]

nsysctl is a tool to get or set the FreeBSD kernel state, this post is a step-by-step tutorial; note, the current version “0.9” is the stage for testing, ideas and feedback (README.md has a TODO list).

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



Step "0"
nsysctl was just the main() funtion to test sysctlmibinfo(3), 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 and to show output via libxo in human and machine readable formats.



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

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


step "3"
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 "4"
-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 "5"
-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 "6"
-t” for type and “-F” for ‘format string’

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


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

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


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

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


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

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

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

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

alfix@fbsd:~/% nsysctl -pyNldtFgGv -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT STRING]: A, [FLAGS]: 80048000, [TRUE-FLAGS]: RD RW RDTUN RWTUN MPSAFE CAPRD CAPRW, [VALUE]: FreeBSD


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

alfix@fbsd:~/% nsysctl -Dp -e ', ' kern.ostype
[ID]: 1.1, [NAME]: kern.ostype, [LABEL]: , [DESCRIPTION]: Operating system type, [TYPE]: string, [FORMAT STRING]: A, [FLAGS]: 80048000, [TRUE-FLAGS]: RD RW RDTUN RWTUN MPSAFE CAPRD CAPRW, [VALUE]: FreeBSD


Step "14"
--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]: : [DESCRIPTION]: Operating system type: [TYPE]: string: [FORMAT STRING]: A: [FLAGS]: 80048000: [TRUE-FLAGS]: RD RW RDTUN RWTUN MPSAFE CAPRD CAPRW: [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></label>
  <description>Operating system type</description>
  <type>string</type>
  <format>A</format>
  <flags>80048000</flags>
  <true-flags>
    <flag>RD</flag>
    <flag>RW</flag>
    <flag>RDTUN</flag>
    <flag>RWTUN</flag>
    <flag>MPSAFE</flag>
    <flag>CAPRD</flag>
    <flag>CAPRW</flag>
  </true-flags>
  <value>FreeBSD</value>
</object>

JSON

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

HTML

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

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

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



Step "18"
-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 "19"
-V” Show value, if value is not “showable” hidden the state, it is default with “sysctl(8) -a”, see Step "21"

% nsysctl -aNV


Step "20"
-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,input_id
  • S,loadavg
  • S,timeval
  • S,vmtotal


Step "21"

  • -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 "22"
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:~/% 

To set a numeric array: “nsysctl name=value,value,value,value”.



Step "23"
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 -e name % nsysctl -Nv -e ‘=’ 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
% sysctl -ae % nsysctl -aNV -e ‘=’


Options:

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


Step "24"
Frequently asked questions:

  • Manual Page? nsysctl(8)
  • Graphical User Interface? deskutils/sysctlview.
  • Where is the source code? It’ s here: 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 for libxo.
  • Can I write my sysctl-utility quickly? Yes, you can: sysctlmibinfo(3) is an easy API to the sysctl MIB, examples.