I very often use FreeBSD for some automation tasks or as a network appliance. I like hardware like SOEKRIS, ALIX and other similar rotate-less and low power consumption hardware platforms. On such platforms I'm running FreeBSD on Compact Flash card and we all know about CF limited writes, don't we? So lets prepare FreeBSD system to run on top of read-only disk and prolong compact flash live.
After normal FreeBSD installation edit /etc/rc.conf and add following lines
tmpmfs="yes"
tmpsize="20m"
varmfs="yes"
varsize="32m"
This will instruct FreeBSD to use tmp and var in memory file system (aka ram disk) instead of normal disk mount points. This will in conjunction with read-only disk significantly save writes to flash disk however /tmp and /var mount points will stay writable which is important for lot of applications.
Now we can setup boot disk to be read-only. I can do it simply by editing /etc/fstab and change Options from rw to ro for boot disk. I can also change Dump from 1 to 0.
Parameter Dump (dump-freq) adjusts the archiving schedule for the partition (used by dump).
/etc/fstab should looks like example below:
# Device Mountpoint FStype Options Dump Pass#
/dev/ada0p2 / ufs ro 0 1
So now is my FreeBSD system ready to run on top of Compact Flash card in read-only mode so it eliminates flash write issue and system can run significantly longer then on read-write disk. Of course with read-only mode limitations but that's ok for lot of automation and network appliances. When I need some data disk I usually use another disk (or CF) just for data.
After FreeBSD reboot your mount points should look like on the screenshot below
root@example:~ # mount
/dev/ada0p2 on / (ufs, local, read-only)
devfs on /dev (devfs, local, multilabel)
/dev/md0 on /var (ufs, local)
/dev/md1 on /tmp (ufs, local)
Because I configure hardware appliance I would like to have possibility to control the system without monitor and keyboard. Unix systems were always ready for serial terminal consoles. So we can simply redirect console to RS-232 port and use it for system administration.
Here is the process how to do it.
Add following command to /boot/loader.conf. You can do it simply by running following command
echo 'console="comconsole"' >> /boot/loader.conf
which redirect all the boot messages to the serial console.
Edit /etc/ttys and change off to on and dialup to xterm for the ttyu0 entry. Otherwise, a password will not be required to connect via the serial console, resulting in a potential security hole.
The line in /etc/ttys should looks like below
ttyu0 "/usr/libexec/getty std.9600" xterm on secure
Update 2016-06-26: This is not needed any more for FreeBSD 9.3 and later because a new flag, "onifconsole" has been added to /etc/ttys. This allows the system to provide a login prompt via serial console if the device is an active kernel console, otherwise it is equivalent to off.
Before editing the file I have to change read-only mode of my disk to read-write otherwise I will not be able to save the file. I can switch from read-only to read-write mode by command below:
mount -u /
If I want to change back to read-only mode here is how I do it
mount -a
This command remount all mounts with options in /etc/fstab so my disk is read-only again.
I leave the disk in read-write mode for now because I have to make the last configuration change, instruct the system to use COM port for console.
I run command
echo '-P' >> /boot.config
to add -P option to /boot.config file. The advantage of this (-P) configuration is the flexibility. If the keyboard is not present then console message are written to
- serial and internal during boot phase
- serial during boot loader phase
- serial when system is running (in kernel phase)
If the keyboard is present in the system then monitor and keyboard is used as usual.
If the keyboard is absent the console is accessible over COM port.
Important note for systems without graphic card like SOEKRIS. Other virtual terminal entries in /etc/ttys should be commented otherwise you can see errors like
Dec 22 20:25:38 PRTG-watchdog getty[1469]: open /dev/ttyv0: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1470]: open /dev/ttyv1: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1471]: open /dev/ttyv2: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1472]: open /dev/ttyv3: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1473]: open /dev/ttyv4: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1474]: open /dev/ttyv5: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1475]: open /dev/ttyv6: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1476]: open /dev/ttyv7: No such file or directory
Dec 22 20:25:38 PRTG-watchdog getty[1477]: open /dev/ttyu0: Interrupted system call
I usually leave ttyv0 enabled otherwise you will not be able to use normal console (monitor + keyboard) on systems where VGA and keyboard exist.
So here is the screenshot from typical /etc/ttys
#
ttyv0 "/usr/libexec/getty Pc" xterm on secure
# Virtual terminals
#ttyv1 "/usr/libexec/getty Pc" xterm on secure
#ttyv2 "/usr/libexec/getty Pc" xterm on secure
#ttyv3 "/usr/libexec/getty Pc" xterm on secure
#ttyv4 "/usr/libexec/getty Pc" xterm on secure
#ttyv5 "/usr/libexec/getty Pc" xterm on secure
#ttyv6 "/usr/libexec/getty Pc" xterm on secure
#ttyv7 "/usr/libexec/getty Pc" xterm on secure
#ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure
# Serial terminals
# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
ttyu0 "/usr/libexec/getty std.9600" xterm on secure
At the end don't forget to reboot the system to see if the changes took effect and everything work.
I'm writing this blog post primarily for me as a personal run-book but I believe it can be useful for some other FreeBSD hackers ;-)