Changes RSS

**This is an old revision of the document!** ----

A PCRE internal error occured. This might be caused by a faulty plugin

====== Creating a Read only Debian Lenny system ====== The task here is: at work, we have these cute little Vesa-mount-sized computers originally manufactured by DMP Electronics as the [[http://www.compactpc.com.tw/ebox-4300.htm|eBOX 4310]], rebranded as [[http://www.norhtec.com/|NorhTec]] [[http://www.norhtec.com/products/mcsr/index.html|MicroClient Sr]], that we are going to use backpack-mounted on large-screen HDTV's for our internal digital signage project. These little boxes are to have no spinning disk, and an as reliable as possible system. To get no moving parts, the boxes skip using a hard drive, and we are setting them up with Compact Flash (CF) as the main storage. But, as any documentation will tell you, CF has a limited number of write-cycles, and as a result of that, it is desirable to have the system running with its filesystem read-only once booted. Internally we normally standardize on CentOS for servers, and Ubuntu+Fedora as supported desktop Linux'es. But none of these are really "dead simple" to make read-only-rootfs, and to be honest comes with too much bloat in my opinion. So I am trying to do this using Debian Lenny. Debian is stock, standard, known tech, easily modified (ref. Pebble, LEAF, DSL, Ubuntu, Mint), and supportable. The base install is also fairly easy to make small. ===== Install ===== I hooked up one of the eBOX'es, PXE-booted the Debian Lenny installer, and installed onto the CF. My magic during install was close to none: * Partitioning: Manual, one partition, no swap * Tasksel Install: Base system only. Post install: <code> apt-get -y install less bzip2 screen vim-nox openssh-server halt </code> ===== CF Image file ===== After installing, I removed the card from the eBOX, put it in a CF-reader on my workstation, created an image of it, and made a backup. <code> sudo cat /dev/sdb > sdb_dump1 # Raw disk-dump of the CF card.. cp sdb_dump1 lenny_testimg1.img # This copy is what I will be working on, sudo bzip2 sdb_dump1 # while this file is my backup. </code> So, should I ever need to restore the original Lenny install, all I'll have to do is bunzip the sdb_dump1.bz2 file back onto a CF card of the same size (or larger). After waiting for a few ages (dumping 8GB, copying 8GB and fibnally bzipping 8GB down to 586MB takes a SOLID time), I mounted up the image using loopback mounting, and continued customizing the install. ==== Loopmounting image ==== As the CF dump is a dump of the complete CF card, and Debian Installer has treated it as a harddisk, it contains a partition table. So a simple "mount -o loop imagefile" will not work. First, get a hold of where the partition to mount starts: <code> fdisk -lu lenny_testimg1.img </code> <code> You must set cylinders. You can do this from the extra functions menu. Disk lenny_testimg1.img: 0 MB, 0 bytes 255 heads, 63 sectors/track, 0 cylinders, total 0 sectors Units = sectors of 1 * 512 = 512 bytes Disk identifier: 0x000bdb20 Device Boot Start End Blocks Id System lenny_testimg1.img1 63 15615179 7807558+ 83 Linux </code> This image opnly contains one partition, and it starts at sector number 63. Each sector is 512 bytes, so the mount command becomes: <code> sudo mount -o loop,offset=$((63*512)) lenny_testimg1.img /mnt/ </code> This mounts the file system that starts at sector 63 onto /mnt. If you get the mount command wrong, it will tell you: <code> mount: you must specify the filesystem type </code> If you get this, adjust your command and try again .... You correct info __is__ given in the "fdisk -lu" output. ===== Customization ===== Jump into the file-system from the host computer: <code> sudo mount -t proc proc /mnt/proc/ sudo mount -o bind /dev/ /mnt/dev/ sudo LC_ALL=C chroot /mnt /bin/bash </code> Remove /etc/mtab and symlink it to /proc/mounts. This special file also describes the mounted filesystems, and can replace mtab without needing a write access on it. <code> rm /etc/mtab ln -s /proc/mounts /etc/mtab </code> Setting up /etc/fstab so that all locations where we will write data is a tempfs, in other words a memory filesystem. If the directories that are set up as tempfs here need to contain data after boot, those data will either be copied across by /etc/rcS.d/S36rosystem-fix or /etc/rc.local <code> # <file system> <mount point> <type> <options> <dump> <pass> /dev/hdc1 / ext3 defaults,noatime 0 0 proc /proc proc defaults 0 0 tmpfs /var/run tmpfs defaults 0 0 tmpfs /var/lock tmpfs defaults 0 0 tmpfs /var/local/data tmpfs defaults 0 0 tmpfs /var/log tmpfs defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 tmpfs /var/lib/urandom tmpfs defaults 0 0 tmpfs /var/lib/dhcp3 tmpfs defaults 0 0 tmpfs /home tmpfs defaults 0 0 </code> Now, we need resolv.conf to be writable for dhclient, so it needs to be located somewhere outside of /etc <code> mkdir /var/local/data mv resolv.conf /var/local/data/ ln -s /var/local/data/resolv.conf /etc/resolv.conf </code> Now, we need to have the dhclient-script (runs while/after dhclient is run) update the writable resolv.conf, instead of trying to replace our link on the read-only part of the system. This is sed-magic, to really see what this does, make a copy of /sbin/dhclient-script, and diff it afterwards... <code> sed \ -e '/local new_/s/=.*/=\/tmp\/resolv.conf.dhclient-new/' \ -e '/mv -f/s/mv -f.*/cat $new_resolv_conf > \/etc\/resolv.conf/' \ -i /sbin/dhclient-script </code> Just verify that network settings are appropriate for our/your/the network. I am using DHCP to configure, so i end up with: <code> cat /etc/network/interfaces </code> <code> auto lo iface lo inet loopback allow-hotplug eth0 iface eth0 inet dhcp </code> ifupdown insists on writing a status file to /etc/network/run, so that location needs to be redirected to a tmpfs location. Note that the directory /var/local/data/network_run is created on boot by /etc/rcS.d/S36rosystem-fix, which will be created later on.. <code> rm /etc/network/run mkdir /var/local/data/network_run ln -s /var/local/data/network_run /etc/network/run rmdir /var/local/data/network_run </code> We install syslogd for logging, and remove all references to xconsole from the configuration. At a later stage, it will be configured to send its log data to a central logging server, and not buffer any logging locally. <code> apt-get install syslogd sed -e '/xconsole/s/^/#/' -i /etc/syslog.conf </code> <code> sed -e 's/rootmode=rw/rootmode=ro/' -i /etc/init.d/checkroot.sh </code> <code> sed -e '/\.clean$/s/$/\n\ttouch \/var\/log\/dmesg/' -i /etc/init.d/bootmisc.sh </code> <code> echo "alias ro='mount -o remount,ro /'" >> /root/.bashrc echo "alias rw='mount -o remount,rw /'" >> /root/.bashrc </code> <code> wget http://dilbert.hig.no/jonl/rosystem-fix.txt -O /etc/init.d/rosystem-fix chmod 755 /etc/init.d/rosystem-fix ln -s /etc/init.d/rosystem-fix /etc/rcS.d/S36rosystem-fix </code> ===== Transferring back ===== <code> exit cd ~ sudo umount -l /mnt/proc sudo umount -l /mnt/dev/ sudo umount /mnt/ </code> <code> sudo cat lenny_testimg1.img > /dev/sdb </code> ===== Booting up, verifying ===== Somewhat of a failure. I need to correct some stuffz, and update the above :) <code> Mounting local filesystems ...failed wtf? Setting up networking.../etc/rcS.d/S39ifupdown: line 85: /etc/network/run/ifstate: Read-only file system Failure initializing /etc/network/run/ifstate failed! failed! Configuring network interfaces...ifup: failed to open statefile: /etc/network/run/ifstate: Read-only file system failed! chown: failed to get attributes of '/var/log/dmesg' : No such file or directory chown: failed to get attributes of '/var/log/dmesg' : No such file or directory rm: cannot remove '/var/lib/urandom/random-seed': Read-only file system Plus syslogd complaining that /var/log/news/* does in fact not exist.... </code> ===== X Server installation ===== <code> apt-get install pci-utils dbus dbus-x11 defoma x11-apps x11-session-utils x11-utils \ x11-xserver-utils xfonts-base xserver-xorg-input-kbd \ xserver-xorg-input-mouse xserver-xorg-video-dummy xserver-xorg-video-openchrome \ xserver-xorg-video-vesa xserver-xorg-video-vga xinit cpp cpp-4.3 xserver-xorg \ xserver-xorg-core xfs xfonts-100dpi xfonts-75dpi xfonts-scalable ttf-dejavu \ ttf-freefont gtk2-engines xterm blackbox iceweasel </code>