[systemd-devel] Safe handling of root filesystem on shutdown

Colin Guthrie gmane at colin.guthr.ie
Thu Apr 12 03:45:32 PDT 2012


'Twas brillig, and Daniel Drake at 11/04/12 17:33 did gyre and gimble:
> On Wed, Apr 11, 2012 at 9:40 AM, Lennart Poettering
> <lennart at poettering.net> wrote:
>> So on shutdown after stopping all services we execute systemd-shutdown
>> as PID 1 replacing the normal systemd process. This is useful to drop
>> all references to files on disk, so that we can remount the disk r/o
>> even on upgrades.
>>
>> systemd-shutdown is basically a single loop that tries to
>> umount/read-only mount all file systems it finds as long as this changes
>> the list of active mounts. This code also disables all swaps and detachs
>> DM/loop devices in the same loop.
> 
> Thanks as always for the fast and good explanation! With that pointer,
> I found the problem, see below.
> 
>>> We do have a bit of a strange fs-layout, where our root fs is kept
>>> inside /versions/pristine/X on the root partition. The initramfs takes
>>> care of this with some bind-mount and chroot tricks so that it looks
>>> 'normal' afterwards, but maybe something along these lines is
>>> confusing systemd.
>>
>> chroot()? Meh, you should not use chroot for these kinds of things...
> 
> Actually, we don't use chroot directly. Here's what happens:
> 
> dracut mounts the root fs at /sysroot, then in a pre-pivot dracut
> trigger OLPC does:
> 
> mkdir /vsysroot
> mount --bind /sysroot/versions/run/6 /vsysroot
> umount /sysroot
> NEWROOT=/vsysroot
> 
> Dracut then goes ahead and performs switch_root on $NEWROOT to pivot
> onto the real system.
> 
> (Happy to hear advice on a nicer way to do this)
> 
> When the system finishes booting, /proc/self/mountinfo looks like:
> http://dev.laptop.org/~dsd/20120411/mountinfo.txt
> 
> Now, in systemd-shutdown we reach mount_points_list_get() in umount.c,
> which does:
> 
>                 /* If we encounter a bind mount, don't try to remount
>                  * the source dir too early */
>                 skip_ro = !streq(root, "/");
> 
> Hence skip_ro gets set to 1 for our /
> 
> mount_points_list_remount_read_only() then ignores the / mount and
> leaves it as RW during shutdown.
> 
> I don't really understand the reasoning for the above behaviour of
> bind mounts. Would it be acceptable to special-case this condition if
> the path in question is / so that skip_ro does not get set? Or are
> there other options available?

Keep in mind that systemd cannot umount / (and often cannot unmount /usr
either) so after it has done everything it can it should re-enter the
dracut initrd to let it do some additional tidy up, i.e. properly
unmounting /usr and /, deactivating LVM+crypt if they were used for / or
/usr (tho' I do not think either of these is done just yet - needs work
at dracut side) etc.

Make sure you build dracut with --systemdsystemunitdir arguement to get
the dracut-shutdown.service files built and make sure they are included
on the running system.

HTHs

Col


-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited http://www.tribalogic.net/
Open Source:
  Mageia Contributor http://www.mageia.org/
  PulseAudio Hacker http://www.pulseaudio.org/
  Trac Hacker http://trac.edgewall.org/



More information about the systemd-devel mailing list