Archive old uefi hint
[linux_from_scratch_hints.git] / readonly_rootfs.txt
blob0b9fcc47930003cfbd06312969e01d47af5f8f8d
1 AUTHOR: Archaic <archaic@remove-this.indy.rr.com>
2 AUTHOR: Oliver Brakmann <obrakmann@gmx.net> 
4 DATE: 2003-09-13
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
16 system) support.
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:
39         hda1 /     2GB   reiserfs
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.
51 ### Dev ###
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.
59         #umount /dev/shm
60         #umount /dev/pts
61         #telinit 1
62         #cd /
63         #cp -a dev .dev
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
69         #cp -a .dev/* dev/
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
73 there.
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
77 following script:
79         #cat >/sbin/tmpdev <<EOF
80         #!/bin/sh
81         mount -n dev /dev -t tmpfs
82         cp -a .dev/* /dev
83         exec /sbin/init
84         EOF
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.
93                                                                        ^^^^
94         echo "Recording existing mounts in /etc/mtab..."
95         > /etc/mtab
96         mount -f / && mount -f /proc && mount -f /dev
97                                      ^^^^^^^^^^^^^^^^
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
106         EOF
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.
112 ### 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.
121         #telinit 1
122         #cd /
123         #mount /dev/hda2 /mnt
124         #cp -a var/* /mnt
125         #umount /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
134         EOF
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.
140         #telinit 1
141         #umount -n /var
142         #rm -rf /var/*
143         #mount -n /var
145 ### Home ###
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
149 there.
151 ### Tmp ###
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.
160         #telinit 1
161         #cd /
162         #cp -a tmp orig_tmp
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
169 reboot.
171         #cat >>/etc/fstab <<EOF
172         tmp     /tmp     tmpfs     defaults     0 0
173         EOF
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.
179         #rm -rf /orig_tmp
180         #telinit 1
181         #umount /tmp
182         #rm -rf /tmp/*
183         #mount /tmp
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.
189 ### Mtab ###
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.
196 ### Symlink Mtab ###
198    Here we delete mtab and make the link to /proc/mounts.
200         #rm /etc/mtab
201         #ln -s /proc/mounts /etc/mtab
203    Next we modify the mountfs boot script to mount / read-only. Comment out the
204 following lines:
206         echo "Remounting root file system in read-write mode..."
207         mount -n -o remount,rw /
208         evaluate_retval
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
214 instead of rw.
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
219 something like this:
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
239 Oliver Brakmann.
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
247 new mtab file.
249    Enough introduction, now we'll get our hands dirty. Start by switching to
250 runlevel 1 (single-user mode).
252         #telinit 1
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.
286         #umount -n /var
287         #mkdir -p /var/lib/misc
288         #ln -s /proc/mounts /var/lib/misc/mtab
289         #mount -n /var
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
294 it should look like:
296 #               echo "Remounting root file system in read-write mode..."
297 #               mount -n -o remount,rw /
298 #               evaluate_retval
300                 echo "Recording existing mounts in /var/lib/misc/mtab..."
301                 mount -n /var &&
302                 > /var/lib/misc/mtab &&
303                 mount -f / && mount -f /proc && mount -f /dev && mount -f /var
304                 evaluate_retval
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..."
314         umount -n -a -r
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 /
345         #telinit 3
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
372 surely others.
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
384 data safe. Period.
386 Changing Passwords
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.
401 ### Added Value ###
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.
431 CHANGELOG:
432 [2003-09-13]
433  * Initial version