[CRIU] [PATCH] scripts: save and restore target mount for autofs service

Stanislav Kinsburskiy skinsbursky at virtuozzo.com
Fri Apr 29 03:38:49 PDT 2016


This patch slightly changes the logic on systemd autofs service restart script:

1) It tries to bind-mount the mountpoint on top of autofs (if any) somewhere
before service restart, and replace new mount point on top of autofs (if any)
by the saved one after.

2) It doesn't exit in case of error, trying to recover as much as
possible in case of failure instead and then continue services restarting.

The reason for introducing new logic is that there can be some other,
stateful, file system on top of autofs (say, tmpfs), which state was restore
during migration.
With current script this state will be lost, while this patch allows to
preserve restored mount point after service restart.

Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
---
 scripts/systemd-autofs-restart.sh |   92 +++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 6 deletions(-)

diff --git a/scripts/systemd-autofs-restart.sh b/scripts/systemd-autofs-restart.sh
index 9d9e2f3..9b02e11 100755
--- a/scripts/systemd-autofs-restart.sh
+++ b/scripts/systemd-autofs-restart.sh
@@ -41,15 +41,95 @@ JOIN_CT="$NS_ENTER -t $CRTOOLS_INIT_PID -m -u -p"
 
 AUTOFS_SERVICES="proc-sys-fs-binfmt_misc.automount"
 
+bindmount=""
+
+function remove_bindmount {
+	if [ -n "$bindmount" ]; then
+		$JOIN_CT umount $bindmount
+		$JOIN_CT rm -rf $bindmount
+		bindmount=""
+	fi
+}
+trap remove_bindmount EXIT
+
+function check_fs_type {
+	local mountpoint=$1
+	local fs_type=$2
+
+	[  "$($JOIN_CT stat -f --printf=%T $mountpoint)" = "$fs_type" ]
+}
+
+function bind_mount {
+	local from=$1
+	local to=$2
+
+	$($JOIN_CT mount --bind $from $to) && return 0
+
+	echo "Failed to bind mount $from to $to"
+	return 1
+}
+
+function save_mountpoint {
+	local mountpoint=$1
+
+	# Nothing to do, if no file system is on top of autofs
+	check_fs_type $mountpoint "autofs" && return
+
+	bindmount=`$JOIN_CT mktemp -d`
+	if [ -z "$bindmount" ]; then
+		echo "Failed to create temporary directory"
+		return
+	fi
+
+	# No need to unmount fs on top of autofs:
+	# systemd will does it for us on service restart
+	bind_mount $mountpoint $bindmount || $JOIN_CT rm -rf $bindmount
+}
+
+function restore_mountpoint {
+	local mountpoint=$1
+
+	[ -n "$bindmount" ] || exit 0
+
+	# Umount file system, remounted by systemd, if any
+	if ! check_fs_type $mountpoint "autofs"; then
+		$($JOIN_CT umount $mountpoint) || echo "Failed to umount $mountpoint"
+	fi
+
+	# Restore origin file system even if we failed to unmount the new one
+	bind_mount $bindmount $mountpoint
+	remove_bindmount
+}
+
+function restart_service {
+	local service=$1
+	local mountpoint=`$JOIN_CT systemctl show $service -p Where | sed 's/.*=//g'`
+
+	if [ -z "$mountpoint" ]; then
+		echo "Failed to discover $service mountpoint"
+		return
+	fi
+
+	# Try to move restored bind-mount aside and exit if Failed
+	# Nothing to do, if we Failed
+	save_mountpoint $mountpoint || return
+
+	$JOIN_CT systemctl restart $service
+	if [ $? -ne 0 ]; then
+		echo "Failed to restart $service service"
+		return
+	fi
+	echo "$service restarted"
+
+	# Try to move saved monutpoint back on top of autofs
+	restore_mountpoint $mountpoint
+}
+
 for service in $AUTOFS_SERVICES; do
 	status=$($JOIN_CT systemctl is-active $service)
+
 	if [ $status == "active" ]; then
-		$JOIN_CT systemctl restart $service
-		if [ $? -ne 0 ]; then
-			echo "Failed to restart $service service"
-			exit 2
-		fi
-		echo "$service restarted"
+		restart_service $service
 	else
 		echo "$service skipped ($status)"
 	fi



More information about the CRIU mailing list