openrc-discuss

[PATCH] unmount /etc/ last when shutting down

David Flatz

Fri Dec 25 21:34:56 2009

Hi List.

I know it's crazy but I have /etc mounted on a separated fs.

After switching to openrc I encountered problems that "something"
segfaulted after rc-mount.sh unmounted /etc before some other mountpoints
which made my computer turn of without unmounting the rest cleanly.

I fixed my problem by adding /etc to no_umounts in /etc/conf.d/localmount
and changing /lib/rc/sh/rc-mount.sh to process /etc last.

I attached the quite ugly hackish patch to the mail.  I'd like to see that
problem fixed in openrc.

Regards,

David
--- /tmp/rc-mount.sh	2009-05-01 16:11:40.000000000 +0200
+++ sh/rc-mount.sh.new	2009-10-10 11:58:24.978290220 +0200
@@ -12,7 +12,7 @@
 do_unmount()
 {
 	local cmd="$1" retval=0 retry= pids=-
-	local f_opts="-m -c" f_kill="-s " mnt=
+	local f_opts="-m -c" f_kill="-s " mnt= doetc=
 	if [ "$RC_UNAME" = "Linux" ]; then
 		f_opts="-m"
 		f_kill="-"
@@ -26,6 +26,7 @@
 		# Unmounting a shared mount can unmount other mounts, so
 		# we need to check the mount is still valid
 		mountinfo --quiet "$mnt" || continue
+		[ "$mnt" = "/etc" ] && doetc=true && continue
 
 		case "$cmd" in
 			umount)
@@ -70,5 +71,56 @@
 			eend 0
 		fi
 	done
+
+	if [ $doetc ]; then
+		mnt="/etc"
+		# Unmounting a shared mount can unmount other mounts, so
+		# we need to check the mount is still valid
+		mountinfo --quiet "$mnt" || continue
+
+		case "$cmd" in
+			umount)
+				ebegin "Unmounting $mnt"
+				;;
+			*)
+				ebegin "Remounting $mnt read only"
+				;;
+		esac
+
+		retry=3
+		while ! LC_ALL=C $cmd "$mnt" 2>/dev/null; do
+			if type fuser >/dev/null 2>&1; then
+				pids="$(fuser $f_opts "$mnt" 2>/dev/null)"
+			fi
+			case " $pids " in
+				*" $$ "*)
+					eend 1 "failed because we are using" \
+					"$mnt"
+					retry=0;;
+				" - ")
+					eend 1
+					retry=0;;
+				"  ")
+					eend 1 "in use but fuser finds nothing"
+					retry=0;;
+				*)
+					local sig="KILL"
+					[ $retry -gt 0 ] && sig="TERM"
+					fuser $f_kill$sig -k $f_opts \
+						"$mnt" >/dev/null 2>&1
+					sleep 1
+					retry=$(($retry - 1))
+					[ $retry -le 0 ] && eend 1
+					;;
+			esac
+			[ $retry -le 0 ] && break
+		done
+		if [ $retry -le 0 ]; then
+			retval=1
+		else
+			eend 0
+		fi
+	fi
+
 	return $retval
 }

Archive administrator: postmaster@marples.name