From Electron Cloud
Revision as of 20:04, 24 July 2010 by Ecloud (Talk | contribs) (Created page with 'I wanted to put together a low-power home automation system, with a fixed set of tasks, with read-only rootfs such that if anything goes wrong it's OK to just hit reset. (Or if …')

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

I wanted to put together a low-power home automation system, with a fixed set of tasks, with read-only rootfs such that if anything goes wrong it's OK to just hit reset. (Or if the power goes out it will reboot drama-free by itself.) For low-power hardware I wanted to make use of an old 233MHz Cyrix MediaGX system which has not had much use until now. With only the motherboard, an AT power supply modified with a Noctua fan, PCI USB and S3 Virge boards, and a 2 GB CF card for the "hard drive", it takes in the range of 20-25 watts... not bad compared to around 100 watts for a more modern PC.

So... given that it's not quite a 686-compatible, we need a Linux distro which doesn't make such assumptions about the hardware (increasingly rare). Debian 5.0 still runs on a 486. So I installed with default options onto the CF card, then went about modifying it to work even if I mount the root filesystem read-only.

grub is already configured "ro" because Debian still mounts ro first, then does fsck then mounts rw again, even with modern journaling filesystems (go figure). So I added a "maintenance mode" entry, and turned off swap on the default entry (/boot/grub/menu.lst):

title		Debian GNU/Linux, kernel 2.6.26-2-486
root		(hd0,0)
kernel		/boot/vmlinuz-2.6.26-2-486 root=/dev/hda1 ro noswap
initrd		/boot/initrd.img-2.6.26-2-486

title		Debian GNU/Linux, kernel 2.6.26-2-486 read/write
root		(hd0,0)
kernel		/boot/vmlinuz-2.6.26-2-486 root=/dev/hda1 rw
initrd		/boot/initrd.img-2.6.26-2-486

In /etc/fstab there are some tmpfs filesystems:

proc            /proc           proc    defaults        0       0
/dev/hda1       /               ext3    errors=remount-ro 0       1
/dev/hda5       none            swap    sw              0       0
tmpfs		/tmp		tmpfs	rw		0	0
tmpfs		/etc/network/run	tmpfs	rw		0	0

/var needs to be tmpfs too, but that gets tricky, because /var normally holds more stuff than I could fit in 64 megs of RAM. So I made /var-ro and /var-tmp, and moved stuff from /var which I wanted to be read-only (in normal mode) into /var-ro, and at boot it mounts /var as tmpfs then copies everything from /var-tmp into there... so we want only the bare directory structures for in /var-tmp, as well as symlinks to the stuff that is actually in /var-ro.

[earll][08:58:25 PM] du -sh /var-ro/*
8.0K	/var-ro/backups
162M	/var-ro/cache
52M	/var-ro/lib
236K	/var-ro/run
8.0K	/var-ro/www

[earll][08:58:27 PM] ll /var-tmp/
total 40
drwxr-xr-x 10 root root  4096 Jul 24 20:11 .
drwxr-xr-x 23 root root  4096 Jul 24 19:41 ..
lrwxrwxrwx  1 root root    15 Jul 24 19:53 backups -> /var-ro/backups
lrwxrwxrwx  1 root root    13 Jul 24 19:40 cache -> /var-ro/cache
lrwxrwxrwx  1 root root    11 Jul 24 19:41 lib -> /var-ro/lib
drwxrwsr-x  2 root staff 4096 Jun 18 15:17 local
drwxrwxrwt  3 root root  4096 Jul 24 19:13 lock
drwxr-xr-x  9 root root  4096 Jul 24 20:11 log
drwxrwsr-x  2 root mail  4096 Nov  6  2005 mail
drwxr-xr-x  2 root root  4096 Nov  6  2005 opt
drwxr-xr-x  6 root root  4096 Jul 24 19:55 run
drwxr-xr-x  6 root root  4096 Nov  6  2005 spool
drwxrwxrwt  2 root root  4096 Jun 18 15:17 tmp
lrwxrwxrwx  1 root root    11 Jul 24 19:40 www -> /var-ro/www

[earll][08:58:53 PM] find /var-tmp
/var-tmp
/var-tmp/mail
/var-tmp/www
/var-tmp/local
/var-tmp/cache
/var-tmp/opt
/var-tmp/backups
/var-tmp/lib
/var-tmp/run
/var-tmp/run/apache2
/var-tmp/run/portmap_mapping
/var-tmp/run/exim4
/var-tmp/run/dbus
/var-tmp/run/utmp
/var-tmp/run/network
/var-tmp/run/motd
/var-tmp/spool
/var-tmp/spool/mail
/var-tmp/spool/exim4
/var-tmp/spool/exim4/input
/var-tmp/spool/exim4/db
/var-tmp/spool/exim4/gnutls-params
/var-tmp/spool/exim4/msglog
/var-tmp/spool/samba
/var-tmp/spool/cups
/var-tmp/spool/cups/tmp
/var-tmp/spool/cron
/var-tmp/spool/cron/crontabs
/var-tmp/spool/cron/atjobs
/var-tmp/spool/cron/atjobs/.SEQ
/var-tmp/spool/cron/atspool
/var-tmp/tmp
/var-tmp/log
/var-tmp/log/installer
/var-tmp/log/installer/cdebconf
/var-tmp/log/apache2
/var-tmp/log/exim4
/var-tmp/log/samba
/var-tmp/log/samba/cores
/var-tmp/log/samba/cores/smbd
/var-tmp/log/samba/cores/winbindd
/var-tmp/log/samba/cores/nmbd
/var-tmp/log/news
/var-tmp/log/fsck
/var-tmp/log/apt
/var-tmp/lock
/var-tmp/lock/apache2

And in /etc/init.d/mountkernfs.sh, we do the copying into the tmpfs, right after the part where it optionally mounts /var/run and /var/lock as tmpfs (we don't enable that option since all of /var is basically tmpfs):

        # Mount /var as tmpfs and copy some initial stuff into there
        domount tmpfs "" /var var -omode=0777
        cp -a /var-tmp/* /var

That's about it... it boots with only a couple complaints about "read-only file system", e.g. "cannot remove /var/lib/exim4/config.autogenerated.tmp" (which is not actually there anyhow), etc.

If I want to change files which are normally read-only, I can either reboot into maintenance mode or just

 mount / -o remount,rw

then reboot again afterwards.