From 80853f5dbc3a42419ac359ee035ebc76de86d3b3 Mon Sep 17 00:00:00 2001
From: "Robin H. Johnson" <robbat2@gentoo.org>
Date: Tue, 18 Jan 2011 01:26:34 +0000
Subject: sh/init: Detect a mounted /proc without sleeping

Previously we checked if /proc was alive by reading /proc/uptime twice
with a 1 second sleep between calls, so that it had time to update.
This got a complaint of an entire 1 second delay, so we improve the
check to be much faster without sleep. We cannot continue to use
/proc/uptime as it only has a 10ms resolution.

X-Gentoo-Bug: 348416
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=348416
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
---
 sh/init.sh.Linux.in | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

(limited to 'sh')

diff --git a/sh/init.sh.Linux.in b/sh/init.sh.Linux.in
index ad48585d..9b045570 100644
--- a/sh/init.sh.Linux.in
+++ b/sh/init.sh.Linux.in
@@ -65,19 +65,27 @@ mount_svcdir()
 # By default VServer already has /proc mounted, but OpenVZ does not!
 # However, some of our users have an old proc image in /proc
 # NFC how they managed that, but the end result means we have to test if
-# /proc actually works or not. We to this by comparing uptime to one a second
-# ago
+# /proc actually works or not. We to this by comparing two reads of
+# /proc/self/stat. They will not match, because at least the minor fault count
+# field (field 10) should have changed.
+#
+# We can use any file here that fills the following requirements:
+# - changes between sequential reads
+# - is world-readable (not blocked in hardened kernel)
+# - Is only a single line (ergo entire check is doable with no forks)
 mountproc=true
-if [ -e /proc/uptime ]; then
-	up="$(cat /proc/uptime)"
-	sleep 1
-	if [ "$up" = "$(cat /proc/uptime)" ]; then
+f=/proc/self/stat
+if [ -e $f ]; then
+	exec 9<$f ; read a <&9 ; exec 9<&-
+	exec 9<$f ; read b <&9 ; exec 9<&-
+	if [ "$a" = "$b" ]; then
 		eerror "You have cruft in /proc that should be deleted"
 	else
 		einfo "/proc is already mounted, skipping"
 		mountproc=false
 	fi
 fi
+unset a b f
 
 if $mountproc; then
 	procfs="proc"
-- 
cgit v1.2.3