Home>Berichten>Technologie>How to: bouw een read-only Linux systeem

How to: bouw een read-only Linux systeem

By ·Categorieën: Technologie·Published On: januari 27th, 2009·11.3 min read·

Er lijken veel mensen op zoek te zijn om een op maat gemaakte applicatie te draaien op een Linux-gebaseerd platform op een solid-state opslagapparaat. Van tijd tot tijd ontvangen we vragen van klanten die hun linux platforms read-only willen maken om de levensduur van hun flash drives te maximaliseren. Ik vond dit een mooie kans om er een blogpost aan te wijden die beschrijft hoe je dit doet.

Er zijn een aantal verschillende manieren om een Linux systeem read-only te maken.Helaas is het normaalgesproken niet zo eenvoudig als gewoon een conventioneel bestandssysteem te gebruiken met de read-only optie. Veel programma’s verwachten dat tenminste op een aantal delen van het systeem kan worden geschreven. In sommige gevallen is de werking van deze programma’s niet correct als dit niet mogelijk is.

Ik zal de aanpak beschrijven waarvan ik denk dat deze het beste is voor de meeste toepassingen. Het is vergelijkbaar met de huidige generatie van live CD-distributies.

Live CD’s hebben over het algemeen read-only toegang tot een a root bestandssysteem. Deze is vaak gecomprimeerd in een enkel bestand om later gebruikt te worden met behulp van een loopback-apparaat. Knoppix heeft iets nieuws bedacht door het cloop bestandssysteem te gebruiken voor dit doel. Recentere live distributies gaan een stap verder door gebruik te maken van een union-bestandssysteem om het root-bestandssysteem beschrijfbaar te maken. Deze aanpak is ook best handig voor onze doelstelling.

Union-bestandssystemen

In het algemeen combineert een union-bestandssysteem meerdere bestandssystemen in een enkel virtueel bestandssysteem. Er zijn 2 populaire union-bestandssystemen waar ik bekend mee ben: unionfs en aufs. Beide hebben hetzelfde basismodel. Het volgende is een zeer versimpelde weergave:

  • Bestandssystemen zijn verticaal opgestapeld.
  • Read-toegang wordt geprobeerd op elk bestandssysteem in de volgorde van boven naar beneden. Het eerste bestandssysteem dat het te lezen bestand bevat wordt gebruikt voor de read-opdracht.
  • Schrijftoegang wordt op eenzelfde wijze uitgevoerd, maar bestanden die worden geschreven worden opgeslagen in het hoogst beschrijfbare bestandssysteem.

Meestal betekent dit dat er een enkele beschrijfbare laag is in de union. Als bestanden in de read-only laag ook geschreven zijn, worden deze eerst gekopieerd naar de volgende hoogst beschrijfbare laag. Natuurlijk zijn er nog andere verdiepingen en bijzaken die ik hier niet bespreek. Het belangrijkste is dat we een read-only bestandssysteem kunnen gebruiken (Mag een gecomprimeerde bestandssysteem afbeelding of flash-apparaat met een meer conventioneel bestandssysteem zijn, zoals ext3) en een schrijfbaar systeem hier bovenop bouwen. Het enige dat we nodig hebben is een beschrijfbaar bestandssysteem naar union met de read-only laag.

De beschrijfbare laag

Het soort beschrijfbare bestandssysteem je gebruikt, hangt af van wat je wilt bereiken. Als je geen persistentie nodig hebt tussen boots is het gemakkelijk om tmpfs te gebruiken. Schrijfopdrachten naar het systeem worden bewaard in RAM als het systeem aanstaat, maar zullen verdwijnen zodra het systeem wordt afgesloten of opnieuw opgestart.

 Wanneer je persistentie over de gehele directory structuur van het systeem wilt hebben, heb je een voortdurend beschrijfbare laag nodig. Dit is waarschijnlijk een conventioneel bestandssysteem op een ander media-apparaat (mogelijk een tweede disk). Dit is in de meeste gevallen handig voor live systemen of thin clients waar het gebruik van een read-only basis niet zoveel doet voor de levensduur, omdat het om de lokale opslagvereisten te minimaliseren is.

In veel gevallen, als je persistentie wilt, is het alleen voor specifieke bestanden nodig. Bijvoorbeeld; als je een kiosk hebt die gebruikersinput opslaat in een lokale database, moet de database bestaan op de disk, maar wil je waarschijnlijk niet dat er tijdelijke bestanden of andere dingen voor korte termijn runtime data opstaan. De beste aanpak voor dit veelvoorkomende geval is om een tmpfs read/write laag te hebben en deze koppelen aan een willekeurig koppelpunt, zoals like /var/local/data (bijvoorbeeld).

Implementatie

Implementatie van een read-only systeem vereist aansluiting in het boot proces. Hoe dit moet, hangt af van distributie tot distributie en kan mogelijk op meerdere manieren worden gedaan per distributie. In dit artikel demonstreer ik een aanpak die werkt met Ubuntu 8.04.

Ubuntu 8.04 gebruikt standaard een initramfs. Dit is de beste locatie om onze modificatie te maken, omdat we er voor kunnen zorgen dat het union bestandssysteem vroeg op het boot proces is aangesloten.

initramfs-tools

Ubuntu heeft een uitgebreid systeem voor het bouwen van de initramfs, genoemd“initramfs-tools”. We kunnen dit gebruiken om wat scripts in de initramfs te plaatsen.Er zijn een aantal verschillende manieren waarop de initramfs-tools uitgebreid kunnen worden: “hooks” en “scripts.”     

Hooks werken wanneer de initramfs wordt opgebouwd en zijn handig voor het toevoegen van kernel modules of executables naar de initramfs image. Hooks die worden verspreid met packages zijn normaalgesproken geïnstalleerd in /usr/share/initramfs-tools/hooks, en gebruiken de functies die zijn gemaakt in usr/share/initramfs-tools/hook-functions. Lokale hooks moet je plaatsen in /etc/initramfs-tools/hooks.

Scripts werken binnen de initramfs omgeving tijdens het booten. Deze kunnen gebruikt worden om het vroege boot proces aan te passen. Net als met hooks zijn scripts die worden verspreid met packages normaalgesproken geïnstalleerd in /usr/share/initramfs-tools/scripts. Lokale scripts horen naar het volgende te gaan: /etc/initramfs-tools/scripts.

initramfs generatie wordt beheerd bij de configuratiebestanden en bevinden zich in/etc/initramfs-tools. /etc/initramfs-tools/initramfs.conf is het primaire configuratiebestand, maar bestanden kunnen ook in /etc/initramfs-tools/conf.d geplaatst worden. De primaire boot methode kan worden geconfigureerd in initramfs.conf door het veranderen van de waarde van de variabele “BOOT.” Standaard is deze “local,” een boot methode die het root bestandssysteem op een lokale media plaatst, zoals een harddisk.

Voor elke boot-methode is er een script met die naam en bepaalt hoe deze boot-methode werkt. Er is bijvoorbeeld een script met de naam “local” dat definieert hoe een lokale boot wordt uitgevoerd. Veel van dergelijke scripts bieden ook hooks voor andere shell-scripts die op bepaalde punten tijdens het opstartproces moeten worden uitgevoerd.Bijvoorbeeld, alle scripts die zijn geplaatst in /usr/share/initramfs-tools/local-premount zullen worden uitgevoerd door het “local” script net voorafgaand aan het mounten van het rootbestandssysteem. Het init-script zelf (dat fungeert als proces # 1 tot het punt waar de echte init daemon wordt gestart, na mounting van het rootbestandssysteem) biedt soortgelijke hooks. Zie de inhoud van /usr/share/initramfs-tools/scripts om een idee te krijgen welke andere hooks beschikbaar zijn.

Ten slotte moeten zowel hooks als scripts zo worden geschreven dat, als ze worden uitgevoerd met één argument ‘prereqs’, ze een door spaties gescheiden lijst afdrukken met de namen van andere scripts of hooks die moeten worden uitgevoerd voordat dit specifieke script of hook wordt uitgevoerd. Dit biedt een eenvoudig systeem met dependencies tussen hooks en scripts. Ik merk dat ik zelden gebruik maak van deze functie, maar het is het wel beschikbaar indien jouw toepassing dit vereist.

Hooks and Scripts

We zullen ons read-only systeem implementeren door één hook en één script te introduceren. Ons script zal eigenlijk een init-bottom script zijn, uitgevoerd nadat het echte root-apparaat al is gemonteerd. Ons doel zal zijn om de reeds gemonteerde root bestandssysteem te nemen en het te gebruiken als de basis voor een aufs-unie met een tmpfs beschrijfbare laag. Hierdoor kunnen we het standaard Ubuntu configuratiemechanisme blijven gebruiken voor het specificeren van het apparaat dat het echte root-bestandssysteem bevat.

We hebben een hook nodig om de initramfs-tools te vertellen dat we een paar kernelmodules nodig hebben (aufs en tmpfs, die beide zijn opgenomen in Ubuntu 8.04) en een uitvoerbaar bestand (chmod). We zullen binnenkort zien waarom we chmod nodig hebben. Onze hook is vrij eenvoudig (zoals de meeste zijn). We noemen dit hooksro_root:

#!/bin/sh

PREREQ=''

prereqs() {
  echo "$PREREQ"
}

case $1 in
prereqs)
  prereqs
  exit 0
  ;;
esac

. /usr/share/initramfs-tools/hook-functions
manual_add_modules aufs
manual_add_modules tmpfs
copy_exec /bin/chmod /bin

Het script doet het echte werk om ervoor te zorgen dat de bestandssystemen allemaal op de juiste plaatsen zijn gemount. Op dit moment van het opstartproces is het echte root-apparaat op $rootmnt gemount en /sbin/init op dat mount-punt staat klaar om te worden uitgevoerd. Hier willen we de root-apparaat mount naar een ander mount-punt verplaatsen en onze union-mount op die plaats bouwen.

Hier is hoe we dit doen:

  1. Verplaats $rootmnt naar /${rootmnt}.ro (dit is de read-only laag).
  2. Mount onze beschrijfbare laag als tmpfs op /${rootmnt}.rw.
  3. Mount de union op ${rootmnt}.

Daarnaast willen we mogelijk toegang hebben tot de read-only en read/write-lagen onafhankelijk van de union. Om toegang tot deze mounts te behouden, moeten we ze binden aan een nieuw mount point onder ${rootmnt}. We doen dit met “mount –bind”.

De union heeft nog steeds toegang tot de oorspronkelijke read-only en read/write mounts, zelfs nadat de root is geroteerd en init is gestart, waardoor die mount-punten buiten het nieuwe root-bestandssysteem vallen. Ik ga ervan uit dat aufs deze mappen tijdens het mount-moment opent en dat de bestandssystemen toegankelijk blijven zolang processen open bestandsmogelijkheden hebben. De kernel lijkt behoorlijk slim te zijn in de omgang met dit soort interessante situaties.

Om erop terug te komen, is hier het init-bottom script dat we gebruiken (scripts/init-bottom/ro_root):

#!/bin/sh

PREREQ=''

prereqs() {
  echo "$PREREQ"
}

case $1 in
prereqs)
  prereqs
  exit 0
  ;;
esac

ro_mount_point="${rootmnt%/}.ro"
rw_mount_point="${rootmnt%/}.rw"

# Create mount points for the read-only and read/write layers:
mkdir "${ro_mount_point}" "${rw_mount_point}"

# Move the already-mounted root filesystem to the ro mount point:
mount --move "${rootmnt}" "${ro_mount_point}"

# Mount the read/write filesystem:
mount -t tmpfs root.rw "${rw_mount_point}"

# Mount the union:
mount -t aufs -o "dirs=${rw_mount_point}=rw:${ro_mount_point}=ro" root.union "${rootmnt}"

# Correct the permissions of /:
chmod 755 "${rootmnt}"

# Make sure the individual ro and rw mounts are accessible from within the root
# once the union is assumed as /.  This makes it possible to access the
# component filesystems individually.
mkdir "${rootmnt}/ro" "${rootmnt}/rw"
mount --bind "${ro_mount_point}" "${rootmnt}/ro"
mount --bind "${rw_mount_point}" "${rootmnt}/rw"

Herbouwen van de initramfs

De hook en init-bottom script dat we hierboven geschreven hebben kan geïnstalleerd worden in de volgende locaties: 

  • /etc/initramfs-tools/hooks/ro_root.
  • /etc/initramfs-tools/scripts/init-bottom/ro_root.

Ze moeten beide de execute-permissie ingesteld hebben 

Na het kopiëren van de bestanden op deze locaties, regenereer je jouw initramfs met Update-initramfs:

update-initramfs -u

De –u switch vertelt update-initramfs om de initramfs voor de meest recente kernel op het systeem bij te werken. Ik neem aan dat dit de kernel is die je gebruikt. Voor de meeste embedded of andere single-purpose machines is meestal slechts één kernel geïnstalleerd.

Booting

Het systeem zou moeten opstarten zoals het is zonder de wijzigingen die we hebben aangebracht. Echter, zodra het opstarten is voltooid, kunt je bevestigen dat:

 

  • /ro bevat het read-only base bestandssysteem.
  • /rw bevat de read/write laag en heeft meestal een aantal nieuwe bestanden in de volgende boot (/var/run, etc.).
  • Als je een bestand creëert en dan reboot, zal het bestand weg zijn.

Natuurlijk heeft een systeem als dit een paar kanttekeningen:

  • De inhoud van /etc/mtab is waarschijnlijk niet correct, dus de output van het mount commando mist waarschijnlijk wat informatie. Er zijn stappen die we kunnen nemen om /etc/mtab te corrigeren, maar ik zal hier niet uitgebreid op ingaan.
  • Er wordt geen runtime-status bewaard. Vergeet dit niet en sla een bestand op, in de verwachting dat het er na een reboot zal zijn!
  • Subtiele semantische verschillen tussen aufs, tmpfs en traditionele bestandssystemen kunnen bij sommige toepassingen problemen veroorzaken. De meeste toepassingen zullen dit niet merken, maar toepassingen die meer geavanceerde functies van het bestandssysteem gebruiken of afhankelijk zijn van details van de implementatie van het bestandssysteem, kunnen fouten tegenkomen of, erger nog, subtiel falen. Ik geloof dat de meeste van dit soort problemen nu tot het verleden behoren, maar als je merkt dat je mysterieuze fouten tegenkomt, houd daar dan rekening mee.

Dit soort systeemaanpassing demonstreert echt de kracht en flexibiliteit van de configuratie-infrastructuur van initramfs-tools. Deze architecturale stijl is gebruikelijk in Debian en Ubuntu, waardoor deze distributies ideale keuzes zijn voor embedded en toegepaste computerprojecten.

Ik hoop dat dit behulpzaam is geweest. Zoals altijd, kijk ik uit naar reacties envragen.

Verbeteringen

[Sectie toegevoegd 2009-02-23, geüpdatet 2009-04-28.]

Het volgende bewerkte script bevat enkele verbeteringen die hebben geholpen bij enkele problemen waar gebruikers tegenaan liepen:

  • Opstarten met normaal gemounte write/read root-bestandssysteem wanneer de gebruiker een enkele gebruikersmodus aanvraagt (ook wel herstelmodus genoemd).
  • Voorkom dat /etc/init.d/checkroot.sh wordt uitgevoerd tijdens het opstarten van het read-only systeem.
  • Gebruik mount –move in plaats van mount –bind bij het verplaatsen van de ro en rw mount-punten in de nieuwe root
#!/bin/sh

PREREQ=''

prereqs() {
  echo "$PREREQ"
}

case $1 in
prereqs)
  prereqs
  exit 0
  ;;
esac

# Boot normally when the user selects single user mode.
if grep single /proc/cmdline >/dev/null; then
  exit 0
fi

ro_mount_point="${rootmnt%/}.ro"
rw_mount_point="${rootmnt%/}.rw"

# Create mount points for the read-only and read/write layers:
mkdir "${ro_mount_point}" "${rw_mount_point}"

# Move the already-mounted root filesystem to the ro mount point:
mount --move "${rootmnt}" "${ro_mount_point}"

# Mount the read/write filesystem:
mount -t tmpfs root.rw "${rw_mount_point}"

# Mount the union:
mount -t aufs -o "dirs=${rw_mount_point}=rw:${ro_mount_point}=ro" root.union "${rootmnt}"

# Correct the permissions of /:
chmod 755 "${rootmnt}"

# Make sure the individual ro and rw mounts are accessible from within the root
# once the union is assumed as /.  This makes it possible to access the
# component filesystems individually.
mkdir "${rootmnt}/ro" "${rootmnt}/rw"
mount --move "${ro_mount_point}" "${rootmnt}/ro"
mount --move "${rw_mount_point}" "${rootmnt}/rw"

# Make sure checkroot.sh doesn't run.  It might fail or erroneously remount /.
rm -f "${rootmnt}/etc/rcS.d"/S[0-9][0-9]checkroot.sh

Delen

About the Author: Forest Bond

Forest had been the lead software developer at Logic Supply since April 2005 before starting his own software company, RapidRollout in 2009. He occasionally peeks back in with us from time to time, but dedicates his energy to developing open source software platforms. We maintain his posts here, but he no longer writes for our blog. To contact him, you can visit RapidRollout.
Volg OnLogic op LinkedIn

66s Reacties

  1. Julien Rhodes januari 28, 2009 at 7:35 pm

    Hey, nice post! I was recently reading https://help.ubuntu.com/community/aufsRootFileSystemOnUsbFlash which discusses a very similar procedure.

    I just put together a neat setup which mounts a readonly nfs mount but is a fully functional and locally writable – but i had to change one line in your init-bottom script. The mount line for me reads:
    mount -t aufs -o “br:${rw_mount_point}=rw:${ro_mount_point}=ro” aufs /root

  2. Philip februari 20, 2009 at 1:07 pm

    Clear, elegant, attractive idea. This could be nice on my netbook, but I’d feel more confident about trying it if I knew three more things. They’re all related.
    1. Precisely which boot files will this procedure alter?
    2. How can I save and restore my working boot setup in case something goes wrong while trying to build this one?
    3. Some day I may want to permanently upgrade a package on my read-only system using standard Debian/Ubuntu tools. What’s the easy way to do this? (Can I make a boot-time selection between a writable-root installation and the setup described here? Answers to questions 1-2 should make this easy.)

    Thanks for the nice writeup.

  3. Forest februari 20, 2009 at 1:50 pm

    Hi Philip,

    The added files affect the contents of generated initramfs images. These sit in /boot, usually.

    update-initramfs makes a backup before writing a new image, but you’ll lose your known-good image if you run update-initramfs twice. For this reason, you might want to make a backup like this:

    sudo cp -a /boot/initrd.img-$(uname -r) /boot/initrd-img-$(uname -r).old
    

    update-initramfs uses a .bak extension, so using .old ensures that update-initramfs won’t overwrite our backup.

    As long as you have GRUB set up to provide a boot menu with editing capabilities, you can use that to boot with your backup whenever you’d like. Just modify the initrd field and add “.old” to the end of the existing entry.

    You probably want to confirm that your GRUB setup allows editing at boot time before beginning the initramfs customization process. Generally speaking, you’ll want to make sure that /boot/grub/menu.lst has a timeout value greater than 0 (or no timeout at all).

    Now, if you want to occasionally be able to make permanent changes to the underlying filesystem, I’d suggest modifying the script such that the system boots normally (with no union) when you select recovery mode from the GRUB menu. Just modify the script by putting this after the case statement:

    if grep single /proc/cmdline >/dev/null; then
      exit 0
    fi
    

    When entering single user mode (recovery mode), the root filesystem will be left mounted read/write. You can log in as root and make permanent changes to the system.

    Hope this helps.

    -Forest

  4. Philip februari 22, 2009 at 2:02 am

    Very informative. Thank you.

  5. Philip februari 22, 2009 at 3:51 am

    I tried this, and it almost worked. I’m glad I made a backup first, though. I’m using Ubuntu 8.10 on an Acer Aspire One netbook. The kernel is 2.6.27-12-generic. With the suggested scripts installed, the system works as expected when the device boots on battery power and fails to boot when the AC adapter is plugged in. Interesting! The boot problems usually start like this:

    * Checking root file system…
    fsck 1.41.3 (12-Oct-2008)
    fsck.ext2: No such device or address while trying to open /lib/init/rw/rootdev
    Possibly non-existent or swap device?
    fsck died with exit status 8

    When the laptop boots on battery power, the init process chooses to skip the fsck step. Booting then proceeds normally, and everything I have tried seems to work. (I have not tested it extensively.)

    Comments are welcome. I’m reluctant to turn this comment service into a support thread, though. Is there a more appropriate place to discuss these issues? (Or should I just go away?) Tks.

  6. V. Schneider februari 23, 2009 at 6:11 am

    Wow, what a lot of work. A simple USB flash drive system with a conventional linux file system on it really does the job. Even if it burns out once in six months, and I think the burnout interval is much longer than that, using it like a hard drive is so simple it makes no sense to go to all that trouble.

    I am writing this from firefox 3.06 running on a 2GB usb flash drive, conventional linux file system.

    (And, the flash drive has a “dual boot” 32-64 bit feature, depending on whether it is running on my 32-bit laptop (external power supply) or my 945GC MB underpowered intel dual processor.

  7. V. Schneider februari 23, 2009 at 6:59 am

    Here is the culprit Linux system that will turn your usb flash into a hard drive file system.

    http://www.tux.org/pub/people/kent-robotti/looplinux/rip/

    You download the “bootable iso” image, around 90 megabytes, burn it to a CD, boot it up as a live system, _mount_ the CD, go to the /boot directory on the CD, and run the mkextlin.sh script for, say, /dev/sdb, which is your flash drive.

    It is a “live” system, residing in memory when in CD mode, but mkextlin.sh can even install onto a conventional hard drive, /dev/sda or /dev/hda, as long as you don’t want any other system on that drive.

    The system can be extended by downloading compatible packages from other systems.

  8. Forest februari 23, 2009 at 10:10 am

    Philip:

    Sorry to hear you had problems. I tested on Ubuntu 8.04. Looks like Ubuntu 8.10 has slight differences with how it identifies the root device for the purpose of running fsck. I’ll have a look and let you know what I find.

    V. Schneider:

    I don’t think that copying two files and running update-initramfs is really that much work.

    Regardless, a read-only system has useful qualities beyond reduced writes to disk. For instance, there is a security benefit associated with prevention of permanent changes to the system.

    Further, using a USB flash drive might suit your particular situation well, but it would likely be inconvenient with a mobile device and insecure with a publicly-deployed system.

  9. Forest februari 23, 2009 at 11:44 am

    Philip:

    I’ve looked into this a little more closely.

    I didn’t run into any problems because my /etc/fstab was empty (the system I’m testing with is on a disk image and was not created using the standard installer).

    /etc/init.d/checkroot.sh parses /etc/fstab to find the root device and then compares to see if it matches with the device that appears to be mounted at /. This causes problems for us, of course. If / is not listed in the fstab, checkroot.sh doesn’t bother checking anything. However, it does remount /, which seems to work fine despite the fact that / is a unionfs mount.

    The easiest way to deal with this is probably to add the following to the end of the script:

    touch "${rootmnt}/fastboot"
    

    checkroot.sh will not check the root filesystem if /fastboot exists.

    Alternatively, you could add this to the script:

    rm -f "${rootmnt}/etc/rcS.d"/S[0-9][0-9]checkroot.sh
    

    This would prevent the checkroot.sh script from running at all.

    I’ll update the post to include this modification, as well as the recovery mode modification mentioned above.

  10. Forest februari 23, 2009 at 12:44 pm

    Note: I corrected a few bugs in the script:

    • The script called chmod with / as argument instead of “${rootmnt}”.
    • The script called rm with /etc/rcS.d/S[0-9][0-9]checkroot.sh as argument instead of “${rootmnt}/etc/rcS.d”/S[0-9][0-9]checkroot.sh.
  11. Will Godfrey februari 23, 2009 at 7:22 pm

    Just wondered if this would work on a vanilla debian lenny install.

    Would any other changes be needed?

  12. Forest februari 24, 2009 at 9:58 am

    Will:

    I can’t think of any reason it wouldn’t work. Both Debian and Ubuntu use initramfs-tools to manage the initramfs image by default, as far as I am aware. I haven’t tested it, though.

    Be sure to make a backup, and let us know how things go.

  13. Luigi maart 9, 2009 at 12:00 pm

    I tried this guide but it don’t work with ubuntu 8.10, can you help me to serolv my problem?

  14. Forest maart 9, 2009 at 1:55 pm

    Hi Luigi,

    What problems are you having?

    Thanks,
    Forest

  15. Dub Dublin maart 10, 2009 at 3:20 pm

    Two words: Puppy Linux. If you want all this goodness (which can be pretty complex) already sorted out for you in a lightweight distro that will boot and behave correctly (from CD, CF/SD/etc. flashcards, HDD, or USB flashdrives), try Puppy. Booting RO is difficult, but booting from flash correctly is even harder, and Barry and the other Puppy devs have done a great job of sorting it out: http://puppylinux.com

    This is the only Linux distro I know of that actually treats flash in a way that’s suitable for long-term embedded use. If you’ve got it configured correctly (which can happen nearly automagically in some cases) writes get gathered and written only periodically to avoid using up your flash memory’s precious write cycles (unless you’re smart enough to use an Intel SSD, in which case their brilliant embedded controller makes such gymnastics unnecessary.)

  16. Luigi maart 11, 2009 at 12:54 pm

    when try to:
    mount -t aufs -o “dirs=${rw_mount_point}=rw:${ro_mount_point}=ro” root.union “${rootmnt}”

    return the error:
    mount: Mounting root.union on /root failed: No such device

  17. Luigi maart 12, 2009 at 4:39 am

    resolved
    I recompiled the kernel and there was no support for aufs
    with the generic kernel works fine

  18. Steve maart 14, 2009 at 9:05 pm

    Hi,

    Thanks for the great article. However, I applied the changes and my microwave oven stopped working.

    Any suggestions?? I can’t cook anything now.

    Thanks,
    Steve

  19. Forest maart 17, 2009 at 3:10 pm

    @Steve

    Sorry to hear about your troubles. Please be advised, this change should not be applied to 64-bit microwave ovens. It will only work on 32-bit models.

    You should unplug your microwave and leave it unplugged for at least 10 minutes. That should resolve the issue. Contact the manufacturer if you require further assistance.

    -Forest

  20. Craig Rae maart 20, 2009 at 4:26 pm

    Handy info, that.

    Vaguely related question time – has anyone tried out the MSI Atom boards that became available recently (MS-9830 and/or MS-9832) and tried chucking a Mini PCI-E flash disk at ‘em (such as Crucial’s N100). I say Crucial as I’d trust them long before some of the other brands I see out there, and they do a short-length card for various Netbooks that looks like it’ll fit.

    I’m itching to give this a go, assuming I can ever lay my hands on one…32GB (or 64GB) of space for a very reasonable price, and presumably they do pretty decent wear levelling if the Netbook crowd run with these mounted read/write all the time.

    On a not-really-related note, has anyone else managed to get all of the RS232 ports going on either of the MSI Atoms under Linux? I have ttyS0 and 1 running with no problems, but I can only get 2 and 3 going under IRQ 0 (i.e. software polled) and 4 and 5 are a wash right now.

  21. Mark april 28, 2009 at 8:14 pm

    Thanks for your work on the script. I’m currently using it on an ALIX embedded computer as a router/firewall. I made one small change.

    I changed:

    mount –bind “${ro_mount_point}” “${rootmnt}/ro”
    mount –bind “${rw_mount_point}” “${rootmnt}/rw”

    to

    mount –move “${ro_mount_point}” “${rootmnt}/ro”
    mount –move “${rw_mount_point}” “${rootmnt}/rw”

    I found this prevents having extra entries in mtab and prevents errors from showing up in df.

  22. Forest april 28, 2009 at 8:53 pm

    Hi Mark,

    That’s definitely the right way to do it. I’m not sure why I didn’t do it that way in the first place.

    I’ll include your change here in the improved version.

    Thanks for posting.

    -Forest

  23. Demian mei 4, 2009 at 2:39 pm

    Another distribution that is designed from the ground up to run from flash and live mostly in ram is Voyage Linux, http://linux.voyage.hk/ It can be extended easily with applications, has a very small footprint and was designed for appliances more than desktop computing. It has a simple way to shift to writable, add stuff and switch back to read only.

  24. Mathias mei 7, 2009 at 4:41 pm

    That is just great! I applied hook and script to a debian lenny system, and after only 15 minutes work, everything was running as expected. Never thought this kind of task could ever be that simple.

    Thanks a lot!!

  25. Chris mei 12, 2009 at 3:33 pm

    Hi Forest,

    I’d like to get this solution working since I’m running Ubuntu off of a CF card. Is there any reason why it wouldn’t work with Ubuntu 9.04 (UNR)? I tried it out, but when I get to the login screen, the keyboard doesn’t work.

  26. Chris mei 12, 2009 at 4:02 pm

    Me again. I almost got it working by switching from aufs to unionfs, but now for some reason, I can’t connect to my wireless network. Any ideas?

  27. Chris mei 12, 2009 at 8:02 pm

    Sorry for spamming, feel free to delete my comments. I’ve fixed my problem. Here’s what fixed it: http://ubuntuforums.org/showthread.php?t=1134892#postcount7138705

    I’m not really sure why using your script would cause that problem to emerge.

  28. TK mei 16, 2009 at 3:12 pm

    Anyone want to see the same thing for Fedora or CentOS 5.x? I’ve done several read-only systems from scratch with those OSs. I could probably also stand to have someone improve my method, I know I’ve got some quirks in it.

  29. Jack mei 18, 2009 at 12:43 am

    This tutorial is excellent … very nice explanation of what we’re doing and why.

    A couple of things I found:

    1. I didn’t need a hook at all. I added unionfs and squashfs to /etc/initramfs-tools/modules and that added the modules to initrd for me. Also didn’t need to add chmod, chmod must already come with busybox.

    2. when initially debugging i found it helpful to add “break=bottom” to the kernel cmd line to stop the startup temporarily before the script so I could poke around and see what files/directories/environment variables are what.

    Again, a really really good write-up.

  30. Penpo juni 27, 2009 at 6:29 pm

    Using Debian I get the same error as “Luigi”:
    “mount: Mounting root.union on /root failed: No such device”
    Which he resolved by
    “I recompiled the kernel and there was no support for aufs
    with the generic kernel works fine”

    I haven’t managed to rebuild the kernel with aufs support, any pointers as to where to start?

  31. Penpo juni 28, 2009 at 6:43 pm

    apt-get install aufs-modules-2.6-amd64
    fixed it

    Thanks for an excellent guide!

  32. RawShark juli 27, 2009 at 12:01 pm

    Worked perfectly for me! Going to blog this and use it to roll out 6 full Ubuntu PCs in a public area.

  33. Penpo juli 28, 2009 at 1:28 pm

    Two thoughts.
    1. The system I did this one used a separate partition as swap, this partition resides on the flash device – not ideal I suppose (mainly since swap is used before the ram runs out).
    Possible solutions(?)
    * Turn off swap. I’ve read that that isn’t recommended, not sure of the reason though – theoretically that solution appeals to me.
    * Use a file or ramdrive as swap (seems like an ugly solution though, and won’t allow for much swap anyway – although after reading on the subject it might be sensible).
    * Echo 0 into /proc/sys/vm/swappiness, I don’t know what that actually results in so I don’t know whether it is sensible in this scenario.

    Basically I use the read-only solution on a server that acts as a router and file-server (mainly for backup and samba-storage for semi-large files). Unless an application leaks a lot of memory I don’t see how the 2 GB of ram would run out on this non-X machine.
    It’s often said that turning off swap will crash the OS if ram runs out, but won’t swap just postpone it?

    That said I’ve barely seen any traffic (iostat) to the swap-partition (then again I’m just experimenting with it so far), but since the machine will be out of my reach when it is deployed it would be quite annoying if the flash device was worn out.

    2. Wouldn’t it be possible to mount the flash-device and do something like:
    cp /rw/* /mnt/flash/ -ur to update all the files that have been changed in case you did some changes that you wanted to store permanently – without rebooting (the solutions to make permanent changes I’ve read about so far doesn’t really work that well to do remotely).

    Also, what decides how large the tmpfs should be?
    On my 2 GB system it takes 1004 MB but I’ve yet to see where that spaces comes from as ‘top’ etc. doesn’t seem to take into account that 1004 MB of the ram is locked away(?).

  34. YAM december 18, 2009 at 7:04 am

    I’ve read the articles carefully, and
    1. started from backing up kernel img
    2. edit menu.lst
    3. prepare 2 scripts
    4. reboot
    and it seems working very fine under kubuntu9.04 64 bit.
    log files are visible about only current session.
    i hope this usb os works forever!

    Thanks a lot.

  35. Confluence: Server Management januari 19, 2010 at 3:57 pm

    Read only root filesystem…

    The following references may be useful:…

  36. […] your linuxrc file (if you don’t know what this is, you’ll want to read the article from logicsupply) that mount your filesystem (at /mnt/root, for example) with something like […]

  37. Chris mei 4, 2010 at 3:44 am

    Very very very good article – great quality of this post!

    Anybody else having trouble starting CUPS on the read-only side? It starts and works perfectly on the backend side, but when I run /etc/init.d/cups start in read-only mode I get the following:
    “* Starting Common Unix Printing System: cupsd
    /usr/svin/cupsd: error while loading shared libraries: libcupsmime.so.1: cannot open shared object file: No such file or directory ”

    Any ideas?

  38. Chris mei 6, 2010 at 4:44 am

    “The best approach for
    dealing with this common use case is to have a tmpfs read/write layer and then
    mount some writable media on an arbitrary mount point like /var/local/data (for
    example).”

    Any commands on this and where to put them?

    Thanks!

  39. Forest mei 6, 2010 at 8:57 am

    Chris,

    You should be able to add boot-time mounts to your fstab file like usual. The following link might be helpful:

    http://www.tuxfiles.org/linuxhelp/fstab.html

    -Forest

  40. Forest mei 6, 2010 at 8:59 am

    Note that you must make changes to the fstab file on the actual on-disk filesystem (not the one in the union filesystem) so that the changes are permanent.

  41. Jon juni 7, 2010 at 2:42 pm

    Great post! However, what if i’m using a build that doesn’t utilize initramfs, such as Red Hat?

  42. rxd september 11, 2010 at 6:38 am

    I have done it by modifying the casper script inside initrd.lz to get read-only system so your rw layer is visible on the system. One good advantage of having this system is you can now merge squashfs file to your root at real time without rebooting the system. Prior to apt-get of any application make a copy of what you have on the /rw, then apt-get any application you want then generate the mksquashfs -ef excluded-files. Once you have say the apache2.squashfs now your next reboot you can just mount -o remount,append:/apache2 /.

  43. Andrew september 14, 2010 at 6:00 am

    Great article.

    However I’m having a problem when certain processes get denied access to files now that I’ve implemented aufs.

    Specifically when running “ifup eth0” I get an error from dhclient3 reporting it cannot find libc.so – but it does exists in the location returned from ldd.

    If I tail dmesg the kernel reports something along the lines:
    denided mask =’r’ operation=’open’ /ro/etc/ld.so.cache
    denided mask =’r’ operation=’open’ /ro/lib/libc.2.11.1.so

    The network interfaces worked perfectly before. Do you have any suggestions?

  44. Andrew september 16, 2010 at 3:44 pm

    Nm – disabling apparmor (by appending apparmor=0 to the grub conf) did the trick.

  45. Purusothaman september 23, 2010 at 1:32 pm

    Good article,

    I have tried and i was able to successfully make the rootfs as read-only using unionfs.But i have following two issues:
    1.Unable to unmount the unionfs and mounted partitions during reboot using “umount -a” command(device or resorce busy).
    2.Creation of the file in the writable layer(rw) is got reflected in read-only filesystem(ro).

    I have used a seperate partition of my hard disk to mount the writable layer instead of using tmpfs.

    Any suggestions for the above issues?

  46. Rick S oktober 13, 2010 at 6:17 pm

    You wrote: “The contents of /etc/mtab are likely not correct, so the output of the mount command is probably missing some information. There are steps we can take to correct /etc/mtab, but I won’t cover those in detail here.”

    Can you point me int he right direction for getting the ‘mount’ command to list properly?

  47. abakan november 23, 2010 at 6:41 am

    In Ubuntu 10.04 it`s scripts work, but In Ubuntu 10.10 it is not corectly working.

    Touble is:
    Some applications doesn`t run at all. I try to run wine, Gogole Chrome but nothing doesn’t happen.

    Any ideas?

  48. abakan november 23, 2010 at 3:23 pm

    When I run wine in terminal:
    “wineserver: mkdir /tmp/.wine-1000 : Operation not permitted”

  49. Diogo Resende december 23, 2010 at 9:26 am

    Some notes:
    – don’t use a journaling system (use ext2, xfs won’t work);
    – apparmor might block some services (I had to change usr.sbin.mysqld profile to be able to access root.ro and root.rw)

  50. Nicola december 27, 2010 at 8:25 am

    how? with ubuntu 10.10?
    Help!

  51. Matt Anderson januari 28, 2011 at 10:26 am

    This worked great for me on Ubuntu 10.04.01 LTS. Thanks for the great write-up.

    The only gotcha I ran into was the single user mode trick did not work for me. My system hung at a blank screen and was non-responsive on the network. I didn’t test this before making the RO root changes, so I’m not sure if this was an existing problem with the computer or not.

    Instead what I’ve been doing is once booted:
    # mount -o remount,ro /ro
    # cd /ro
    # chroot .

    That lets me edit my system in a persistent way. Once I’m done I simply:

    # exit (this gets me out of the chroot)
    # cd /
    # mount -o remount,ro /ro

    Usually I’ll throw a `sync` in there for good measure :)

  52. Francesco februari 7, 2011 at 8:02 am

    everything seems work, I’ve also added an item to grub, to start linux in normal mode, but I’ve encountered a bug: “Bug#607879: System hangs up with mmap.c:873”. Do you have any suggestion?
    Thanks again for your work

  53. Scott maart 26, 2011 at 11:25 am

    As an FYI, this guide is really superb. I’m using it with a Ubuntu 10.04 LTS server, booted off of a compact flash, in an embedded server application.

    One gajillion thanks!

  54. sparsile maart 29, 2011 at 2:35 pm

    TK (or anyone else!), if you’re still listening, I would very much appreciate a tutorial on building a RO linux system for CentOS 5.

  55. Johnny oktober 17, 2011 at 12:24 pm

    This works except for one found one bug in Ubuntu 10.04:

    dhclient breaks.
    this is kind of a weird error. It reports that the libraries aren’t there, but they are.

    #dhclient: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
    # which dhclient
    /sbin/dhclient
    # ldd /sbin/dhclient
    linux-vdso.so.1 => (0x00007fffa8fff000)
    libc.so.6 => /lib/libc.so.6 (0x00007f4a3b820000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4a3be1f000)
    # ls -al /lib | grep libc.so.6
    lrwxrwxrwx 1 root root 14 2011-10-10 20:05 libc.so.6 -> libc-2.11.1.so
    root@Archives:/lib# ls -al /lib | grep libc-2.11.1.so
    -rwxr-xr-x 1 root root 1572232 2011-01-21 14:23 libc-2.11.1.so
    lrwxrwxrwx 1 root root 14 2011-10-10 20:05 libc.so.6 -> libc-2.11.1.so

  56. FBP oktober 17, 2011 at 3:04 pm

    I have a Seagate Dockstar (arm5 processor, 128 MB RAM, boots Debian squeeze from a usb flash drive). I have done this “Read-Only Linux System” procedure on a more “normal” computer (Intel Atom, Debian squeeze), and it works fine. But it fails on the Dockstar. It boots, it just isn’t read-only. I get the following in dmesg:

    [ 12.960395] aufs: module is from the staging directory, the quality is unknown, you have been warned.
    [ 12.993986] aufs 2-standalone.tree-32-20100125
    [ 13.003956] aufs test_add:218:mount[124]: unsupported filesystem, /root.ro (rootfs)

    I end up with no /rw or /ro mount points. Ideas?

  57. Setting up a read-only Debian system? oktober 25, 2011 at 11:51 am

    […] a NAS. I have been trying to make the boot flash drive read-only using the method described here: http://www.logicsupply.com/blog/2009…-linux-system/ The method entails moving the root filesystem to an aufs filesystem so that the boot drive is […]

  58. Forest Bond oktober 29, 2011 at 2:19 pm

    Hi everyone,

    I’m no longer at Logic Supply, but if people still have questions I can do my best to get them answered. I’ve created a new thread for this purpose on the RapidRollout forums:

    Configuring Ubuntu for read-only storage

    Go ahead and post your questions there and I’ll see what I can do to help!

    -Forest

  59. W3 Network Solutions augustus 17, 2012 at 11:02 am

    Hey There. I found your blog the usage of msn. This is a really neatly written article. I will be sure to bookmark it and come back to read more of your useful information. Thanks for the post. I’ll definitely return.

  60. OZ juli 6, 2015 at 11:45 am

    Thanks for the How-To.

    I’ve done this on [L]ubuntu 14.04.

    Now – as it was supposed, all changes and/or new files are flushed on a reboot.
    That’s good.

    On the negative side:
    1) auto-mounting an USB Flash broke: reports that a device “/mount/%username%/%devicename%” is invalid;
    2) DHCP also broke – I have to assign settings manually.

    I was looking for something as easy as windows’ Enhanced Write Filter which has a manager program (ewfmgr.exe) – to be able to arbitrarily apply some changes (after OS or software update, etc). It is not clear how to do it with this environment.

    Please comment.
    Thank you in advance.

  61. OZ juli 6, 2015 at 11:48 am

    correction – the error message is this:
    ‘The specified directory “/media/%username%/%volumename%” is not valid’.

  62. Darek Fanton juli 7, 2015 at 11:35 am

    Hi OZ, thank you for your comment. While Forest, the author of this post, is no longer with Logic Supply, he has a thread specifically designed for answering questions related to this tutorial here.

  63. trueriver januari 3, 2017 at 2:10 am

    Just to say three things.
    1. Used recently in conjunction with network booting. I used your hook and a variation of your script to boot a read only system over NFS, and all the writable stuff kept local. Works. OS was Debian Jessie.
    2. I personally do not like the top level directories /ro and /rw, and arguably they break the FHS. My version of your script puts them in /root/ro and /root/rw where they “belong” to the root user. Just a matter of changing the mount moves near the end
    3. As well as testing for ‘single’, I also test for the string no-overlay, and exit on that. This gives me the chance to run a normal system in read-write mode.
    Finally, thank you very much for this — there are several alternatives o the web, and I read maybe half a dozen of them. Yours seemed easiest to understand (ie easiest for me to maintain). Thank you for preparing my 2016 Christmas present so far in advance ;)

  64. Darek Fanton januari 4, 2017 at 11:48 am

    Thank you for the kind words Trueriver, we’re very happy to hear that you found the tutorial helpful. Thank you as well for sharing your adjustments to the script, hopefully others will find them useful.

  65. ganesh juni 8, 2017 at 10:03 am

    mount -o remount rw /
    not wotking remount temporary for writing files

  66. MG september 29, 2018 at 2:18 pm

    Hello,

    I was wondering about making this FIlesystem with a writable layer that presists after power outage. I understand that you use tmpfs to mimic the behavoir of that of RAM (i.e. retain info till power is out) but I assume that since you are using aufs at the top root.union to mount eveything else into one view I would get a system that can retain some newly created files.

    1. Why is this assumption not correct? (I have tested everytime I create new files/dir after boot they are gone) And what is the point of doing mount aufs in the created script?
    2. Does this mean that my files in/rw directory that are being written into will lose at that info as soon as I boot? like log files in /var/log?
    3. How do I alter this implementation to have the writable layer on top of ro fs be of unionfs or aufs (the type that would retain the newly created info after boot time in certain locations for application data monitoring/logging?

Leave A Comment

DELEN

Heb je een project? Neem contact op