[CRIU] [PATCH 6/6] vzctl: checkpoint/restoer of upstream CTs

Andrey Vagin avagin at openvz.org
Thu May 16 08:14:52 EDT 2013


It can be done by any third party tools.
sripts/ct-cpt and script/ct_rst are executed to dump and restore CT
This patch adds scripts for CRIU.

v2: add the GPL header and descriptions in scripts
    describe and check variables in scripts

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 scripts/Makefile.am |   4 +-
 scripts/vps-cpt.in  |  54 ++++++++++++++++++++++++++
 scripts/vps-rst.in  |  51 ++++++++++++++++++++++++
 src/lib/hooks_ct.c  | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 vzctl.spec          |   2 +
 5 files changed, 218 insertions(+), 2 deletions(-)
 create mode 100755 scripts/vps-cpt.in
 create mode 100755 scripts/vps-rst.in

diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 0221973..05381f8 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -27,7 +27,9 @@ script_SCRIPTS = \
 	vps-net_del \
 	vzevent-stop \
 	vzevent-reboot \
-	vps-pci
+	vps-pci	\
+	vps-cpt \
+	vps-rst
 
 EXTRA_DIST = \
 	$(script_SCRIPTS:%=%.in)
diff --git a/scripts/vps-cpt.in b/scripts/vps-cpt.in
new file mode 100755
index 0000000..fe65ee8
--- /dev/null
+++ b/scripts/vps-cpt.in
@@ -0,0 +1,54 @@
+#!/bin/sh
+#  Copyright (C) 2012, Parallels, Inc. 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
+#
+#
+# Checkpoint a container using the criu.
+# Useful for running in non-OpenVZ kernels.
+#
+# Parameters are passed in environment variables.
+# Required parameters:
+#   VE_ROOT	- container root directory
+#   VE_DUMP_DIR - directory for saving dump files 
+#   VE_PID	- PID of the init process
+#
+
+exec 1>&2
+. @SCRIPTDIR@/vps-functions
+
+vzcheckvar VE_ROOT
+vzcheckvar VE_PID
+vzcheckvar VE_DUMP_DIR
+
+mkdir $CT_CR_DIR &&
+criu dump	--file-locks		\
+		--tcp-established	\
+		--evasive-devices	\
+		--link-remap		\
+		--root $VE_ROOT		\
+		-t $VE_PID		\
+		-D $VE_DUMP_DIR		\
+		-o dump.log		\
+		-vvvv
+if [ $? -ne 0 ]; then
+	[ -d $VE_DUMP_DIR.fail ] && rm -rf $VE_DUMP_DIR.fail
+	mv -f $VE_DUMP_DIR $VE_DUMP_DIR.fail
+	echo Failed to checkpoint the Container
+	echo All dump files and logs were saved in $VE_DUMP_DIR.fail
+	exit 1
+else
+	echo Checkpointing finished successfully
+fi
diff --git a/scripts/vps-rst.in b/scripts/vps-rst.in
new file mode 100755
index 0000000..6fe9502
--- /dev/null
+++ b/scripts/vps-rst.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+#  Copyright (C) 2012, Parallels, Inc. 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
+#
+#
+# Resume a container using the criu.
+# Useful for running in non-OpenVZ kernels.
+#
+# Parameters are passed in environment variables.
+# Required parameters:
+#   VE_ROOT	  - container root directory
+#   VE_DUMP_DIR	  - directory for saving dump files
+#   VE_STATE_FILE - file, where PID of the init process will be saved
+#
+
+exec 1>&2
+. @SCRIPTDIR@/vps-functions
+
+vzcheckvar VE_ROOT
+vzcheckvar VE_STATE_FILE
+vzcheckvar VE_DUMP_DIR
+
+criu restore	--file-locks		\
+		--tcp-established	\
+		--evasive-devices	\
+		--link-remap		\
+		--root $VE_ROOT		\
+		--restore-detached	\
+		-D $VE_DUMP_DIR		\
+		-o restore.log		\
+		-vvvv			\
+		--pidfile $VE_STATE_FILE
+if [ $? -eq 0 ]; then
+	rm -rf $VE_DUMP_DIR
+else
+	echo The restore log was saved in $VE_DUMP_DIR/restore.log
+	exit 1
+fi
diff --git a/src/lib/hooks_ct.c b/src/lib/hooks_ct.c
index 8c98289..c1f8cd9 100644
--- a/src/lib/hooks_ct.c
+++ b/src/lib/hooks_ct.c
@@ -17,6 +17,7 @@
 #include "logger.h"
 #include "script.h"
 #include "cgroup.h"
+#include "cpt.h"
 
 #define NETNS_RUN_DIR "/var/run/netns"
 
@@ -307,7 +308,11 @@ int ct_env_create(struct arg_start *arg)
 		return VZ_RESOURCE_ERROR;
 	}
 
-	ret = ct_env_create_real(arg);
+	if (arg->fn)
+		ret = arg->fn(arg->h, arg->veid, &arg->res->fs,
+				arg->wait_p, arg->old_wait_p, arg->err_p, arg->data);
+	else
+		ret = ct_env_create_real(arg);
 	if (ret < 0)
 		return VZ_RESOURCE_ERROR;
 
@@ -599,6 +604,106 @@ static int ct_setcontext(envid_t veid)
 	return 0;
 }
 
+static int ct_chkpnt(vps_handler *h, envid_t veid,
+			const fs_param *fs, int cmd, cpt_param *param)
+{
+	const char *dumpfile = NULL;
+	char statefile[STR_SIZE], buf[STR_SIZE];
+	char *arg[2], *env[4];
+	FILE *sfile;
+	pid_t pid;
+	int ret;
+
+	ret = VZ_CHKPNT_ERROR;
+
+	get_dump_file(veid, param->dumpdir, buf, sizeof(buf));
+	dumpfile = strdup(buf);
+
+	arg[0] = SCRIPTDIR "/vps-cpt";
+	arg[1] = NULL;
+
+	get_state_file(veid, statefile, sizeof(statefile));
+	sfile = fopen(statefile, "r");
+	if (sfile == NULL) {
+		logger(-1, errno, "Unable to open %s", statefile);
+		return VZ_CHKPNT_ERROR;
+	}
+
+	ret = fscanf(sfile, "%d", &pid);
+	if (ret != 1) {
+		logger(-1, errno, "Unable to read PID from %s", statefile);
+		fclose(sfile);
+		return VZ_CHKPNT_ERROR;
+	}
+	fclose(sfile);
+
+	snprintf(buf, sizeof(buf), "VE_ROOT=%s", fs->root);
+	env[0] = strdup(buf);
+	snprintf(buf, sizeof(buf), "VE_PID=%d", pid);
+	env[1] = strdup(buf);
+	snprintf(buf, sizeof(buf), "VE_DUMP_DIR=%s", dumpfile);
+	env[2] = strdup(buf);
+	env[3] = NULL;
+
+	if (run_script(arg[0], arg, env, 0))
+		return ret;
+
+	return 0;
+}
+
+static int ct_env_restore(vps_handler *h, envid_t veid, const fs_param *fs,
+			  int wait_p, int old_wait_p, int err_p, void *data)
+{
+	char *argv[2], *env[4];
+	const char *dumpfile = NULL;
+	const char *statefile = NULL;
+	cpt_param *param = data;
+	char buf[STR_SIZE];
+	pid_t pid = -1;
+	FILE *sfile;
+
+	get_dump_file(veid, param->dumpdir, buf, sizeof(buf));
+	dumpfile = strdup(buf);
+
+	get_state_file(veid, buf, sizeof(buf));
+	statefile = strdup(buf);
+
+	argv[0] = SCRIPTDIR "/vps-rst";
+	argv[1] = NULL;
+
+	snprintf(buf, sizeof(buf), "VE_ROOT=%s", fs->root);
+	env[0] = strdup(buf);
+	snprintf(buf, sizeof(buf), "VE_DUMP_DIR=%s", dumpfile);
+	env[1] = strdup(buf);
+	snprintf(buf, sizeof(buf), "VE_STATE_FILE=%s", statefile);
+	env[2] = strdup(buf);
+	env[3] = NULL;
+	if (run_script(argv[0], argv, env, 0))
+		return -1;
+
+	sfile = fopen(statefile, "r");
+	if (sfile == NULL) {
+		logger(-1, errno, "Unable to open %s", statefile);
+		goto err_destroy;
+	}
+
+	if (fscanf(sfile, "%d", &pid) != 1)
+		logger(-1, errno, "Unable to read PID from %s", statefile);
+
+	fclose(sfile);
+err_destroy:
+	if (pid < 0)
+		destroy_container(veid);
+
+	return pid;
+}
+
+static int ct_restore(vps_handler *h, envid_t veid, vps_param *vps_p, int cmd,
+	cpt_param *param, skipFlags skip)
+{
+	return vps_start_custom(h, veid, vps_p, SKIP_CONFIGURE | skip, NULL, ct_env_restore, param);
+}
+
 int ct_do_open(vps_handler *h)
 {
 	int ret;
@@ -632,6 +737,8 @@ int ct_do_open(vps_handler *h)
 	h->enter = ct_enter;
 	h->destroy = ct_destroy;
 	h->env_create = ct_env_create;
+	h->env_chkpnt = ct_chkpnt;
+	h->env_restore = ct_restore;
 	h->setlimits = ct_setlimits;
 	h->setcpus = ct_setcpus;
 	h->setcontext = ct_setcontext;
diff --git a/vzctl.spec b/vzctl.spec
index f77d326..9fe947b 100644
--- a/vzctl.spec
+++ b/vzctl.spec
@@ -221,6 +221,8 @@ OpenVZ containers control utility core package
 %{_scriptdir}/vzevent-stop
 %{_scriptdir}/vzevent-reboot
 %{_scriptdir}/vps-pci
+%{_scriptdir}/vps-cpt
+%{_scriptdir}/vps-rst
 /etc/vz/conf
 %config(noreplace) %{_configdir}/vz.conf
 %config(noreplace) %{_configdir}/osrelease.conf
-- 
1.8.2



More information about the CRIU mailing list