1 AUTHOR: Archaic <archaic@remove-this.indy.rr.com>
2 AUTHOR: Oliver Brakmann <obrakmann@gmx.net>
6 LICENSE: GNU Free Documentation License http://www.gnu.org/licenses/fdl.txt
8 SYNOPSIS: How to create a read-only root file system
10 DESCRIPTION: A read-only root file system has many advantages over read-write
11 when the computer unexpectedly powers off. However, some parts of the file
12 system still need read-write access. This hint will show how to split the file
13 system into multiple partitions to achieve data stability.
15 PREREQUISITES: The kernel must be compiled with tmpfs (virtual memory file
18 HINT: Warning! Serious ruin of your system may occur if you mistype something.
19 I offer no warranty or guarantee that this will work and your data will be
20 safe. It is recommended that you backup (and test the backup) all data before
21 beginning. If you use tar, don't forget the -p switch. I prefer to boot with a
22 boot CD and then manipulate the hard drive ensuring all needed data is in a
23 static state. Also, you cannot read just the tabbed commands and succeed. You
24 must read the paragraphs as well.
26 This hint assumes reiser file systems. I chose reiser for its stability and
27 journaling capabilities. Ext2/3 file systems will work as well. For you uptime
28 junkies, you will not like the many reboots in this hint, but that's the only
29 true way to test the boot process. Now let's begin...
31 First, we need to partition according to our needs. The bare minimum to run
32 a read-only rootfs is / and /var. You may want /tmp as well, but this hint
33 assumes /tmp is on tmpfs. Optionally, /usr can be separated, but unless you are
34 sharing /usr or want it to be read-write, then it can stay on /. Additionally,
35 most will want a partition for /home and possibly /root. Partition size is very
36 subjective so I will not cover it here. This hint assumes you have the ability
37 to add at least 1 extra partition for /var. Here is my partitioning scheme:
40 hda2 /var 900Mb reiserfs
41 hda3 /home 3.1GB reiserfs
43 Now it's time to start splitting the file systems. You have two choices
44 currently; static dev or devfs (when the 2.6 series kernel stabilizes, devfs
45 will be deprecated and a new virtual /dev will be available). While devfs has
46 many potentially good qualities, I do not like the workarounds needed, the
47 lessened stability, and the soon to be extinct nature of it. If you want devfs
48 then read the devfs and/or devfsd hints and get it working on your system
49 first. Then continue with this hint, skipping the "Dev" section.
53 Here, we make the transition from a hard drive-based /dev tree to a virtual
54 one. Start by making sure /dev/pts and /dev/shm are _not_ mounted. Also switch
55 to single user mode and make sure all daemons are shut off. If your boot
56 scripts and symlinks are in order you can do this by simply typing 'telinit 1'.
57 We also want to copy the device files and directories to a new location.
65 Next, remove all device files and directories from /dev except console, then
66 mount a tmpfs on /dev and copy the original device files to the new /dev.
68 #mount dev /dev -t tmpfs
71 Verify that everything is in order by catting /proc/mounts or using df to
72 see if a tmpfs is mounted on /dev, and ls /dev to make sure the files are
75 Now it's time to make /dev mount at boot time. Since some of the device
76 files are needed by init, we need to mount /dev before init runs. Create the
79 #cat >/sbin/tmpdev <<EOF
81 mount -n dev /dev -t tmpfs
85 #chmod 0700 /sbin/tmpdev
87 To make the kernel run this script, you have to change your boot loader's
88 config file by adding init=/sbin/tmpdev.
90 Next, we modify the mountfs boot script so that /dev gets written properly
91 to mtab. We do this by adding mount -f /dev to the script. I will show the
92 relevant part of the boot script with the change being underlined like this.
94 echo "Recording existing mounts in /etc/mtab..."
96 mount -f / && mount -f /proc && mount -f /dev
99 Lastly, we modify fstab to include the mount. Though not strictly necessary
100 (as /dev is mounted before fstab is read), it's included for a sense of
101 completeness. Note the 'noauto' option. That is to keep the mountfs script from
102 trying to mount it again.
104 #cat >>/etc/fstab <<EOF
105 dev /dev tmpfs defaults,noauto 0 0
108 Now it's time to test it out by rebooting your computer. Use /proc/mounts to
109 verify /dev is mounted. If you use /dev/pts, make sure it is mounted as well.
110 If all is well, it's time to separate var.
114 Here we will separate /var from /. Again, we need to make sure that no
115 daemons are running. This process is pretty much the same as the Dev section.
116 We will start with mounting the soon-to-be var partition on a temporary mount
117 point and copying all the files in /var to this mount point, then unmounting
118 and remounting the new partition over /var. Don't forget to substitute
119 partition numbers for your setup.
123 #mount /dev/hda2 /mnt
126 #mount /dev/hda2 /var
128 Now check to make sure var is properly mounted and contains the directory
129 structure it's supposed to have. Cat /proc/mounts instead of using mtab for
130 maximum reliability. If it's all good, edit fstab to mount /var upon reboot.
132 #cat >>/etc/fstab <<EOF
133 /dev/hda2 /var reiserfs defaults 0 0
136 Now it's time to test it out by rebooting your computer. Use /proc/mounts to
137 verify /var is mounted. If all is well, we can delete the stuff in the original
138 /var. You might want to md5sum the stuff first, to be extra safe.
147 Follow the same steps as in the "Var" section. Telinit'ing to runlevel 1 is
148 not necessary unless by some weird chance you have a daemon writing log files
153 Follow the same basic idea as in the "Dev" section copying the files in /tmp
154 to another location, then mounting tmpfs over /tmp and copying the files back.
155 Make sure to telinit to runlevel 1 in case something is using /tmp. Note: Some
156 people think /tmp should be wiped at reboot and /var/tmp should be used for
157 tmpfiles that need to last across reboots. Others vehemently object. If you are
158 the latter, get used to using /var/tmp. ;) Tmpfs is virtual.
163 #mount tmp /tmp -t tmpfs
164 #cp -a orig_tmp/* /tmp
166 Verify that everything is in order by catting /proc/mounts or using df to
167 see if a tmpfs is mounted on /tmp, and ls /tmp to make sure any files that
168 should be there are there. If it's all good, edit fstab to mount /tmp upon
171 #cat >>/etc/fstab <<EOF
172 tmp /tmp tmpfs defaults 0 0
175 Now it's time to test it out by rebooting your computer. Use /proc/mounts to
176 verify /tmp is mounted. If all is well, we can delete the orig_tmp directory
177 and the stuff still in /tmp on the root partition.
184 #telinit 3 # Or your runlevel of choice.
186 Note, there may be some hidden dirs or files that still need to be deleted.
187 If someone has a command to catch them, please email me.
191 Now it is time to make a decision. If you prefer having a writable mtab,
192 skip the "Symlink Mtab" section and read the "Writable Mtab" section. If you
193 think /proc/mounts is good enough, do the opposite. If you can't decide, search
194 the lfs-dev mailing list archives for arguments for and against each.
198 Here we delete mtab and make the link to /proc/mounts.
201 #ln -s /proc/mounts /etc/mtab
203 Next we modify the mountfs boot script to mount / read-only. Comment out the
206 echo "Remounting root file system in read-write mode..."
207 mount -n -o remount,rw /
210 Finally, we edit fstab to include the ro option for our root fs.
212 Since the kernel command line option for reiserfs is generally set to mount
213 read-write, you also must change your boot loader config file to mount / ro
216 Now it's time to test it out by rebooting your computer. Cat /etc/mtab
217 (which is now /proc/mounts) to verify everything is mounted properly. As an
218 alternative, you can just type 'mount' to get a listing. You should see
221 rootfs / rootfs rw 0 0
222 /dev/root / reiserfs ro 0 0 #<- The "ro" is what you are looking for
223 dev /dev tmpfs rw 0 0
224 proc /proc proc rw 0 0
225 devpts /dev/pts devpts rw 0 0
226 /dev/hda2 /var reiserfs rw 0 0
228 You can disregard rootfs. Some kernels show this, but it's supposed to be a
229 hidden, virtual fs that only the kernel uses.
231 If everything looks good then congratulations! You are finished. Read the
232 section "Other Concerns" to prepare for any (minor) gotcha's your new read-only
233 system may throw at you.
235 ### Writable Mtab ###
237 Note: With the exception of a few edits, the following text covering a
238 writable mtab was taken directly from the now-obsolete mtab hint written by
241 OK, so we want to have a read-only root partition, but /etc/mtab needs to be
242 writable. The simple solution is to put /etc/mtab somewhere else! I will use
243 /var/lib/misc/mtab in this hint, as that is the most logical place as I read
244 the FHS. The downside to this approach is that you have to recompile glibc,
245 util-linux and possibly other software packages. To be compatible with scripts
246 and other (broken) pieces of software, we re-create /etc/mtab as a link to our
249 Enough introduction, now we'll get our hands dirty. Start by switching to
250 runlevel 1 (single-user mode).
254 We need to unpack glibc and linuxthreads, as well as apply any patches
255 necessary per the lfs book instructions. The following instructions assume you
256 are in glibc's top directory. The sed makes newly compiled programs look for
257 the mtab file in /var/lib/misc/mtab.
259 #cp sysdeps/unix/sysv/linux/paths.h{,.orig}
260 #sed 's%/etc/mtab%/var/lib/misc/mtab%' \
261 sysdeps/unix/sysv/linux/paths.h.orig >sysdeps/unix/sysv/linux/paths.h
263 Next we will rebuild util-linux so that mount, umount and friends are aware
264 of mtab's new location. There are no patches required, just look up the
265 instructions in the LFS Book.
267 Note: Other packages you might want to rebuild are the GNU fileutils (df)
268 and other programs that might access /etc/mtab. As long as these programs do
269 not write to that file, it is not absolutely required, though. That is why we
270 will set up that symlink.
272 The next step is to move /etc/mtab to /var/lib/misc/mtab then re-create
273 /etc/mtab as a link to /var/lib/misc/mtab (for compatibility reasons).
275 #mv /etc/mtab /var/lib/misc/
276 #chmod 644 /var/lib/misc/mtab # Just to make sure
277 #ln -s ../var/lib/misc/mtab /etc/mtab
279 Now we need to create /var/lib/misc/mtab _on your root partition_. We need
280 this so that mount and umount always know what is mounted regardless of whether
281 or not /var (where the real mtab is) is mounted, otherwise file systems may not
282 get unmounted properly and disk corruption may occur. We will make this a
283 symlink to /proc/mounts so we can have dynamic information on a static
284 (read-only) root file system. We must do this by first unmounting /var.
287 #mkdir -p /var/lib/misc
288 #ln -s /proc/mounts /var/lib/misc/mtab
291 Now we have to modify the mountfs boot script. We need to comment out the
292 lines that remount / in read-write mode. Also, we need to explicitly mount /var
293 so we can clear the writable mtab and start recording the mounts. Here is what
296 # echo "Remounting root file system in read-write mode..."
297 # mount -n -o remount,rw /
300 echo "Recording existing mounts in /var/lib/misc/mtab..."
302 > /var/lib/misc/mtab &&
303 mount -f / && mount -f /proc && mount -f /dev && mount -f /var
306 While we are editing mountfs we need to modify the umount section by adding
307 the -n switch. What happens is umount sees a writable mtab (not a symlink),
308 unmounts /var, and then tries to write a lock file to /var/lib/misc. This won't
309 work due to being a read-only file system. (If it wasn't, I wonder if it
310 would/could write to /proc/mounts by way of the symlink.) Anyway, here is the
311 relevant part of the script:
313 echo "Unmounting all other currently mounted file systems..."
315 ^^ <- Note the addition of -n
317 Next, modify your /etc/fstab so that /, /proc, and /var do not get mounted
318 automatically (as they will already be mounted). The key word in the following
319 example is 'noauto'. Note that with the lfs-boot scripts, my testing shows that
320 this is not really necessary, but it makes things nice and tidy. We will also
321 add the 'ro' option for your root file system. It's not absolutely necessary as
322 the checkfs script explicitly mounts root as ro and we commented out the
323 remounting rw in the mountfs script. But if you leave it out, mount will
324 mistakenly say it is rw (/proc/mounts will say ro, though).
326 /dev/hda1 / reiserfs defaults,noauto,ro 0 0
327 /dev/hda2 /var reiserfs defaults,noauto 0 0
328 proc /proc proc defaults,noauto 0 0
330 Finally, if you are on an ext2/3 root file system (or any other that
331 initially boots up in read-only), you are ready to go. If you use reiser,
332 however, by default it initially boots in read-write. You will have to change
333 the config file of your boot loader to mount ro.
335 You can now remount root read-only since we are not changing any more files.
336 If you have not unmounted any partitions other than /var during the process,
337 all those listed in /etc/mtab should still be mounted. Check out /proc/mounts
338 and be sure that it reports the same mounted partitions as /var/lib/misc/mtab.
339 If it checks out ok, you can switch to runlevel 3 prior to rebooting. The
340 reason for this is to fire up the daemons so they will be using /var. This will
341 put the system into real-life use and may cause a problem to surface that might
342 not be detected until you reboot the next time.
344 #mount -n -o remount,ro /
347 Now it's time to test it out by rebooting your computer. Cat /proc/mounts to
348 verify everything is mounted properly. You should see something like this:
350 rootfs / rootfs rw 0 0
351 /dev/root / reiserfs ro 0 0 #<- The "ro" is what you are looking for
352 dev /dev tmpfs rw 0 0
353 proc /proc proc rw 0 0
354 devpts /dev/pts devpts rw 0 0
355 /dev/hda2 /var reiserfs rw 0 0
357 You can disregard rootfs. Some kernels show this, but it's supposed to be a
358 hidden, virtual fs that only the kernel uses. Also, make sure you compare
359 /proc/mounts with /etc/mtab (by catting mtab or typing 'mount') to make sure
360 they agree. /proc/mounts will lack some detail, but what it does have needs to
361 be the same on mtab. Make sure all mounting options are correct.
363 If everything looks good then congratulations! You are finished. Read the
364 section "Other Concerns" to prepare for any (minor) gotcha's your new read-only
365 system may throw at you.
367 ### Other Concerns ###
369 Here I list a few of caveats you will find with your new system. The main
370 problems I see are installing/uninstalling software, changing passwords, and
371 creating/removing devices (if you use the static /dev method), but there are
374 Installing New Software
375 To install something, build as usual (in /home or /var or somewhere else of
376 your choosing as long as it is writable). Keep in mind the space requirements
377 of the package while compiling. Glibc-2.5.x needed around 400MB during
378 compilation but needed much less installed. I keep /home extra large for just
379 that reason. Then when you switch to root to install, just remount root
380 read-write and install (making sure to run ldconfig if necessary). Then remount
381 back to read-only. That's a small price to pay for data security. Also, for the
382 people who think it's redundant to use reiserfs when you're just going to mount
383 read-only, I ask, "What if you lose power while installing software?" I want my
387 Initially, the easy way to change passwords is also to remount root
388 read-write, but this can be tedious if you have more than a couple of users, as
389 you will have to be present whenever they change them. I haven't yet explored
390 other options, but the simplest would seem to be symlinking passwd, shadow,
391 group, etc. to /var. This may not be so cut-and-dry however. Shadow may need
392 patching. If anyone tries the latter two, I would be interested in knowing how
393 it comes out. Also anyone using pam with shadow (if that makes any difference).
395 Creating/Removing Devices
396 This is just a reminder that you must create/remove devices in the /.dev
397 directory for the change to last across a reboot. If you don't want to reboot
398 for the changes to apply (who does?) then simply repeat the creation/removal of
399 the device in the virtual /dev as well.
403 Now that you are running a multi-partition system, you can tweak the
404 mounting options used for each file system. Here is a sample fstab to give you
405 an idea of some of the things that are possible:
407 /dev/hda1 / reiserfs ro,noauto,nodev 0 0
408 /dev/hda2 /var reiserfs noauto,nodev,noexec,nosuid 0 0
409 /dev/hda3 /home reiserfs nodev,nosuid 0 0
410 /dev/hda4 /tarballs reiserfs nodev,noexec,nosuid,users 0 0
411 dev /dev tmpfs noauto,noexec,nosuid,size=50k 0 0
412 proc /proc proc noauto 0 0
413 tmp /tmp tmpfs nodev,nosuid,size=80m,nr_inodes=20k 0 0
414 devpts /dev/pts devpts gid=4,mode=620 0 0
415 devshm /dev/shm tmpfs defaults 0 0
417 Read 'man 8 mount' to understand the options. The options for tmpfs can be
418 found in the kernel source under Documentation/filesystems/tmpfs.txt.
420 ACKNOWLEDGEMENTS: I would like to thank Richard Lightman for the initial idea
421 of mounting /dev before exec'ing init (I really hate devfs ;)) and Oliver
422 Brakmann for the mtab hint (I also hate symlinking mtab to /proc/mounts ;)). I
423 would also like to thank Oliver for allowing me to absorb his hint into mine.
424 It would not have been possible to have a complete hint without his hint.
426 Oliver Brakmann would like to give credit to Seth W. Klein for teaching him
427 through the process in the first place and further corrections and suggestions.
428 Also thanks to DJ Lucas, Jesse Tie-Ten-Quee, Richard Lightman and Wouter
429 Vanwalleghem for additional feedback.