Introduction to sysclean(8)
- Published on 2023-09-19 by Sebastien Marie
- Reading time: 5 minutes #sysclean
sysclean(8), what is it ?
sysclean(8) is a system tool designed for help system administrator to keep their OpenBSD clean after upgrade.
It walks the installed system and compare to a reference system, reporting to the user additionnal things in the installed system.
The purpose is to point any elements that wouldn't be present if a fresh install was done, instead of an upgrade.
The reference system
The reference system is built from several local sources:
- the locate databases installed by the system
- the
/dev/MAKEDEV
script - the ports tree database, for currently installed packages
- a small set of hardcoded paths
- sysmerge(8) sets for base and X(7)
locate databases
The system is installed with two locate databases:
/usr/lib/locate/src.db
/usr/X11R6/lib/locate/xorg.db
The content is extractable with locate(1)
$ locate -d /usr/lib/locate/src.db '/ls'
base73:/bin/ls
comp73:/usr/include/dev/ic/lsi64854reg.h
comp73:/usr/include/dev/ic/lsi64854var.h
comp73:/usr/share/man/man2/lseek.2
comp73:/usr/share/man/man3/lsearch.3
man73:/usr/share/man/man1/ls.1
These files are built during the release(8) process, using the sets list files at src/distrib/sets/lists/.
/dev/MAKEDEV
script
The /dev
directory is populated at install time. So the sets doesn't have the exact list of files, and so locate databases doesn't have /dev/
paths.
During the install (or the upgrade), installer runs the /dev/MAKEDEV
script. This script is complex: it is built from m4 source files, with a machine dependant and machine independant mix (see the MAKEDEV.*
files in src/etc/).
To extract the list of paths for the reference system, the script is ran in "Echo-Only debugging" mode.
$ eo=echo /dev/MAKEDEV std
rm -f console tty mem kmem null zero stdin stdout stderr ksyms klog xf86;
mknod -m 600 console c 0 0
-m 666 tty c 1 0
-m 640 mem c 2 0
-m 640 kmem c 2 1
-m 666 null c 2 2
-m 666 zero c 2 12
-m 666 stdin c 22 0
-m 666 stdout c 22 1
-m 666 stderr c 22 2
-m 640 ksyms c 50 0
-m 600 klog c 7 0
-m 600 xf86 c 2 4
&& chgrp kmem mem
&& chgrp kmem kmem
&& chgrp kmem ksyms
&& chgrp wheel console tty null zero stdin stdout stderr klog xf86
Here, we asked for std
set: only the "Standard devices". The output has been reindented for readability.
sysclean will slightly parse the output searching for mknod(1)
command, and it extracts the device name.
ports tree database
The database of installed packages is at /var/db/pkg/
.
The access to the database is done using the Perl API for the pkg tools internals, specially OpenBSD::PackingList for the "pkg_add(1)" packing-list manipulations.
As sysclean is itself written in Perl, it is easier to use it.
From the command-line, the list of installed files from a package could be get with pkg_info(1).
$ pkg_info -L sysclean
Information for inst:sysclean-3.4
Files:
/usr/local/man/man8/sysclean.8
/usr/local/sbin/sysclean
/usr/local/share/examples/sysclean/sysclean.ignore
hardcoded paths
Some others paths are directly hardcoded in sysclean.
Usually, it is files which are created at first-time run (like ssh host keys), or installed by the installer but without using a set (like /bsd
kernel, or the network configuration files at /etc/hostname.*
).
But some configuration files has been added in this list too, and are only conditionnally added. So if the daemon isn't enabled, the configuration file isn't expected to be present.
For example, if accounting
is on, the logs at /var/account/
are expected to be present.
The current configuration is exported using rcctl(8).
$ rcctl ls on
accounting
apmd
check_quotas
cron
dhcpleased
hotplugd
httpd
library_aslr
lpd
ntpd
obsdfreqd
pf
pflogd
resolvd
slaacd
smtpd
sndiod
sshd
syslogd
unwind
vmd
xenodm
sysmerge(8) sets
sysmerge(8)
is a tool to update system configuration files.
It comes with /var/sysmerge/etc.tgz
and /var/sysmerge/xetc.tgz
, which contains the reference files corresponding to the currently installed system.
sysclean(8) will read etc/master.passwd
and etc/group
files from the etc.tgz
tarball, to extract the expected list of users and groups.
The installed system
It is the simpler part, as it is enough to walk:
- the filesystem, using File::Find
- the users, using getpwent(3) (via perl API)
- the groups, using getgrent(3) (via perl API)
For the filesystem, File::Find
permit to cut the search and avoid going depth in unknown directories. So only the first level is reported by sysclean(8), and not all files in a unknown directory.