#!/bin/sh
#  Copyright (c) 2013-2017, Parallels International GmbH
# Copyright (c) 2017-2019 Virtuozzo International GmbH. All rights reserved.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#  Our contact details: Virtuozzo International GmbH, Vordergasse 59, 8200
#  Schaffhausen, Switzerland.
#
# Resume a container using CRIU (http://criu.org).
# Useful with recent upstream (i.e. non-OpenVZ) kernels.
# Requires criu to be installed.
#
# Parameters are passed in environment variables.
# Required parameters:
#   VE_ROOT       - container root directory
#   VE_DUMP_DIR   - directory for saving dump files
#   VE_INIT_PIDFILE- file to write CT init PID to
# Optional parameters:
#   VE_VETH_DEVS  - pair of veth names (CT=HW\n)
exec 1>&2
veth_args=""
for dev in $VE_VETH_DEVS; do
	veth_args="$veth_args --veth-pair $dev"
done

external=
# VE_PLOOP_DEVS=UUID@ploopN:major:minor:[root]
for s in $VE_PLOOP_DEVS; do
	uuid=${s%%@*}
	t=${s#*@}
	device=${t%%:*}
	t=${t#*:}
	major=${t%%:*}
	t=${t#*:}
	minor=${t%%:*}
	root=${t#*:}

	[ "$root" = "root" ] && continue

	external="$external --external dev[$uuid]:${device}"
done

ext_mount_map=
cgroup_root="--cgroup-root ve:/$VEID --cgroup-root beancounter:/$VEID"
for s in $VE_CGROUP_MOUNT_MAP; do
	ext_mount_map="$ext_mount_map --ext-mount-map $s"

	# For backward compatibility we must keep adding net_cls,net_prio map pointing
	# to the same location that net_cls points to.
	netprio=$(echo $s | awk '/net_cls/{sub(/net_cls:/,"net_cls,net_prio:");print}')
	if [ -n "$netprio" ]; then
		ext_mount_map="$ext_mount_map --ext-mount-map $netprio"
	fi

	ctl=${s%%:*}
	t=${s#*/sys/fs/cgroup/}
	root=${t#*/}
	cgroup_root="$cgroup_root --cgroup-root $ctl:/$root"
done

for s in $VE_EXT_MOUNT_MAP; do
	ext_mount_map="$ext_mount_map --ext-mount-map $s"
done

action_script=/usr/libexec/libvzctl/scripts/vz-rst-action

d=$(dirname $VE_INIT_PIDFILE)
[ ! -d "$d" ] && mkdir -p "$d"

rm -f $VE_INIT_PIDFILE

# Setup default work directory if not explicitly specified
[ -z "$VE_WORK_DIR" ] && VE_WORK_DIR="$VE_DUMP_DIR"

# Setup VE specific settings (cgroup interface)
if [ -n "$VEID" ]; then
	[ -f $VE_DUMP_DIR/vz_clock_bootbased.img ] && export VE_CLOCK_BOOTBASED=`cat $VE_DUMP_DIR/vz_clock_bootbased.img`
	[ -f $VE_DUMP_DIR/vz_clock_monotonic.img ] && export VE_CLOCK_MONOTONIC=`cat $VE_DUMP_DIR/vz_clock_monotonic.img`
	[ -f $VE_DUMP_DIR/vz_iptables_mask.img ] && export VE_IPTABLES_MASK=`cat $VE_DUMP_DIR/vz_iptables_mask.img`
	[ -f $VE_DUMP_DIR/vz_os_release.img ] && export VE_OS_RELEASE=`cat $VE_DUMP_DIR/vz_os_release.img`
	[ -f $VE_DUMP_DIR/vz_features.img ] && export VE_FEATURES=`cat $VE_DUMP_DIR/vz_features.img`
	[ -f $VE_DUMP_DIR/vz_aio_max_nr.img ] && export VE_AIO_MAX_NR=`cat $VE_DUMP_DIR/vz_aio_max_nr.img`
	[ -f $VE_DUMP_DIR/vz_pid_max.img ] && export VE_PID_MAX=`cat $VE_DUMP_DIR/vz_pid_max.img`
fi

# Setup default log name if not explicitly specified
[ -z "$VE_RESTORE_LOG_PATH" ] && VE_RESTORE_LOG_PATH="restore.log"

# AutoFS actions
autofs_actions_path=/usr/libexec/criu/scripts/systemd-autofs-restart.sh
if [ -f "$autofs_actions_path" ]; then
	autofs_actions="--action-script $autofs_actions_path"
fi

CRIU_LOGLEVEL=4
[ -n "$VE_CRIU_PIDFILE" ] && echo $$ > $VE_CRIU_PIDFILE
exec criu restore -v$CRIU_LOGLEVEL				\
		--file-locks				\
		--tcp-established			\
		--evasive-devices			\
		--manage-cgroups			\
		--link-remap				\
		--root $VE_ROOT				\
		--restore-detached			\
		--action-script $action_script		\
		-D $VE_DUMP_DIR				\
		-W $VE_WORK_DIR				\
		-o $VE_RESTORE_LOG_PATH			\
		--pidfile $VE_INIT_PIDFILE		\
		$cgroup_root				\
		$ext_mount_map				\
		$autofs_actions				\
		$veth_args				\
		$external
