Crucial FreeBSD Toolkit

10 hours ago 5

While FreeBSD is similar in many concepts to other UNIX systems or to Linux – its good to know exact commands and solutions for various needs.

Today I would like to share all of them – after using FreeBSD for about 20 years – both privately and professionally.

The Table of Contents looks as follows.

  • Scroll Raw FreeBSD Console
  • Suspend/Resume Internals
  • Network Information
  • FreeBSD Tools
  • Additional Mount Points
  • Disk Information and Evaluation
  • Linux lsblk(8) Command
  • Instant Reboot
  • Mount ISO Image
  • Free RAM Memory
  • What is Listening
  • The tar(1) That Does More
  • Create/Extend Raw Volume
  • Filesystem Detection
  • Track Disk Utilization over Time
  • Manage ZFS Boot Environments
  • Sensors
  • Gigabytes in df(8) Command
  • Process Tracing
  • Idle and Realtime Priority
  • The fstab(5) Input
  • Forgotten systat(8) Command
  • Apply devfs(8) Ruleset Live

~

This is probably the first question I asked at the legendary – now killed and not existent – BSDForums.net – how to scroll the raw terminal on the FreeBSD – as I came from the Linux world to FreeBSD – I expected that just [SHIFT]+[PGUP] and [SHIFT]+[PGDN] would work … not on FreeBSD.

On FreeBSD You first need to hit [Scroll Lock] key – then you can scroll the console buffer with [PGUP] and [PGDN] keys.

~

On FreeBSD system one can use to enter sleep (S3) state with zzz(8) command.

To add various tasks that need to happen before sleep happens can be added to the /etc/rc.suspend file.

To add various tasks that need to happen after sleep ends and resume phase happens – use the /etc/rc.resume file instead.

~

Linux is well known to rewrite its older ifconfig(8) and router(8) tools into ip(8) command.

FreeBSD still uses (and develops) the ifconfig(8) and route(8) commands – but if you come from Linux – the so called muscle memory will often guide your fingers to type ip(8) command instead of ifconfig(8) – how to cope with that?

The answer is simple – additional shell function that would take care of that.

Below you can copy the needed function.

FreeBSD % grep -A 256 'ip()' /usr/local/etc/zshrc | bat -l sh ip() { case ${1} in (r) netstat -Wrn -f inet \ | grep -A 256 '^Destination' \ | awk '{printf("%20s %-18s %18s %-7s\n", $1, $2, $4, $3)}' ;; (l) netstat -Win -f link \ | awk '{printf("%20s %-18s %18s %-7s\n", $1, $4, $3, $2)}' ;; (a|*) netstat -Win -f inet \ | awk '{printf("%20s %-18s %18s %-7s\n", $1, $4, $3, $2)}' ;; esac } FreeBSD % ip a Name Address Network Mtu lo0 127.0.0.1 127.0.0.0/8 - vm-public 10.1.1.1 10.1.1.0/24 - vm-VLAN239 172.27.33.193 172.27.33.192/26 - ue0 192.168.50.3 192.168.50.0/24 - FreeBSD % ip r Destination Gateway Nhop# Flags default 192.168.50.114 11 UGS 10.1.1.0/24 link#5 2 U 10.1.1.1 link#2 3 UHS 127.0.0.1 link#2 1 UH 172.27.33.192/26 link#6 4 U 172.27.33.193 link#2 5 UHS 192.168.50.0/24 link#3 6 U 192.168.50.3 link#2 7 UHS

I still need to work with Linux systems from time to time – so having a working ip(8) command equivalent on FreeBSD is welcoming.

… and if you are curious why I always use -prism option set for the uname(1) command – besides that it shows all information that is needed – its my personal tribute to Edward Snowden – the man who bravely whistleblowered the PRISM program – KUDOS to You mate. Not sure how much accurate is the movie – Snowden (2016) – but I really enjoyed it – especially after the Joseph Gordon-Levitt performance in the Dark Knight Rises (2012) and Premium Rush (2012) movies.

~

FreeBSD Tools

By default the FreeBSD ifconfig(8) command displays information in hexadecimal values like netmask 0xffffff00 for example instead of /24 … but you can use -f cidr option to switch to the latter.

You can also make that permanent with IFCONFIG_FORMAT=inet:cidr variable exported within your shell configs with either export(1) or setenv(1) depending on your preferred shell.

FreeBSD # ifconfig ue0 ue0: flags=8843 metric 0 mtu 1500 options=0 ether 02:25:6d:76:1e:7b inet 192.168.50.3 netmask 0xffffff00 broadcast 192.168.50.255 nd6 options=29 FreeBSD # export IFCONFIG_FORMAT=inet:cidr FreeBSD # ifconfig ue0 ue0: flags=8843 metric 0 mtu 1500 options=0 ether 02:25:6d:76:1e:7b inet 192.168.50.3/24 broadcast 192.168.50.255 nd6 options=29

~

In about 2013 I wrote and published automount(8) that utilizes FreeBSD devd(8) daemon to automatically mount and serve removable media and disks. Twelve years later – after many updates and improvements – I still use and maintain that very solution.

While using FreeBSD there came one additional need that automount(8) does not cover. What is additionally mounted and what I can unmount to get to the ‘default’ state of mounted filesystems?

In the past I checked the output of mount(8) command – and acted accordingly – that took time. Every. Single. Time.

That pushed me to kinda semi automate it – to not waste much more time on that.

Meet mnt.sh command (script).

It has two functions – first to list all filesystems and devices that are mounted additionally to what FreeBSD system has after the boot – or in Jails – or in Bhyve VMs. Secondly it allows to successfully unmount all of them with -u option. Nothing more. Nothing less.

~

When people think about that topic – they often either think about some S.M.A.R.T. related tools or benchmarks … and the diskinfo(8) can tell you fast how good the disk performs. Just start it against any disk with -cvt arguments and you know what You need to know.

In the terminal.

FreeBSD % diskinfo -ctv DISK

That is most that you need for a start.

~

While for most of the time I prefer FreeBSD tools for the job – exceptions sometimes happen – and lsblk(8) is one of such welcoming exception. It lists all disks/partitions/filesystems in a system that FreeBSD does not with its Geom disk list or gpart show commands – or just not in a condensed way that I really like.

It took me some time to rewrite the meritum of the tool in the POSIX /bin/sh shell – but now its available at lsblk package on FreeBSD.

You can read more about lsblk(8) for FreeBSD on the List Block Devices on FreeBSD lsblk(8) Style page.

~

Nothing really fancy – but sometimes needed – imagine some process (or mount) went sideways and usual reboot(8) or shutdown(8) commands are not able to do anything to reboot a locked system.

This is when this tip is useful. Its equivalent of Linux -r flag for the reboot(8) command. Restart the system NOW – in that single second – no questions asked.

FreeBSD # sysctl debug.kdb.panic=1

After issuing that command you can be SURE that its restated.

~

Mounting ISO image on Linux systems requires one step while it requires two steps on FreeBSD.

Lets bring that up to par with loop.sh script.

FreeBSD % loop.sh -h usage: loop.sh image.iso /mnt/point

Example usage below.

Keep in mind that even loop.sh image.iso ISO command would work.

~

You can get the amount of free RAM from – for example – the top(1) command – but a lot of people already have the free(1) command. Fortunately you can install freecolor package on FreeBSD and have the same functionality.

FreeBSD # pkg install -y freecolor FreeBSD # freecolor -o -m total used free shared buffers cached Mem: 31728 6874 24854 0 0 0 Swap: 2048 0 2048 FreeBSD # pkg which -o $( which freecolor ) /usr/local/bin/freecolor was installed by package sysutils/freecolor

~

The question that every sysadmin asks himself everytime server is managed.

FreeBSD offers really great sockstat(8) command for that.

FreeBSD # sockstat -l4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root sshd 42298 8 tcp4 *:22 *:* root nfsd 90131 5 tcp4 *:2049 *:* root cupsd 81818 7 tcp4 127.0.0.1:631 *:*

~

On FreeBSD the tar(1) command uses libarchive(3) – it allows tar(1) to also read and extract – for example – ISO files.

FreeBSD % which tar /usr/bin/tar FreeBSD % tar -tf ~/vm/iso/FreeBSD-15.0-CURRENT-amd64-20250612-e6928c33f60c-277883-disc1.iso | head . bin bin/cat bin/chflags bin/chio bin/chmod bin/cp bin/cpuset bin/csh bin/tcsh

~

On FreeBSD that is covered by the truncate(1) command.

For example – want to expand your vm-bhyve VM disk up to 100 GB in size? This is the command.

FreeBSD # cd /vm/poudriere FreeBSD # truncate -s 100g disk0.img

~

When I started with automount(8) I could only rely on file -s ... command for filesystem detection.

Some time after automount(8) introduction the fstyp(8) command was introduced.

It is more or less simplified way to check what filesystem is on a device – and its really useful.

FreeBSD % fstyp /dev/nda0p1 msdosfs

~

One of the commands I love from FreeBSD is this one – gstat(8) – just shows in desired interval how many IOPS and bandwidth the disks provide.

FreeBSD # gstat -p -I 3s dT: 0.010s w: 1.000s L(q) ops/s r/s kBps ms/r w/s kBps ms/w %busy Name 0 486 486 20228 0.214 0 0 0.000 10.4| nda0 0 0 0 0 0.000 0 0 0.000 0.0| nda1 0 0 0 0 0.000 0 0 0.000 0.0| da0

It also comes with useful colors – and there is also Rust version on the FreeBSD Ports as sysutils/gstat-rs port available.

~

Right now FreeBSD has bectl(8) in the base – which works well. There is also mine beadm(8) available as sysutils/beadm package that has one important additional reroot option – ZFS Boot Environments Revolutions – more on that here.

Once You understand how great protection ZFS Boot Environments give – you will never want to live without them.

~

Linux comes with a sensors(8) command that prints various sensors temperatures etc. While similar information was available on FreeBSD – it was never gathered in one single place … up till I wrote the sensors(8) command for FreeBSD.

Installation is pretty straightforward.

FreeBSD # mkdir -p ~/bin FreeBSD # fetch -o ~/bin/sensors https://raw.githubusercontent.com/vermaden/sensors/master/sensors FreeBSD # chmod +x ~/bin/sensors

If you would like to read more about it – Sensors Information on FreeBSD – you will find it here.

~

Both IBM AIX and FreeBSD UNIX systems have one advantage that Linux df(8) command – they both support -g flag that will display usage in gigabytes. Unfortunately with Linux one you can either have megabytes at most.

The one on IBM AIX looks slightly different – but the end result is similar.

~

On Linux systems many times I needed to use useful strace(8) command. On IBM AIX and FreeBSD UNIX its called truss(8) but does the same thing.

FreeBSD # truss -s 30 /bin/ls /tmp/gimp 2>&1 | grep / open("/etc/libmap.conf",O_RDONLY|O_CLOEXEC,030250030030) = 3 (0x3) read(3,"includedir /usr/local/etc/libm"...,35) = 35 (0x23) open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) = 3 (0x3) open("/usr/local/etc/libmap.d/mesa.conf",O_RDONLY|O_CLOEXEC,0165) = 4 (0x4) open("/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,016177641474) = 3 (0x3) pread(3,"/lib:/usr/lib:/usr/lib/compat:"...,437,0x80) = 437 (0x1b5) open("/lib/libutil.so.9",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3) open("/lib/libtinfow.so.9",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3) open("/lib/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3) readlink("/etc/malloc.conf",0x2b93923aae70,1024) ERR#2 'No such file or directory' open("/usr/share/locale/en_US.UTF-8/LC_COLLATE",O_RDONLY|O_CLOEXEC,022216535310) = 3 (0x3) open("/usr/share/locale/en_US.UTF-8/LC_CTYPE",O_RDONLY|O_CLOEXEC,022216532030) = 3 (0x3) open("/usr/share/locale/en_US.UTF-8/LC_MONETARY",O_RDONLY|O_CLOEXEC,022216533616) = 3 (0x3) open("/usr/share/locale/en_US.UTF-8/LC_NUMERIC",O_RDONLY|O_CLOEXEC,022216533636) = 3 (0x3) open("/usr/share/locale/en_US.UTF-8/LC_TIME",O_RDONLY|O_CLOEXEC,022216533656) = 3 (0x3) open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES",O_RDONLY|O_CLOEXEC,022216533656) = 3 (0x3) fstatat(AT_FDCWD,"/tmp/gimp",{ mode=drwxr-xr-x ,inode=354,size=3,blksize=4096 },0x0) = 0 (0x0) open("/tmp/gimp",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,016033264547) = 4 (0x4)

One can also use DTrace if needed.

~

I do not remember how many times I wanted a process – like make(1) for FreeBSD Ports compiling for example – would REALLY do not interfere with what I am interactively doing right now – have as low priority as possible … and the good oldschool renice(8) was just not enough.

This is where FreeBSD idprio(1) and rtprio(1) command come handy – for idle and realtime respectively. If you want to allow a regular user to be able to use them – add that user to idletime or realtime groups.

While the renice(8) command takes argument from -19 to 20 – both idprio(1) and rtprio(1) commands take argument from 0 to 31. Higher the value – bigger the power. For example idprio 31 command would make a command ultra low in the priority – that when anything else uses CPU – that command will literally have to wait till its not 🙂

~

When you are on a Linux system – the /etc/mtab file helps mounted filesystems in fstab(5) format. That helps if you mounted filesystem by hand and now want to add that information to /etc/fstab file to make it permanent. On Linux you would do something like that:

Linux # tail -1 /etc/mtab >> /etc/fstab Linux # vi /etc/fstab

On FreeBSD there is no /etc/mtab file – but there is -p file for mount(8) command – that prints mounted filesystems in fstab(5) format – so on FreeBSD you would do something like that instead.

FreeBSD # mount -p | tail -1 >> /etc/fstab FreeBSD # vi /etc/fstab

~

Its rarely known – that systat(8) command – I often use it for example to check how much the network interfaces are utilized.

FreeBSD # systat -if 1 /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 Load Average || Interface Traffic Peak Total tap0 in 0.000 KB/s 0.000 KB/s 10.095 MB out 0.174 KB/s 0.174 KB/s 350.764 MB vm-VLAN239 in 0.160 KB/s 0.160 KB/s 22.615 MB out 0.174 KB/s 0.174 KB/s 351.268 MB vm-public in 0.160 KB/s 0.160 KB/s 12.183 MB out 0.000 KB/s 0.000 KB/s 0.000 KB lo0 in 0.160 KB/s 0.160 KB/s 113.110 MB out 0.000 KB/s 0.000 KB/s 95.753 MB em0 in 8.569 KB/s 25.965 KB/s 37.437 GB out 6.907 KB/s 127.806 KB/s 82.828 GB

The next one should be familiar to IBM AIX fans – as it kinda reminds topas(8) command.

FreeBSD # systat -vmstat 6 users Load 0.31 0.61 0.62 Jun 24 15:29:45 Mem usage: 89%Phy 5%Kmem VN PAGER SWAP PAGER Mem: REAL VIRTUAL in out in out Tot Share Tot Share Free count Act 24451M 995M 7391G 116G 3591M pages All 24515M 1058M 7391G 117G ioflt Interrupts Proc: cow 3353 total r p d s w Csw Trp Sys Int Sof Flt 49 zfod atkbd0 1 33 1364 7K 53 2K 2K 2 52 ozfod acpi0 9 %ozfod psm0 12 0.6%Sys 0.5%Intr 1.2%User 0.0%Nice 97.6%Idle daefr 145 cpu0:timer | | | | | | | | | | | prcfr 129 cpu1:timer + 25 totfr 121 cpu2:timer dtbuf react 129 cpu3:timer Namei Name-cache Dir-cache 1102463 maxvn pdwak 115 cpu4:timer Calls hits % hits % 17701 numvn 1108 pdpgs 86 cpu5:timer 196 188 96 1404 frevn intrn 207 cpu6:timer 2729M wire 115 cpu7:timer Disks nda0 nda1 da0 pass0 pass1 pass2 2616M act 1961 xhci0 128 KB/t 2.67 1024 0.00 0.00 0.00 0.00 21G inact nvme0:admi tps 1 1 0 0 0 0 1542M laund nvme0:io0 MB/s 0.00 0.80 0.00 0.00 0.00 0.00 3591M free nvme0:io1 %busy 0 0 0 0 0 0 0 buf 1 nvme0:io2 nvme0:io3 nvme1:admi 1 nvme1:io0 nvme1:io1 nvme1:io2 nvme1:io3 188 hdac0 139 147 em0:irq0 8 vgapci0 iwm0 142 xhci1 143

The systat(8) command even comes with ZFS ARC monitor.

FreeBSD # systat -zarc Total MFU MRU Anon Hdr L2Hdr Other ZFS ARC 641M 303M 234M 1917K 4525K 0 99181K Rate Hits Misses | Total Rate Hits Misses arcstats : 0% 0 0 | 96% 177M 6695k arcstats.demand_data : 0% 0 0 | 98% 41577k 633k arcstats.demand_metadata : 0% 0 0 | 96% 134M 4870k arcstats.prefetch_data : 0% 0 0 | 4% 18251 425k arcstats.prefetch_metadata: 0% 0 0 | 64% 1371k 768k zfetchstats : 0% 0 0 | 39% 13054k 20324k arcstats.l2 : 0% 0 0 | 0% 0 0 Disks nda0 nda1 da0 pass0 pass1 pass2 KB/t 0.00 0.00 0.00 0.00 0.00 0.00 tps 0 0 0 0 0 0 MB/s 0.00 0.00 0.00 0.00 0.00 0.00 %busy 0 0 0 0 0 0

~

One of the things I found useful – especially for debugging – was how to apply new devfs(8) ruleset to running Jail.

FreeBSD # devfs -m /jail/dns/dev ruleset 130

Hope that helps.

~

Feel free to share your favorite useful FreeBSD commands that make your life better.

EOF

Read Entire Article