On Thu, Mar 31, 2011 at 06:55:16PM +0100, Roger Leigh wrote:
> On Wed, Mar 30, 2011 at 11:00:57PM +0100, Roger Leigh wrote:
> > The attached patch contains a detailed changelog of the changes, so
> > I won't repeat it here verbatim.  Outstanding issues are marked
> > TODO, and may require further discussion to resolve them.
> 
> Updated patch attached.  Handles upgrades and reboots; other than
> the one outstanding TODO item (transition of /lib/init/rw from
> directory to symlink, probably something we can leave until after
> squeeze).

Updated patch attached.  This one has been tested in a VM, and will
allow a machine to boot and transition to /run safely.

Minor outstanding issue:
/etc/init.d/mountall.sh fails.  This is due to (apparently) / and /proc
already being mounted, leading to a 32 exit status.  Maybe an mtab
issue?

In order to work properly with bind mounts on freebsd kernels, I've
synched domount and domtab logic so that they behave identically.
However, I'm seeing some odd double bind mounts in /proc/mounts
and an incomplete /etc/mtab, so there's possibly something not quite
right here.

Apart from this one issue, everything else is working fully.


Regards,
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.
Index: debian/src/initscripts/share/default.rcS
===================================================================
--- debian/src/initscripts/share/default.rcS	(revision 1953)
+++ debian/src/initscripts/share/default.rcS	(working copy)
@@ -13,5 +13,4 @@
 UTC=yes
 VERBOSE=no
 FSCKFIX=no
-RAMRUN=no
-RAMLOCK=no
+RAMLOCK=yes
Index: debian/src/initscripts/doc/README.Debian
===================================================================
--- debian/src/initscripts/doc/README.Debian	(revision 1953)
+++ debian/src/initscripts/doc/README.Debian	(working copy)
@@ -4,15 +4,14 @@
 Tmpfs can be used as virtual memory filesystem. glibc 2.2 and above
 expects a tmpfs to be mounted at /dev/shm for POSIX shared memory,
 this is done automatically by /etc/init.d/mountdevsubfs.sh early in
-the boot process. You can limit tmpfs max size by setting the
-SHM_SIZE variable to a desired size in the /etc/default/tmpfs file
-to prevent tmpfs from using up all system memory.
+the boot process. You can limit tmpfs max size by setting the SHM_SIZE
+variable to a desired size in the /etc/default/tmpfs file to prevent
+tmpfs from using up all system memory.
 
-A tmpfs can also be mounted over /var/run/ and /var/lock/. This can
-be achieved by setting the RAMRUN and RAMLOCK variables to "yes" in
-the /etc/default/rcS file. A size limit for the tmpfs filesystem
-mounted over /var/run/ and /var/lock/ can be set via the RUN_SIZE
-and LOCK_SIZE variables in the /etc/default/tmpfs file.
+A size limit for the tmpfs filesystem mounted over /run can be set via
+the RUN_SIZE variable in the /etc/default/tmpfs file.  Likewise, a
+size limit for the tmpfs filesystem mounted over /run/lock can be set
+via the LOCK_SIZE variable (if enabled with RAMLOCK=yes).
 
 If TMPFS_SIZE is set in /etc/default/tmpfs, it will be used as the
 default value for SHM_SIZE, RUN_SIZE and LOCK_SIZE. Otherwise, kernel
@@ -22,11 +21,10 @@
 sendsigs process omission interface
 -----------------------------------
 
-Since initscripts package version 2.86.ds1-48, /etc/init.d/sendsigs
-is able to omit processes from being killed by killall5(8). Process
-id's listed in /var/run/sendsigs.omit, /lib/init/rw/sendsigs.omit or
-any file in the /lib/init/rw/sendsigs.omit.d/ directory will be
-omitted by sendsigs.
+Since initscripts package version 2.86.ds1-48, /etc/init.d/sendsigs is
+able to omit processes from being killed by killall5(8). Process id's
+listed in /run/sendsigs.omit, /run/init/sendsigs.omit or any file in
+the /run/init/sendsigs.omit.d/ directory will be omitted by sendsigs.
 
 The recommended practise for adding a process id for omission is to
 create a file in /lib/init/rw/sendsigs.omit.d/<package name>
Index: debian/src/initscripts/lib/init/bootclean.sh
===================================================================
--- debian/src/initscripts/lib/init/bootclean.sh	(revision 1953)
+++ debian/src/initscripts/lib/init/bootclean.sh	(working copy)
@@ -112,7 +112,7 @@
 }
 
 clean_lock() {
-	if [ yes = "$RAMLOCK" ] ; then
+	if [ -f /var/lock/.ramfs ] ; then
 	    return 0
 	fi
 
@@ -136,7 +136,7 @@
 }
 
 clean_run() {
-	if [ yes = "$RAMRUN" ] ; then
+	if [ -f /var/run/.ramfs ] ; then
 	    return 0
 	fi
 
Index: debian/src/initscripts/lib/init/mount-functions.sh
===================================================================
--- debian/src/initscripts/lib/init/mount-functions.sh	(revision 1953)
+++ debian/src/initscripts/lib/init/mount-functions.sh	(working copy)
@@ -21,8 +21,8 @@
 	which selinuxenabled >/dev/null 2>&1 && selinuxenabled
 }
 
-
 # Called before mtab is writable to mount kernel and device file systems.
+# Note any changes here must also be made in domtab in mtab.sh.
 # $1: file system type
 # $2: alternative file system type (or empty string if none)
 # $3: mount point
@@ -33,15 +33,23 @@
 	KERNEL="$(uname -s)"
 	# Figure out filesystem type
 	FSTYPE=
+	OPTS=
 	if [ "$1" = proc ]
 	then
 		case "$KERNEL" in
-			Linux|GNU) FSTYPE=proc ;;
+			Linux|GNU) FSTYPE=proc;;
 			*FreeBSD)  FSTYPE=linprocfs ;;
 			*)         FSTYPE=procfs ;;
 		esac
+	elif [ "$1" = bind ]
+	then
+		case "$KERNEL" in
+			Linux|GNU) FSTYPE=$4; OPTS="-obind" ;;
+			*FreeBSD)  FSTYPE=nullfs ;;
+			*)         FSTYPE=none ;;
+		esac
 	elif [ "$1" = tmpfs ]
-	then # always accept tmpfs, to mount /lib/init/rw before /proc
+	then # always accept tmpfs, to mount /run before /proc
 		FSTYPE=$1
 	elif grep -E -qs "$1\$" /proc/filesystems
 	then
@@ -71,14 +79,13 @@
 	fi
 
 	# Get the options from /etc/fstab.
-	OPTS=
 	if [ -f /etc/fstab ]
 	then
 		exec 9<&0 </etc/fstab
 
 		while read TAB_DEV TAB_MTPT TAB_FSTYPE TAB_OPTS TAB_REST
 		do
-			case "$TAB_DEV" in (""|\#*) continue ;; esac
+			case "$TAB_DEV" in ""|\#*) continue ;; esac
 			[ "$MTPT" = "$TAB_MTPT" ] || continue
 			[ "$FSTYPE" = "$TAB_FSTYPE" ] || continue
 			case "$TAB_OPTS" in
@@ -87,7 +94,7 @@
 				return
 				;;
 			  ?*)
-				OPTS="-o$TAB_OPTS"
+				OPTS="$OPTS -o$TAB_OPTS"
 				;;
 			esac
 			break
@@ -121,45 +128,69 @@
 #
 pre_mountall ()
 {
-	# We may end up mounting something over top of /var, either directly
-	# or because /var is a symlink to something that's mounted.  So keep
-	# copies of the /var/run and /var/lock mounts elsewhere on the root
-	# filesystem so they can be moved back.
-	if [ yes = "$RAMRUN" ] ; then
-		mkdir /lib/init/rw/var.run
-		mount -n --bind /var/run /lib/init/rw/var.run
-	fi
-	if [ yes = "$RAMLOCK" ] ; then
-		mkdir /lib/init/rw/var.lock
-		mount -n --bind /var/lock /lib/init/rw/var.lock
-	fi
+	# RAMRUN and RAMLOCK on /var/run and /var/lock are obsoleted by
+	# /run.  Note that while RAMRUN is no longer used (/run is always
+	# a tmpfs), RAMLOCK is still functional, but will cause a second
+	# tmpfs to be mounted on /run/lock.
+	:
 }
 
 #
-# Restore /var/run and /var/lock mountpoints if something was mounted
-# as /var/.  Avoid mounting them back over themselves if nothing was
-# mounted as /var/ by checking if /var/run/ and /var/lock/ are still
-# mount points.  Enabling RAMRUN and RAMLOCK while listing /var/run or
-# /var/lock in /etc/fstab is not supported.
+# Migrate a directory to /run and create compatibility symlink or bind
+# mount.
 #
-post_mountall ()
+run_migrate ()
 {
-	if [ yes = "$RAMRUN" ] ; then
-		[ -d /var/run ] || mkdir /var/run
-		if mountpoint -q /var/run ; then
-			umount /lib/init/rw/var.run
-		else
-			mount -n --move /lib/init/rw/var.run /var/run
-		fi
-		rmdir /lib/init/rw/var.run
+	OLD=$1
+	RUN=$2
+
+	KERNEL="$(uname -s)"
+	OPTS=""
+	case "$KERNEL" in
+		Linux|GNU) FSTYPE=none OPTS="-obind";;
+		*FreeBSD)  FSTYPE=nullfs ;;
+		*)         FSTYPE=none ;;
+	esac
+
+	# Try to remove if a directory.  Note this is safe because the
+	# system is not yet fully up, and nothing is allowed to use
+	# them yet.  If the user explicitly mounted a filesystem here,
+	# it will be cleaned out, but this would happen later on when
+	# bootclean runs in any case.
+	if [ ! -L "$OLD" ] && [ -d "$OLD" ] ; then
+		rm -fr "$OLD" 2>/dev/null || true
 	fi
-	if [ yes = "$RAMLOCK" ] ; then
-		[ -d /var/lock ] || mkdir /var/lock
-		if mountpoint -q /var/lock ; then
-			umount /lib/init/rw/var.lock
+
+	# If removal failed (directory still exists), set up bind mount.
+	if [ -d "$OLD" ] ; then
+		mount -t $FSTYPE "$RUN" "$OLD" -orw $OPTS
+	else
+		# Create symlink if not already present.
+		if [ -L "$OLD" ] && [ "$(readlink "$OLD")" = "$RUN" ]; then
+			:
 		else
-			mount -n --move /lib/init/rw/var.lock /var/lock
+			ln -fs "$RUN" "$OLD"
 		fi
-		rmdir /lib/init/rw/var.lock
 	fi
 }
+
+#
+# For compatibility, create /var/run and /var/lock symlinks to /run
+# and /run/lock, respectively.
+#
+post_mountall ()
+{
+	# /var/run and /var/lock are now /run and /run/lock,
+	# respectively.  Cope with filesystems being deliberately
+	# mounted on /var/run and /var/lock.  We will create bind
+	# mounts from /run and /run/lock to /var/run and /var/lock if
+	# we can't remove the /var/run and /var/lock directories, or
+	# else simply create symlinks.  For example, in the case that
+	# the user has explicitly mounted filesystems on /var/run or
+	# /var/lock, we bind mount over the top of them.  Where no
+	# filesystems are mounted, we replace the directory with a
+	# symlink where possible.
+
+	run_migrate /var/run /run
+	run_migrate /var/lock /run/lock
+}
Index: debian/src/initscripts/etc/default/tmpfs
===================================================================
--- debian/src/initscripts/etc/default/tmpfs	(revision 1953)
+++ debian/src/initscripts/etc/default/tmpfs	(working copy)
@@ -1,6 +1,19 @@
+# TMPFS_SIZE sets the maximum size (in bytes) that tmpfs filesystems can use.
+#
+# The size will be rounded down to a multiple of the page size, 4096 bytes.
+TMPFS_SIZE=
+
 # SHM_SIZE sets the maximum size (in bytes) that the /dev/shm tmpfs can use.
 # If this is not set then the size defaults to the value of TMPFS_SIZE
 # if that is set; otherwise to the kernel's default.
-#
-# The size will be rounded down to a multiple of the page size, 4096 bytes.
 SHM_SIZE=
+
+# RUN_SIZE sets the maximum size (in bytes) that the /run tmpfs can use.
+# If this is not set then the size defaults to the value of TMPFS_SIZE
+# if that is set; otherwise to the kernel's default.
+RUN_SIZE=
+
+# LOCK_SIZE sets the maximum size (in bytes) that the /run/lock tmpfs can use.
+# If this is not set then the size defaults to the value of TMPFS_SIZE
+# if that is set; otherwise to the kernel's default.
+LOCK_SIZE=
Index: debian/src/initscripts/etc/init.d/sendsigs
===================================================================
--- debian/src/initscripts/etc/init.d/sendsigs	(revision 1953)
+++ debian/src/initscripts/etc/init.d/sendsigs	(working copy)
@@ -27,9 +27,7 @@
 do_stop () {
 	OMITPIDS=
 
-	# The /var/run/sendsigs.omit file is used to be compatible
-	# with Ubuntu.
-	for omitfile in /var/run/sendsigs.omit /lib/init/rw/sendsigs.omit; do
+	for omitfile in /run/sendsigs.omit /run/init/sendsigs.omit /var/run/sendsigs.omit /lib/init/rw/sendsigs.omit; do
 		if [ -e $omitfile ]; then
 			for pid in $(cat $omitfile); do
 				OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
@@ -40,14 +38,17 @@
 	# Load sendsigs.omit.d/packagename files too, to make it
 	# possible for scripts that need to modify the list of pids at
 	# run time without race conditions.
-	if [ -d /lib/init/rw/sendsigs.omit.d/ ]; then
-		for pidfile in /lib/init/rw/sendsigs.omit.d/*; do
-			[ -f "$pidfile" ] || continue
-			for pid in $(cat $pidfile); do
-				OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
+	for omitdir in /run/init/sendsigs.omit.d/ /lib/init/rw/sendsigs.omit.d/; do
+
+		if [ -d $omitdir ]; then
+			for pidfile in $omitdir/*; do
+				[ -f "$pidfile" ] || continue
+				for pid in $(cat $pidfile); do
+					OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
+				done
 			done
-		done
-	fi
+		fi
+	done
 
 	# Upstart jobs have their own "stop on" clauses that sends
 	# SIGTERM/SIGKILL just like this, so if they're still running,
Index: debian/src/initscripts/etc/init.d/umountfs
===================================================================
--- debian/src/initscripts/etc/init.d/umountfs	(revision 1953)
+++ debian/src/initscripts/etc/init.d/umountfs	(working copy)
@@ -27,16 +27,16 @@
 	do
 		echo "$PROTECTED_MOUNTS" | grep -qs "^$DEV $MTPT " && continue
 		case "$MTPT" in
-		  /|/proc|/dev|/.dev|/dev/pts|/dev/shm|/dev/.static/dev|/proc/*|/sys|/sys/*|/lib/init/rw)
+		  /|/proc|/dev|/.dev|/dev/pts|/dev/shm|/dev/.static/dev|/proc/*|/sys|/sys/*|/run|/lib/init/rw)
 			continue
 			;;
 		  /var/run)
-			if [ yes = "$RAMRUN" ] ; then
+			if [ -f /var/run/.ramfs ] ; then
 				continue
 			fi
 			;;
 		  /var/lock)
-			if [ yes = "$RAMLOCK" ] ; then
+			if [ -f /var/run/.ramfs ] ; then
 				continue
 			fi
 			;;
Index: debian/src/initscripts/etc/init.d/mountkernfs.sh
===================================================================
--- debian/src/initscripts/etc/init.d/mountkernfs.sh	(revision 1953)
+++ debian/src/initscripts/etc/init.d/mountkernfs.sh	(working copy)
@@ -26,12 +26,38 @@
 	#
 	RW_OPT=
 	[ "${RW_SIZE:=$TMPFS_SIZE}" ] && RW_OPT=",size=$RW_SIZE"
-	domount tmpfs "" /lib/init/rw tmpfs -omode=0755,nosuid$RW_OPT
-	touch /lib/init/rw/.ramfs
+	domount tmpfs shmfs /run tmpfs -omode=0755,nosuid$RW_OPT
+	touch /run/.ramfs
 
+	# Make lock directory as the replacement for /var/lock
+	mkdir /run/lock
+
+	# Mount /var/lock as tmpfs if enabled.  This prevents user DoS
+	# of /run by filling /run/lock at the expense of using an
+	# additional tmpfs.
+	if [ yes = "$RAMLOCK" ] ; then
+		LOCK_OPT=
+		[ "${LOCK_SIZE:=$TMPFS_SIZE}" ] && LOCK_OPT=",size=$LOCK_SIZE"
+		domount tmpfs shmfs /run/lock tmpfs -omode=1777,nodev,noexec,nosuid$LOCK_OPT
+	fi
+
+	touch /run/lock/.ramfs
+	chmod 01777 /run/lock
+
+	# Make init directory as the replacement for /lib/init/rw
+	mkdir /run/init
+	touch /run/init/.ramfs
+
 	# Make pidfile omit directory for sendsigs
-	mkdir /lib/init/rw/sendsigs.omit.d/
+	# TODO: Move to /run/sendsigs.omit.d?  Keeping it in /run/init
+	# keeps compatibility with the existing use of /lib/init/rw.
+	mkdir /run/init/sendsigs.omit.d/
 
+	# Create compatibility bind mount for /lib/init/rw from /run/init
+	if [ -d /lib/init/rw ]; then
+		domount bind "" /lib/init/rw /run/init -orw
+	fi
+
 	#
 	# Mount proc filesystem on /proc
 	#
@@ -45,20 +71,6 @@
 	then
 		domount sysfs "" /sys sysfs -onodev,noexec,nosuid
 	fi
-
-	# Mount /var/run and /var/lock as tmpfs if enabled
-	if [ yes = "$RAMRUN" ] ; then
-		RUN_OPT=
-		[ "${RUN_SIZE:=$TMPFS_SIZE}" ] && RUN_OPT=",size=$RUN_SIZE"
-		domount tmpfs "" /var/run varrun -omode=0755,nosuid$RUN_OPT
-		touch /var/run/.ramfs
-	fi
-	if [ yes = "$RAMLOCK" ] ; then
-		LOCK_OPT=
-		[ "${LOCK_SIZE:=$TMPFS_SIZE}" ] && LOCK_OPT=",size=$LOCK_SIZE"
-		domount tmpfs "" /var/lock varlock -omode=1777,nodev,noexec,nosuid$LOCK_OPT
-		touch /var/lock/.ramfs
-	fi
 }
 
 case "$1" in
Index: debian/src/initscripts/etc/init.d/checkroot.sh
===================================================================
--- debian/src/initscripts/etc/init.d/checkroot.sh	(revision 1953)
+++ debian/src/initscripts/etc/init.d/checkroot.sh	(working copy)
@@ -137,7 +137,7 @@
 	#
 	# Does the root device in /etc/fstab match with the actual device ?
 	# If not we try to use the /dev/root alias device, and if that
-	# fails we create a temporary node in /lib/init/rw.
+	# fails we create a temporary node in /run/init.
 	#
 	if [ "$rootcheck" = yes ]
 	then
@@ -150,11 +150,11 @@
 				rootdev=/dev/root
 			else
 				if \
-					rm -f /lib/init/rw/rootdev \
-					&& mknod -m 600 /lib/init/rw/rootdev b ${rdev%:*} ${rdev#*:} \
-					&& [ -e /lib/init/rw/rootdev ]
+					rm -f /run/init/rootdev \
+					&& mknod -m 600 /run/init/rootdev b ${rdev%:*} ${rdev#*:} \
+					&& [ -e /run/init/rootdev ]
 				then
-					rootdev=/lib/init/rw/rootdev
+					rootdev=/run/init/rootdev
 				else
 					rootfatal=yes
 				fi
@@ -169,7 +169,7 @@
 	then
 		log_failure_msg "The device node $rootdev for the root filesystem is missing or incorrect 
 or there is no entry for the root filesystem listed in /etc/fstab. 
-The system is also unable to create a temporary node in /lib/init/rw. 
+The system is also unable to create a temporary node in /run/init. 
 This means you have to fix the problem manually."
 		log_warning_msg "A maintenance shell will now be started. 
 CONTROL-D will terminate this shell and restart the system."
@@ -268,7 +268,7 @@
 		then
 			log_action_begin_msg "Checking root file system"
 			if [ "$roottype" = "ext2" -o "$roottype" = "ext3" -o "$roottype" = "ext4" ] && usplash_running; then
-			    PROGRESS_FILE=`mktemp -p /lib/init/rw` || PROGRESS_FILE=/lib/init/rw/checkroot_fsck
+			    PROGRESS_FILE=`mktemp -p /run/init` || PROGRESS_FILE=/run/init/checkroot_fsck
 			    set -m
 			    logsave -s $FSCK_LOGFILE fsck -C3 $force $fix -t $roottype $rootdev >/dev/console 2>&1 3>$PROGRESS_FILE &
 			    set +m
@@ -385,9 +385,9 @@
 	fi
 
 	#
-	# Remove /lib/init/rw/rootdev if we created it.
+	# Remove /run/init/rootdev if we created it.
 	#
-	rm -f /lib/init/rw/rootdev
+	rm -f /run/init/rootdev
 }
 
 do_status () {
Index: debian/src/initscripts/etc/init.d/mtab.sh
===================================================================
--- debian/src/initscripts/etc/init.d/mtab.sh	(revision 1953)
+++ debian/src/initscripts/etc/init.d/mtab.sh	(working copy)
@@ -31,35 +31,102 @@
 . /lib/lsb/init-functions
 . /lib/init/mount-functions.sh
 
-# $1 - fstype
-# $2 - mount point
-# $3 - mount name/device
-# $4 - mount options
+# Note any changes here must also be made in domount in mount-functions.
+# $1: file system type
+# $2: alternative file system type (or empty string if none)
+# $3: mount point
+# $4: mount device name
+# $5... : extra mount program options
 domtab ()
 {
-	# Directory present?
-	if [ ! -d $2 ]
+	MTPT="$3"
+	KERNEL="$(uname -s)"
+	# Figure out filesystem type
+	FSTYPE=
+	OPTS=
+	if [ "$1" = proc ]
 	then
+		case "$KERNEL" in
+			Linux|GNU) FSTYPE=proc;;
+			*FreeBSD)  FSTYPE=linprocfs ;;
+			*)         FSTYPE=procfs ;;
+		esac
+	elif [ "$1" = bind ]
+	then
+		case "$KERNEL" in
+			Linux|GNU) FSTYPE=$4; OPTS="-obind" ;;
+			*FreeBSD)  FSTYPE=nullfs ;;
+			*)         FSTYPE=none ;;
+		esac
+	elif [ "$1" = tmpfs ]
+	then # always accept tmpfs, to mount /run before /proc
+		FSTYPE=$1
+	elif grep -E -qs "$1\$" /proc/filesystems
+	then
+		FSTYPE=$1
+	elif grep -E -qs "$2\$" /proc/filesystems
+	then
+		FSTYPE=$2
+	fi
+
+	if [ ! "$FSTYPE" ]
+	then
+		if [ "$2" ]
+		then
+			log_warning_msg "Filesystem types '$1' and '$2' are not supported. Skipping mount."
+		else
+			log_warning_msg "Filesystem type '$1' is not supported. Skipping mount."
+		fi
 		return
 	fi
 
-	# Not mounted?
-	if ! mountpoint -q $2 < /dev/null
+	# We give file system type as device name if not specified as
+	# an argument
+	if [ "$4" ] ; then
+	    DEVNAME=$4
+	else
+	    DEVNAME=$FSTYPE
+	fi
+
+	# Get the options from /etc/fstab.
+	if [ -f /etc/fstab ]
 	then
+		exec 9<&0 </etc/fstab
+
+		while read TAB_DEV TAB_MTPT TAB_FSTYPE TAB_OPTS TAB_REST
+		do
+			case "$TAB_DEV" in ""|\#*) continue ;; esac
+			[ "$MTPT" = "$TAB_MTPT" ] || continue
+			[ "$FSTYPE" = "$TAB_FSTYPE" ] || continue
+			case "$TAB_OPTS" in
+			  noauto|*,noauto|noauto,*|*,noauto,*)
+				exec 0<&9 9<&-
+				return
+				;;
+			  ?*)
+				OPTS="$OPTS -o$TAB_OPTS"
+				;;
+			esac
+			break
+		done
+
+		exec 0<&9 9<&-
+	fi
+
+	if [ ! -d "$MTPT" ]
+	then
 		return
 	fi
 
-	if [ -n "$3" ]
+	if mountpoint -q "$MTPT"
 	then
-		NAME="$3"
-	else
-		NAME="$1"
+		return # Already mounted
 	fi
 
 	# Already recorded?
-	if ! grep -E -sq "^([^ ]+) +$2 +" /etc/mtab < /dev/null
+	if ! grep -E -sq "^([^ ]+) +$MTPT +" /etc/mtab < /dev/null
 	then
-		mount -f -t $1 $OPTS $4 $NAME $2 < /dev/null
+		mount -f -t $FSTYPE $5 $OPTS $DEVNAME $MTPT < /dev/null
 	fi
 }
 
@@ -108,40 +175,42 @@
 	# 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 tmpfs shmfs /run 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
+		domtab tmpfs shmfs /run/lock tmpfs -omode=1777,nodev,noexec,nosuid$LOCK_OPT
 	fi
+
+	if [ -d /lib/init/rw ]; then
+		domtab bind "" /lib/init/rw /run/init -orw
+	fi
+
+	domtab proc "" /proc proc -onodev,noexec,nosuid
+
+	if grep -E -qs "sysfs\$" /proc/filesystems
+	then
+		domtab sysfs "" /sys sysfs -onodev,noexec,nosuid
+	fi
+
 	if [ -d /proc/bus/usb ]
 	then
-		domtab usbfs /proc/bus/usb "procbususb"
+		domtab usbfs "" /proc/bus/usb "procbususb"
 	fi
 
 	# S03udev
-	domtab tmpfs /dev "udev" -omode=0755
+	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
+	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
+	exec 8<&0 0</proc/mounts
 	while read FDEV FDIR FTYPE FOPTS REST
 	do
 		case "$FDIR" in
@@ -155,9 +224,9 @@
 				continue
 				;;
 		esac
-		domtab "$FTYPE" "$FDIR" "$FDEV" "-o$FOPTS"
+		domtab "$FTYPE" "" "$FDIR" "$FDEV" "-o$FOPTS"
 	done
-	exec 0<&9 9<&-
+	exec 0<&8 8<&-
 }
 
 case "$1" in
Index: debian/src/initscripts/etc/init.d/umountnfs.sh
===================================================================
--- debian/src/initscripts/etc/init.d/umountnfs.sh	(revision 1953)
+++ debian/src/initscripts/etc/init.d/umountnfs.sh	(working copy)
@@ -48,16 +48,16 @@
 	while read -r DEV MTPT FSTYPE OPTS REST
 	do
 		case "$MTPT" in
-		  /|/proc|/dev|/dev/pts|/dev/shm|/proc/*|/sys|/lib/init/rw)
+		  /|/proc|/dev|/dev/pts|/dev/shm|/proc/*|/sys|/run|/lib/init/rw)
 			continue
 			;;
 		  /var/run)
-			if [ yes = "$RAMRUN" ] ; then
+			if [ -f /var/run/.ramfs ] ; then
 				continue
 			fi
 			;;
 		  /var/lock)
-			if [ yes = "$RAMLOCK" ] ; then
+			if [ -f /var/lock/.ramfs ] ; then
 				continue
 			fi
 			;;
Index: debian/src/initscripts/man/rcS.5
===================================================================
--- debian/src/initscripts/man/rcS.5	(revision 1953)
+++ debian/src/initscripts/man/rcS.5	(working copy)
@@ -97,19 +97,15 @@
 This will tell fsck always to repair the file systems
 without asking for permission.
 
-.IP \fBRAMRUN\fP
-Make /var/run/ available as a ram file system (tmpfs).  Will also disable
-cleaning of /var/run/ during boot.  Set to 'yes' to enable, to 'no' to disable.
-The size of the tmpfs can be controlled using TMPFS_SIZE and RUN_SIZE in
-/etc/default/tmpfs.  Because of this, packages can not expect directories in /var/run
-to exist after boot.  Packages expecting this are buggy and need to be fixed.
-
 .IP \fBRAMLOCK\fP
-Make /var/lock/ available as a ram file system (tmpfs).  Will also disable
-cleaning of /var/lock/ during boot.  Set to 'yes' to enable, to 'no' to disable.
-The size of the tmpfs can be controlled using TMPFS_SIZE and LOCK_SIZE in
-/etc/default/tmpfs.  Because of this, packages can not expect directories in /var/lock
-to exist after boot.  Packages expecting this are buggy and need to be fixed.
+Make /run/lock/ available as a ram file system (tmpfs).  Set to 'yes'
+to enable, to 'no' to disable.  The size of the tmpfs can be
+controlled using TMPFS_SIZE and LOCK_SIZE in /etc/default/tmpfs.
+Because of this, packages can not expect directories in /var/lock to
+exist after boot.  Packages expecting this are buggy and need to be
+fixed.  Note that /run/lock was previously /var/lock, and a
+compatibility symlink or bind mount will be created to allow the old
+path to continue to function.
 
 .IP \fBASYNCMOUNTNFS\fP
 Set this to 'no' to disable asynchronous mounting of network drives
Index: debian/src/initscripts/Makefile
===================================================================
--- debian/src/initscripts/Makefile	(revision 1953)
+++ debian/src/initscripts/Makefile	(working copy)
@@ -10,7 +10,10 @@
 all:
 
 install:
-	$(INSTALL) -d $(DESTDIR)/lib/init/rw/.
+	# TODO: Replace /lib/init/rw directory with symbolic link to
+	# /run.  This requires the directory to be empty and unused,
+	# so needs doing post-wheezy.
+	$(INSTALL) -d $(DESTDIR)/lib/init/rw
 	$(INSTALL) -d $(DESTDIR)/var/lib/initscripts/.
 	$(INSTALL) -d $(DESTDIR)/var/lib/urandom/.
 	$(INSTALL) -d $(DESTDIR)/var/log/fsck/.
Index: debian/initscripts.postinst
===================================================================
--- debian/initscripts.postinst	(revision 1953)
+++ debian/initscripts.postinst	(working copy)
@@ -118,38 +118,83 @@
 done
 
 #
-# 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
-# it.  The admins enabling RAMRUN and RAMLOCK will have to create the
-# directories themselves in this case.
+# Setup /run if not already in use.  Note that the intent here is to
+# make the existing /var/run and /var/lock and /lib/init/rw available
+# as /run, /run/lock and /run/init, respectively.  When the system is
+# next restarted, a proper /run tmpfs will be set up.  The bind mounts
+# set up here are intended to recreate the directory heirarchy using
+# the existing locations in order that packages may transition to
+# using /run without a system restart.
 #
-if dpkg --compare-versions "$PREV_VER" lt "2.86.ds1-22" && ! chrooted
-then
-	# We need to quickly bind / to another location so we can make them
-	# just in case /var is a mountpoint or a symlink to one.
-	mkdir -p /.root
-	if mount -n --bind / /.root ; then
-		if [ -L /.root/var ] && [ ! -d /.root/var ] ; then
-			# No use trying if /var is a relative symlink.  It is not
-			# going to work.
+
+# Device and inode of directories:
+svarrun=$(/usr/bin/stat --format="%d %i" /var/run)
+svarlock=$(/usr/bin/stat --format="%d %i" /var/lock)
+slibinitrw=$(/usr/bin/stat --format="%d %i" /lib/init/rw)
+# May not exist yet
+srun=$(/usr/bin/stat --format="%d %i" /run 2>/dev/null || :)
+srunlock=$(/usr/bin/stat --format="%d %i" /run/lock 2>/dev/null || :)
+sruninit=$(/usr/bin/stat --format="%d %i" /run/init 2>/dev/null || :)
+
+# If /run does not exist yet, or /run/.run-transition does not exist
+# then skip.  /run/.run-transition should not exist either before or
+# after the transition.
+if [ -d /run ] && [ ! -f /run/.run-transition ]; then
+	# If in a chroot, do not do any messing around with mounts,
+	# but do make /run/init and /run/lock for packages which
+	# depend upon their presence.
+	if chrooted; then
+		[ -d /run/lock ] || mkdir /run/lock
+		[ -d /run/init ] || mkdir /run/init
+	else
+		# If /run/.ramfs exists, then a ramfs already exists,
+		# and we assume it's all set up correctly.  If the
+		# device/inode are the same, it's not set up entirely
+		# correctly, but a bind mount already exists for some
+		# reason, so again assume set up is not required.
+		if [ -f /run/.ramfs ] || [ "$svarrun" = "$srun" ]; then
 			:
 		else
-			mkdir -p /.root/var/run /.root/var/lock
+			# Bind mount /var/run on /run
+			if mount --bind /var/run /run; then
+				# Bind mount /var/lock on /run/lock
+				[ -d /run/lock ] || mkdir /run/lock
+				if [ "$svarlock" = "$srunlock" ]; then
+					:
+				else
+					mount --bind /var/lock /run/lock
+				fi
+				# Bind mount /lib/init/rw on /run/init
+				[ -d /run/init ] || mkdir /run/init
+				if [ "$slibinitrw" = "$sruninit" ]; then
+					:
+				else
+					mount --bind /lib/init/rw /run/init
+				fi
+			fi
 		fi
-		umount /.root
+
+		# Create a /run/.run-transition stamp file.  This is
+		# to ensure we don't repeat the above setup if the
+		# package is upgraded again prior to a system reboot.
+		# On reboot, it will be deleted by the init scripts
+		# and the transition will be completed.  This means
+		# the transition will complete at the sysadmin's
+		# convenience, since the system will function
+		# identically before and after a reboot.
+		echo "Please reboot to complete migration to tmpfs-based /run" > /run/.run-transition
 	fi
-	rmdir /.root
 fi
 
+
 #
-# When installing for the first time or upgrading from version before
-# 2.86.ds1-27, a reboot is needed to make the /lib/init/rw/ tmpfs
-# available.  Flag this using notify-reboot-required.  Not mounting it
-# here as it creates problem for debootstrap, vservers, pbuilder and
-# cowbuilder.
+# When installing for the first time or upgrading from a version
+# before or equal to 2.88dsf-14, a reboot is needed to make the /run
+# tmpfs available.  Flag this using notify-reboot-required.  Not
+# mounting it here as it creates problem for debootstrap, vservers,
+# pbuilder and cowbuilder.
 #
-if dpkg --compare-versions "$PREV_VER" lt "2.86.ds1-27" \
+if dpkg --compare-versions "$PREV_VER" le "2.88dsf-14" \
  && [ -x /usr/share/update-notifier/notify-reboot-required ]; then
 	/usr/share/update-notifier/notify-reboot-required
 fi
Index: debian/changelog
===================================================================
--- debian/changelog	(revision 1953)
+++ debian/changelog	(working copy)
@@ -1,3 +1,93 @@
+sysvinit (2.88dsf-14.1) UNRELEASED; urgency=low
+
+  * Support for new top-level directory /run to replace /var/run,
+    /var/lock and /lib/init/rw as a place to store transient
+    writable data which should not be preserved across a system
+    reboot.  Summary:
+      /var/run → /run
+      /var/lock → /run/lock
+      /lib/init/rw → /run/init
+    These changes do not take effect until the system is rebooted as
+    is currently done for /lib/init/rw setup.  Following a reboot, the
+    old paths will continue to be available via bind mounts.  For
+    wheezy, packages must continue to use the existing paths because
+    /run is not guaranteed to be present.  In wheezy+1, all paths under
+    /run can be relied upon, and the old paths can be switched to be
+    symlinks (maybe only for clean installs?) or kept as bind mounts.
+    - initscripts.postinst:
+      Trigger reboot to complete transition.
+      If the system has not yet transitioned to a tmpfs-based /run, set up
+      bind mounts as follows:
+        /var/run → /run
+        /var/lock → /run/lock
+        /lib/init/rw → /run/init
+      On reboot, the system will complete the migration to a tmpfs-based
+      /run; this creates the directory heierachy from the old paths to
+      enable the use of the new /run paths prior to a restart.  This means
+      packages may transition to using /run with a versioned dependency
+      upon initscripts, rather than waiting for the release of wheezy.
+      Remove special handling for RAMRUN and RAMLOCK, which is now taken
+      care of by /run.
+    - debian/src/initscripts/doc/README.Debian:
+      Document new use of RUN_SIZE and LOCK_SIZE.
+      Refer to /run/init rather than /lib/init/rw.
+    - debian/src/initscripts/etc/init.d/checkroot.sh:
+      Use /run/init in place of /lib/init/rw.
+    - debian/src/initscripts/etc/init.d/mountkernfs.sh:
+      Create /run/init, /run/init/sendsigs.omit.d and /run/lock.
+      Bind mount /run/init to /lib/init/rw for backward compatibility.
+      Mount /run/lock as a separate tmpfs if RAMLOCK=yes.
+      /run/lock has 01777 permissions to match /var/lock.
+      Drop mounting of /var/run and /var/lock.
+    - debian/src/initscripts/etc/init.d/mtab.sh:
+      domtab mirrors behaviour of domount in mount-functions exactly, to
+      prevent duplicate mounts.
+      Bind mount /run/init and drop mounting of /var/run.  Mount /run/lock
+      in place of /var/lock.
+    - debian/src/initscripts/etc/init.d/sendsigs:
+      Support both old and new paths:
+        files: /run/sendsigs.omit /run/init/sendsigs.omit
+               /var/run/sendsigs.omit /lib/init/rw/sendsigs.omit
+        dirs: /run/init/sendsigs.omit.d/ /lib/init/rw/sendsigs.omit.d/
+      Support for both is required to allow clean shutdown of systems
+      both after an upgrade but before reboot (old paths) and after an
+      upgrade after reboot (new paths).
+    - debian/src/initscripts/etc/init.d/umountfs:
+      Ignore /run.  Continue to ignore /lib/init/rw in order to handle
+      clean shutdown.  Also continue to ignore /var/run and /var/lock
+      Check for presence of .ramfs than configuration variable when
+      skipping /var/run and /var/lock.
+    - debian/src/initscripts/etc/init.d/umountnfs.sh:
+      Check for presence of .ramfs than configuration variable when
+      skipping /var/run and /var/lock.
+      Ignore /run.  Continue to ignore /lib/init/rw in order to handle
+      clean shutdown.  Also continue to ignore /var/run and /var/lock
+      if mounted as tmpfs in order to cleanly shutdown.
+    - debian/src/initscripts/lib/init/bootclean.sh
+      Check for presence of .ramfs than configuration variable when
+      cleaning /var/run and /var/lock.
+    - debian/src/initscripts/lib/init/mount-functions.sh:
+      Drop support for mounting /var/run and /var/lock as separate
+      tmpfs filesystems.  Symlink /var/run to /run and /var/lock to
+      /run/lock if possible.  If /var/run and /var/lock are directories,
+      attempt to remove and symlink if successful, or else bind mount.
+    - debian/src/initscripts/man/rcS.5:
+      Drop documentation of RAMRUN.  Update documentation for RAMLOCK.
+    - debian/src/initscripts/Makefile: /lib/init/rw is created as a
+      symlink to /run.
+      TODO: Given that it's a directory and in use as a mountpoint on
+      upgrades, this probably won't work.  Maybe create as a symlink
+      for new installs only.  Since /lib might be read only, we can't
+      assume that we can change it at boot time.
+
+ -- Roger Leigh <rle...@debian.org>  Wed, 30 Mar 2011 21:17:49 +0100
+
+ sysvinit (2.88dsf-13.1) unstable; urgency=low
+ 
+   * Non-maintainer upload.
+
+ -- Roger Leigh <rle...@debian.org>  Fri, 01 Apr 2011 00:26:11 +0100
+
 sysvinit (2.88dsf-14) UNRELEASED; urgency=low
 
   [ Petter Reinholdtsen ]

Attachment: signature.asc
Description: Digital signature

Reply via email to