tags 494001 + patch thanks On Wed, Aug 06, 2008 at 03:32:50PM +0100, Roger Leigh wrote: > /etc/mtab can be either a regular file updated by mount/umount, or a symlink > to /proc/mounts. Currently, it is a regular file, though the user can change > this by hand. > > With linux < 2.6.26, /proc/mounts lacks information present in /etc/mtab such > as additional mount options. Thus a symlink breaks things like discquotas > which rely on parsing the additional mount options. As a result, we are > mostly all still using it as a plain file. > > With linux >= 2.6.26, /proc/mounts contains all of the information in > /etc/mtab, plus more. The mount system call can now pass all of the mount > options to the kernel, so no information is missing in /proc/mounts. This > has obviously useful benefits such as read-only root, and the state in > /etc/mtab never gets out of sync with reality (there are a number of open > bugs against mount where this occurs). > > Additionally, with the addition of per-process namespaces with CLONE_NEWNS to > clone(2), each process has its own set of mounts, and as such a system-wide > /etc/mtab is useless: it's only valid in one of the potentially many > namespaces and can quickly get into a horrible mess. At this point, > /etc/mtab *must* be a symlink to avoid breakage. Note that /proc/mounts is > now a symlink to /proc/self/mounts for this reason: each process has > potentially different mounts. > > > After discussion on #debian-devel, we came up with these points: > - we could detect the kernel version on boot, and set up a file or a symlink > as needed. However, this breaks read-only root. > - we could change on upgrades rather than boot, but because it's dependent > upon the kernel version, breakage could result if an older kernel is > booted. > - doing it at install time if a kernel >= 2.6.26 is installed is the most > robust solution.
Following further discussion today, we concluded that - the initscripts postinst was the appropriate place to do this. - since Lenny uses Linux 2.6.26, and Squeeze will require Linux >= 2.6.26 a version check was not required. - non-Linux kernels don't support /proc, so only make this change for Linux. - comments in the bug report concerning inotify were not justified and should not hold back this change. I have attached a small patch against sysvinit to implement this change in initscripts. It's not yet tested; it's just to show the intent of the changes I'd like to make. Thanks, Roger -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.
diff -urN sysvinit-2.86.ds1.original/debian/changelog sysvinit-2.86.ds1/debian/changelog --- sysvinit-2.86.ds1.original/debian/changelog 2009-03-18 19:05:21.000000000 +0000 +++ sysvinit-2.86.ds1/debian/changelog 2009-03-18 20:02:19.000000000 +0000 @@ -1,3 +1,12 @@ +sysvinit (2.86.ds1-62) unstable; urgency=low + + [ Roger Leigh ] + * /etc/init.d/mtab.sh: Remove. + * initscripts postinst: Remove mtab.sh. Symlink /etc/mtab to + /proc/mounts on Linux systems (Closes: #494001). + + -- Roger Leigh <[email protected]> Wed, 18 Mar 2009 20:01:47 +0000 + sysvinit (2.86.ds1-61) unstable; urgency=low * Fix typo in rcS(5), proberly->properly (Closes: #484233). Thanks to diff -urN sysvinit-2.86.ds1.original/debian/initscripts/conffiles sysvinit-2.86.ds1/debian/initscripts/conffiles --- sysvinit-2.86.ds1.original/debian/initscripts/conffiles 2009-03-18 19:05:21.000000000 +0000 +++ sysvinit-2.86.ds1/debian/initscripts/conffiles 2009-03-18 19:33:49.000000000 +0000 @@ -14,7 +14,6 @@ /etc/init.d/mountoverflowtmp /etc/init.d/mountdevsubfs.sh /etc/init.d/mountkernfs.sh -/etc/init.d/mtab.sh /etc/init.d/rc.local /etc/init.d/reboot /etc/init.d/rmnologin diff -urN sysvinit-2.86.ds1.original/debian/initscripts/doc/README.Debian sysvinit-2.86.ds1/debian/initscripts/doc/README.Debian --- sysvinit-2.86.ds1.original/debian/initscripts/doc/README.Debian 2009-03-18 19:05:21.000000000 +0000 +++ sysvinit-2.86.ds1/debian/initscripts/doc/README.Debian 2009-03-18 19:38:09.000000000 +0000 @@ -46,8 +46,8 @@ sysfs /sys sysfs rw,nosuid,nodev,noexec 0 0 The reason is that the entry in fstab needs to match the entry -generated by the mountkernfs.sh and mtab.sh scripts. If it does not, -the system will complain with this message during boot: +generated by the mountkernfs.sh script. If it does not, the system +will complain with this message during boot: Will now mount local filesystems:mount: /sys already mounted or /sys busy mount: according to mtab, sysfs is already mounted on /sys diff -urN sysvinit-2.86.ds1.original/debian/initscripts/etc/init.d/mtab.sh sysvinit-2.86.ds1/debian/initscripts/etc/init.d/mtab.sh --- sysvinit-2.86.ds1.original/debian/initscripts/etc/init.d/mtab.sh 2009-03-18 19:05:21.000000000 +0000 +++ sysvinit-2.86.ds1/debian/initscripts/etc/init.d/mtab.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,180 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: mtab -# Required-Start: checkroot -# Required-Stop: -# Default-Start: S -# Default-Stop: -# Short-Description: Update mtab file. -# Description: Update the mount program's mtab file after -# all local filesystems have been mounted. -### END INIT INFO - -# -# The main purpose of this script is to update the mtab file to reflect -# the fact that virtual filesystems were mounted early on, before mtab -# was writable. -# - -PATH=/lib/init:/sbin:/bin -. /lib/init/vars.sh - -TTYGRP=5 -TTYMODE=620 -[ -f /etc/default/devpts ] && . /etc/default/devpts - -TMPFS_SIZE= -[ -f /etc/default/tmpfs ] && . /etc/default/tmpfs - -KERNEL="$(uname -s)" - -. /lib/lsb/init-functions -. /lib/init/mount-functions.sh - -# $1 - fstype -# $2 - mount point -# $3 - mount name/device -# $4 - mount options -domtab () -{ - # Directory present? - if [ ! -d $2 ] - then - return - fi - - # Not mounted? - if ! mountpoint -q $2 < /dev/null - then - return - fi - - if [ -n "$3" ] - then - NAME="$3" - else - NAME="$1" - fi - - # Already recorded? - if ! grep -E -sq "^([^ ]+) +$2 +" /etc/mtab < /dev/null - then - mount -f -t $1 $OPTS $4 $NAME $2 < /dev/null - fi -} - -do_start () { - DO_MTAB="" - MTAB_PATH="$(readlink -f /etc/mtab || :)" - case "$MTAB_PATH" in - /proc/*) - # Assume that /proc/ is not writable - ;; - /*) - # Only update mtab if it is known to be writable - # Note that the touch program is in /usr/bin - #if ! touch "$MTAB_PATH" >/dev/null 2>&1 - #then - # return - #fi - ;; - "") - [ -L /etc/mtab ] && MTAB_PATH="$(readlink /etc/mtab)" - if [ "$MTAB_PATH" ] - then - log_failure_msg "Cannot initialize ${MTAB_PATH}." - else - log_failure_msg "Cannot initialize /etc/mtab." - fi - ;; - *) - log_failure_msg "Illegal mtab location '${MTAB_PATH}'." - ;; - esac - - # - # Initialize mtab file if necessary - # - if [ ! -f /etc/mtab ] - then - :> /etc/mtab - chmod 644 /etc/mtab - fi - if selinux_enabled && which restorecon >/dev/null 2>&1 && [ -r /etc/mtab ] - then - restorecon /etc/mtab - fi - - # S02mountkernfs.sh - RW_OPT= - [ "${RW_SIZE:=$TMPFS_SIZE}" ] && RW_OPT=",size=$RW_SIZE" - domtab tmpfs /lib/init/rw tmpfs -omode=0755,nosuid$RW_OPT - - domtab proc /proc "proc" -onodev,noexec,nosuid - if grep -E -qs "sysfs\$" /proc/filesystems - then - domtab sysfs /sys sysfs -onodev,noexec,nosuid - fi - if [ yes = "$RAMRUN" ] ; then - RUN_OPT= - [ "${RUN_SIZE:=$TMPFS_SIZE}" ] && RUN_OPT=",size=$RUN_SIZE" - domtab tmpfs /var/run "varrun" -omode=0755,nosuid$RUN_OPT - fi - if [ yes = "$RAMLOCK" ] ; then - LOCK_OPT= - [ "${LOCK_SIZE:=$TMPFS_SIZE}" ] && LOCK_OPT=",size=$LOCK_SIZE" - domtab tmpfs /var/lock "varlock" -omode=1777,nodev,noexec,nosuid$LOCK_OPT - fi - if [ -d /proc/bus/usb ] - then - domtab usbfs /proc/bus/usb "procbususb" - fi - - # S03udev - domtab tmpfs /dev "udev" -omode=0755 - - # S04mountdevsubfs - SHM_OPT= - [ "${SHM_SIZE:=$TMPFS_SIZE}" ] && SHM_OPT=",size=$SHM_SIZE" - domtab tmpfs /dev/shm tmpfs -onosuid,nodev$SHM_OPT - domtab devpts /dev/pts "devpts" -onoexec,nosuid,gid=$TTYGRP,mode=$TTYMODE - - # Add everything else in /proc/mounts into /etc/mtab, with - # special exceptions. - exec 9<&0 0</proc/mounts - while read FDEV FDIR FTYPE FOPTS REST - do - case "$FDIR" in - /lib/modules/*/volatile) - FDEV="lrm" - ;; - /dev/.static/dev) - # Not really useful to show in 'df', - # and it isn't accessible for non-root - # users. - continue - ;; - esac - domtab "$FTYPE" "$FDIR" "$FDEV" "-o$FOPTS" - done - exec 0<&9 9<&- -} - -case "$1" in - start|"") - do_start - ;; - restart|reload|force-reload) - echo "Error: argument '$1' not supported" >&2 - exit 3 - ;; - stop) - # No-op - ;; - *) - echo "Usage: mountall-mtab.sh [start|stop]" >&2 - exit 3 - ;; -esac - -: diff -urN sysvinit-2.86.ds1.original/debian/initscripts/postinst sysvinit-2.86.ds1/debian/initscripts/postinst --- sysvinit-2.86.ds1.original/debian/initscripts/postinst 2009-03-18 19:05:21.000000000 +0000 +++ sysvinit-2.86.ds1/debian/initscripts/postinst 2009-03-18 20:05:31.000000000 +0000 @@ -107,6 +107,15 @@ update-rc.d -f sendsigs remove >/dev/null 2>&1 || : fi +# In 2.86.ds1-62, the mtab.sh script was removed and /etc/mtab was +# replaced with a symbolic link to /etc/mtab on Linux. +if dpkg --compare-versions "$PREV_VER" lt "2.86.ds1-62" +then + update-rc.d -f mtab.sh remove >/dev/null 2>&1 || : + update-rc.d -f hostname.sh remove >/dev/null 2>&1 || : +fi + + # # Okay, we could do this with update-rc.d, but that would probably # be pretty slow. This way we win some speed. @@ -119,7 +128,6 @@ updatercd mountdevsubfs.sh start 4 S . updatercd bootlogd start 5 S . updatercd checkroot.sh start 10 S . -updatercd mtab.sh start 12 S . updatercd checkfs.sh start 30 S . updatercd mountall.sh start 35 S . updatercd mountall-bootclean.sh start 36 S . @@ -161,6 +169,24 @@ done # +# In 2.86.ds1-62 the "mtab.sh" script was removed, and /etc/mtab +# replaced as a symbolic link to /proc/mounts. +# +# The reason for this is that /etc/mtab requires a writable root +# filesystem, and does not support per-process namespaces. Since +# Linux 2.6.26, /proc/mounts contains all the information that +# /etc/mtab provided (such as extra mount options), and it is a +# symlink to /proc/self/mounts, to support per-process namespaces. +# +if [ "$(uname -s)" = Linux ] +then + if [ -L /etc/mtab && -r /proc/mounts ] + then + rm /etc/mtab && ln -s /proc/mounts /etc/mtab + fi +fi + +# # Create /var/run and /var/lock on the root partition to make sure # they are available when RAMRUN or RAMLOCK is enabled. # If mount fail (like in a vserver environment), just clean up and ignore

