diff mbox series

[4/4] nfs-utils: Start nfsv4 utilities with sysvinit

Message ID 20250212191518.1968329-4-danismostlikely@gmail.com
State Accepted, archived
Commit 2cca2dfb6acc25f1a6a25dc60423708a78cef85d
Headers show
Series [1/4] nfs-utils: clean up startup | expand

Commit Message

Dan McGregor Feb. 12, 2025, 7:12 p.m. UTC
From: Daniel McGregor <daniel.mcgregor@vecima.com>

Rewrite the nfs sysvinit scripts to start the services required
by nfsv4: gssd, idmapd, and statd.

Signed-off-by: Daniel McGregor <daniel.mcgregor@vecima.com>
---
 .../nfs-utils/nfs-utils/nfscommon             | 294 +++++++++++++++---
 .../nfs-utils/nfs-utils/nfsserver             |  43 ++-
 2 files changed, 289 insertions(+), 48 deletions(-)
diff mbox series

Patch

diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/nfscommon b/meta/recipes-connectivity/nfs-utils/nfs-utils/nfscommon
index 4f07324a21f..6c7b92bdb1b 100644
--- a/meta/recipes-connectivity/nfs-utils/nfs-utils/nfscommon
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/nfscommon
@@ -1,63 +1,279 @@ 
 #!/bin/sh
+
 ### BEGIN INIT INFO
 # Provides:          nfs-common
 # Required-Start:    $portmap $time
 # Required-Stop:     $portmap $time
 # Default-Start:     S
 # Default-Stop:      0 1 6
-# Short-Description: NFS support for both client and server
+# Short-Description: NFS support files common to client and server
 # Description:       NFS is a popular protocol for file sharing across
-#                    TCP/IP networks. This service provides various
+#		     TCP/IP networks. This service provides various
 #                    support functions for NFS mounts.
 ### END INIT INFO
-#
-# Startup script for nfs-utils
-#
-#
-# Location of executables:
 
-# Source function library.
+# What is this?
+DESC="NFS common utilities"
+
+# Read config
+DEFAULTFILE=/etc/default/nfs-utils
+NEED_STATD=
+NEED_GSSD=
+if nfsconf --isset general pipefs-directory; then
+    PIPEFS_MOUNTPOINT=$(nfsconf --get general pipefs-directory)
+else
+    PIPEFS_MOUNTPOINT=/var/lib/nfs/rpc_pipefs
+fi
+if [ -f $DEFAULTFILE ]; then
+    . $DEFAULTFILE
+fi
+
 . /etc/init.d/functions
 
-test -x "$NFS_STATD" || NFS_STATD=/usr/sbin/rpc.statd
-test -z "$STATD_PID" && STATD_PID=/run/rpc.statd.pid
+# Exit if required binaries are missing.
+[ -x /usr/sbin/rpc.statd ] || exit 0
+
 #
-# The default state directory is /var/lib/nfs
-test -n "$NFS_STATEDIR" || NFS_STATEDIR=/var/lib/nfs
+# Parse the fstab file, and determine whether we need gssd. (The
+# /etc/defaults settings, if any, will override our autodetection.) This code
+# is partially adapted from the mountnfs.sh script in the sysvinit package.
 #
-#----------------------------------------------------------------------
-# Startup and shutdown functions.
-#  Actual startup/shutdown is at the end of this file.
-
-start_statd(){
-	echo -n "starting statd: "
-	start-stop-daemon --start --exec "$NFS_STATD" --pidfile "$STATD_PID"
-	echo done
+AUTO_NEED_GSSD=no
+
+if [ -f /etc/fstab ]; then
+    exec 9<&0 </etc/fstab
+
+    while read -r DEV _ _ OPTS _
+    do
+	case $DEV in
+	    ''|\#*)
+		continue
+		;;
+	esac
+	OLDIFS="$IFS"
+	IFS=","
+	for OPT in $OPTS; do
+	    case "$OPT" in
+		sec=krb5|sec=krb5i|sec=krb5p)
+		    AUTO_NEED_GSSD=yes
+		;;
+	    esac
+	done
+	IFS="$OLDIFS"
+    done
+
+    exec 0<&9 9<&-
+fi
+
+case "$NEED_STATD" in
+    yes|no)
+        ;;
+    *)
+        NEED_STATD=yes
+        ;;
+esac
+
+case "$NEED_IDMAPD" in
+    yes|no)
+        ;;
+    *)
+        NEED_IDMAPD=yes
+	;;
+esac
+
+case "$NEED_GSSD" in
+    yes|no)
+        ;;
+    *)
+        NEED_GSSD=$AUTO_NEED_GSSD
+	;;
+esac
+
+do_modprobe() {
+    if [ -x /sbin/modprobe ] && [ -f /proc/modules ]
+    then
+        modprobe -q "$1" || true
+    fi
+}
+
+do_mount() {
+    if ! grep -E -qs "$1\$" /proc/filesystems
+    then
+	return 1
+    fi
+    if ! mountpoint -q "$2"
+    then
+	mount -t "$1" "$1" "$2"
+	return
+    fi
+    return 0
 }
-stop_statd(){
-	echo -n 'stopping statd: '
-	start-stop-daemon --stop --quiet --signal 1 --pidfile "$STATD_PID"
-	echo done
+
+do_umount() {
+    if mountpoint -q "$1"
+    then
+	umount "$1"
+    fi
+    return 0
 }
-#----------------------------------------------------------------------
-#
-# supported options:
-#  start
-#  stop
-#  restart: stops and starts mountd
-#FIXME: need to create the /var/lib/nfs/... directories
+
+# See how we were called.
 case "$1" in
   start)
-	start_statd;;
+	echo -n "Starting $DESC ..."
+
+	if [ "$NEED_STATD" = yes ]; then
+	    echo -n " statd"
+
+	    # See if rpcbind is running
+	    if [ -x /usr/sbin/rpcinfo ]; then
+		/usr/sbin/rpcinfo -p >/dev/null 2>&1
+		RET=$?
+		if [ $RET != 0 ]; then
+		   echo
+		   echo "Not starting: portmapper is not running"
+		   exit 0
+		fi
+	    fi
+	    start-stop-daemon --start --oknodo --quiet \
+		--pidfile /run/rpc.statd.pid \
+	        --exec /sbin/rpc.statd
+	    RET=$?
+	    if [ $RET != 0 ]; then
+	        echo " failed" $RET
+	        exit $RET
+	    else
+		if [ -d /run/sendsigs.omit.d ]; then
+		    rm -f /run/sendsigs.omit.d/statd
+		    ln -s /run/rpc.statd.pid /run/sendsigs.omit.d/statd
+		fi
+	    fi
+	fi
+
+	# Don't start idmapd and gssd if we don't have them (say, if /usr is not
+	# up yet).
+	[ -x /usr/sbin/rpc.idmapd ] || NEED_IDMAPD=no
+	[ -x /usr/sbin/rpc.gssd   ] || NEED_GSSD=no
+
+	if [ "$NEED_IDMAPD" = yes ] || [ "$NEED_GSSD" = yes ]
+	then
+	    do_modprobe sunrpc
+	    do_modprobe nfs
+	    do_modprobe nfsd
+	    mkdir -p "$PIPEFS_MOUNTPOINT"
+	    if do_mount rpc_pipefs $PIPEFS_MOUNTPOINT
+	    then
+	    	if [ "$NEED_IDMAPD" = yes ]
+		then
+	            ecno -n " idmapd"
+		    start-stop-daemon --start --oknodo --quiet \
+			    --exec /usr/sbin/rpc.idmapd
+		    RET=$?
+	            if [ $RET != 0 ]; then
+        	        echo " failed" $RET
+        	        exit $RET
+                    fi
+		fi
+		if [ "$NEED_GSSD" = yes ]
+		then
+		    do_modprobe rpcsec_gss_krb5
+	            echo -n " gssd"
+
+		    start-stop-daemon --start --oknodo --quiet \
+			    --exec /usr/sbin/rpc.gssd
+		    RET=$?
+	            if [ $RET != 0 ]; then
+        	        echo " failed" $RET
+        	        exit $RET
+                    fi
+		fi
+	    fi
+	fi
+	echo " done"
+	;;
+
   stop)
-	stop_statd;;
+	echo -n "Stopping $DESC ..."
+
+	if [ "$NEED_GSSD" = yes ]
+	then
+	    echo -n " gssd"
+	    start-stop-daemon --stop --oknodo --quiet \
+		    --name rpc.gssd
+	    RET=$?
+	    if [ $RET != 0 ]; then
+                echo " failed" $RET
+                exit $RET
+            fi
+	fi
+	if [ "$NEED_IDMAPD" = yes ]
+	then
+	    echo -n " idmapd"
+	    start-stop-daemon --stop --oknodo --quiet \
+		--name rpc.idmapd
+            RET=$?
+	    if [ $RET != 0 ]; then
+                echo " failed" $RET
+                exit $RET
+            fi
+	fi
+	if [ "$NEED_STATD" = yes ]
+	then
+	    echo -n " statd"
+	    start-stop-daemon --stop --oknodo --quiet \
+	        --name rpc.statd
+	    RET=$?
+	    if [ $RET != 0 ]; then
+                echo " failed" $RET
+                exit $RET
+            fi
+	fi
+	do_umount $PIPEFS_MOUNTPOINT 2>/dev/null || true
+	echo " done"
+	;;
+
   status)
-	status $NFS_STATD
-	exit $?;;
-  restart)
+	if [ "$NEED_STATD" = yes ]
+	then
+	    if ! pidof rpc.statd >/dev/null
+	    then
+	        echo "rpc.statd not running"
+	        exit 3
+	    fi
+	fi
+
+	if [ "$NEED_GSSD" = yes ]
+	then
+            if ! pidof rpc.gssd >/dev/null
+	    then
+		echo "rpc.gssd not running"
+		exit 3
+	    fi
+	fi
+
+	if [ "$NEED_IDMAPD" = yes ]
+	then
+            if ! pidof rpc.idmapd >/dev/null
+	    then
+		echo "rpc.idmapd not running"
+		exit 3
+	    fi
+	fi
+
+	echo "all daemons running"
+	exit 0
+	;;
+
+  restart | force-reload)
 	$0 stop
-	$0 start;;
+	sleep 1
+	$0 start
+	;;
+
   *)
-	echo "Usage: $0 {start|stop|status|restart}"
-	exit 1;;
+	echo "Usage: nfscommon {start|stop|status|restart}"
+	exit 1
+	;;
 esac
+
+exit 0
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/nfsserver b/meta/recipes-connectivity/nfs-utils/nfs-utils/nfsserver
index 0f5747cc6db..cb6c1b4d08d 100644
--- a/meta/recipes-connectivity/nfs-utils/nfs-utils/nfsserver
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/nfsserver
@@ -1,8 +1,10 @@ 
 #!/bin/sh
+
 ### BEGIN INIT INFO
 # Provides:          nfs-kernel-server
-# Required-Start:    $remote_fs nfs-common $portmap hwclock
-# Required-Stop:     $remote_fs nfs-common $portmap hwclock
+# Required-Start:    $remote_fs nfs-common $portmap $time
+# Required-Stop:     $remote_fs nfs-common $portmap $time
+# Should-Start:      $named
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
 # Short-Description: Kernel NFS server support
@@ -19,20 +21,25 @@ 
 #
 # The environment variable NFS_SERVERS may be set in /etc/default/nfsd
 # Other control variables may be overridden here too
-test -r /etc/default/nfsd && . /etc/default/nfsd
+test -r /etc/default/nfs-utils && . /etc/default/nfs-utils
 #
 # Location of executables:
 test -x "$NFS_MOUNTD" || NFS_MOUNTD=/usr/sbin/rpc.mountd
 test -x "$NFS_NFSD" || NFS_NFSD=/usr/sbin/rpc.nfsd
+test -x "$NFS_SVCGSSD" || NFS_SVCGSSD=/usr/sbin/rpc.svcgssd
 #
 # The user mode program must also exist (it just starts the kernel
 # threads using the kernel module code).
 test -x "$NFS_MOUNTD" || exit 0
 test -x "$NFS_NFSD" || exit 0
-#
-# Default is 8 threads, value is settable between 1 and the truely
-# ridiculous 99
-test "$NFS_SERVERS" != "" && test "$NFS_SERVERS" -gt 0 && test "$NFS_SERVERS" -lt 100 || NFS_SERVERS=8
+
+case "$NEED_SVCGSSD" in
+	yes|no)
+		;;
+	*)
+		NEED_SVCGSSD=no
+		;;
+esac
 #
 #----------------------------------------------------------------------
 # Startup and shutdown functions.
@@ -49,6 +56,22 @@  stop_mountd(){
 	echo done
 }
 #
+#svcgssd
+start_svcgssd(){
+	modprobe -q rpcsec_gss_krb5
+	if [ "$NEED_SVCGSSD" = "yes" ]; then
+		echo -n "starting svcgssd: "
+		start-stop-daemon --start --exec "$NFS_SVCGSSD" -- "$@"
+		echo done
+	fi
+}
+stop_svcgssd(){
+	if [ "$NEED_SVCGSSD" = "yes" ]; then
+		echo -n "stop svcgssd: "
+		start-stop-daemon --stop --exec "$NFS_SVCGSSD"
+		echo done
+	fi
+}
 #nfsd
 start_nfsd(){
         modprobe -q nfsd
@@ -62,7 +85,7 @@  start_nfsd(){
 		exit 1
         }
 
-	echo -n "starting $1 nfsd kernel threads: "
+	echo -n "starting nfsd: "
 	start-stop-daemon --start --exec "$NFS_NFSD" -- "$@"
 	echo done
 }
@@ -108,11 +131,13 @@  stop_nfsd(){
 case "$1" in
   start)
 	test -r /etc/exports && exportfs -r
-	start_nfsd "$NFS_SERVERS"
+	start_nfsd
+	start_svcgssd
 	start_mountd
 	test -r /etc/exports && exportfs -a;;
   stop)	exportfs -ua
 	stop_mountd
+	stop_svcgssd
 	stop_nfsd;;
   status)
 	status /usr/sbin/rpc.mountd