Skip to content

Commit

Permalink
Merge pull request #743 from rst0git/criu-join-ns
Browse files Browse the repository at this point in the history
criu: Enable support for restore of shared IPC, UTS and Time namespaces
  • Loading branch information
giuseppe authored Oct 5, 2021
2 parents e1979a2 + 762269c commit b30c6fc
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 25 deletions.
49 changes: 26 additions & 23 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AC_PREREQ([2.69])
AC_INIT([crun],
m4_esyscmd([build-aux/git-version-gen --prefix "" .tarball-version]),
[[email protected]])
m4_esyscmd([build-aux/git-version-gen --prefix "" .tarball-version]),
[[email protected]])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
Expand Down Expand Up @@ -33,9 +33,9 @@ AC_ARG_ENABLE(embedded-yajl,
AS_HELP_STRING([--enable-embedded-yajl], [Statically link a modified yajl version]),
[
case "${enableval}" in
yes) embedded_yajl=true ;;
no) embedded_yajl=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-embedded-yajl) ;;
yes) embedded_yajl=true ;;
no) embedded_yajl=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-embedded-yajl) ;;
esac],[embedded_yajl=false])

AM_CONDITIONAL([HAVE_EMBEDDED_YAJL], [test x"$embedded_yajl" == xtrue])
Expand All @@ -57,7 +57,7 @@ AS_IF([test "x$enable_caps" != "xno"], [
dnl dl
AC_ARG_ENABLE([dl], AS_HELP_STRING([--disable-dl], [Disable dynamic libraries support]))
AS_IF([test "x$enable_dl" != "xno"], [
AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_DLOPEN], 1, [Define if DLOPEN is available])], [])
AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_DLOPEN], 1, [Define if DLOPEN is available])], [])
])

dnl include support for libkrun (EXPERIMENTAL)
Expand Down Expand Up @@ -96,11 +96,11 @@ AS_IF([test "x$enable_bpf" != "xno"], [
#include <unistd.h>
#include <stdint.h>
#include <linux/bpf.h>
void foo() {
void foo() {
uint64_t val = 0x123456789;
union bpf_attr attr;
attr.insns = val;
}
}
int program = BPF_PROG_TYPE_CGROUP_DEVICE;
]])],
[AC_MSG_RESULT(yes)
Expand All @@ -112,22 +112,24 @@ AS_IF([test "x$enable_bpf" != "xno"], [

AC_ARG_WITH([python-bindings], AS_HELP_STRING([--with-python-bindings], [build the Python bindings]))
AS_IF([test "x$with_python_bindings" = "xyes"], [
PKG_CHECK_MODULES([PYTHON], [python3], [], [AC_MSG_ERROR([*** python headers not found])])
# configure should not touch CFLAGS/LDFLAGS but we need it to propagate it
# to libocispec.
CFLAGS+=" -fPIC "
LDFLAGS+=" -fPIC "
PKG_CHECK_MODULES([PYTHON], [python3], [], [AC_MSG_ERROR([*** python headers not found])])
# configure should not touch CFLAGS/LDFLAGS but we need it to propagate it
# to libocispec.
CFLAGS+=" -fPIC "
LDFLAGS+=" -fPIC "
])

dnl criu
AC_ARG_ENABLE([criu], AS_HELP_STRING([--disable-criu], [Disable CRIU based checkpoint/restore support]))
AS_IF([test "x$enable_criu" != "xno"], [
PKG_CHECK_MODULES([CRIU], [criu >= 3.15], [have_criu="yes"], [have_criu="no"
AC_MSG_NOTICE([CRIU headers not found, building without CRIU support])])
AS_IF([test "$have_criu" = "yes"], [
AC_DEFINE([HAVE_CRIU], 1, [Define if CRIU is available])
AC_SEARCH_LIBS(criu_init_opts, [criu])
])
PKG_CHECK_MODULES([CRIU], [criu >= 3.15], [have_criu="yes"], [have_criu="no"
AC_MSG_NOTICE([CRIU headers not found, building without CRIU support])])
PKG_CHECK_MODULES([CRIU], [criu > 3.16], [have_criu_join_ns="yes"], [have_criu_join_ns="no"
AC_MSG_NOTICE([CRIU version doesn't support join-ns API])])
AS_IF([test "$have_criu" = "yes"], [
AC_DEFINE([HAVE_CRIU], 1, [Define if CRIU is available])
AC_SEARCH_LIBS(criu_init_opts, [criu])
])
], [AC_MSG_NOTICE([CRIU support disabled per user request])])

FOUND_LIBS=$LIBS
Expand All @@ -138,10 +140,10 @@ AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
#include <linux/mount.h>
int cmd = FSCONFIG_CMD_CREATE;
]])],
[AC_MSG_RESULT(yes)
]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_FSCONFIG_CMD_CREATE], 1, [Define if FSCONFIG_CMD_CREATE is available])],
[AC_MSG_RESULT(no)])
[AC_MSG_RESULT(no)])

AC_MSG_CHECKING([for seccomp notify API])
AC_COMPILE_IFELSE(
Expand All @@ -163,13 +165,14 @@ AC_SUBST([RPM_VERSION])

AC_CHECK_TOOL(GPERF, gperf)
if test -z "$GPERF"; then
AC_MSG_NOTICE(gperf not found - cannot rebuild signal parser code)
AC_MSG_NOTICE(gperf not found - cannot rebuild signal parser code)
fi

AC_SEARCH_LIBS([argp_parse], [argp], [], [AC_MSG_ERROR([*** argp functions not found - install libargp or argp_standalone])])

AM_CONDITIONAL([PYTHON_BINDINGS], [test "x$with_python_bindings" = "xyes"])
AM_CONDITIONAL([CRIU_SUPPORT], [test "x$have_criu" = "xyes"])
AM_CONDITIONAL([CRIU_JOIN_NS_SUPPORT], [test "x$have_criu_join_ns" = "xyes"])

AC_CONFIG_FILES([Makefile rpm/crun.spec])

Expand Down
44 changes: 42 additions & 2 deletions src/libcrun/criu.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
# define CRIU_EXT_NETNS "extRootNetNS"
# define CRIU_EXT_PIDNS "extRootPidNS"

# ifndef CLONE_NEWTIME
# define CLONE_NEWTIME 0x00000080 /* New time namespace */
# endif

static const char *console_socket = NULL;

static int
Expand Down Expand Up @@ -645,8 +649,18 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru
goto out_umount;
}

/* If there is a PID or network namespace defined in config.json we are telling
* CRIU to restore the process into that namespace.
# ifdef CRIU_JOIN_NS_SUPPORT
/* criu_join_ns_add() API was introduced with CRIU version 3.16.1
* Here we check if this API is available at build time to support
* compiling with older version of CRIU, and at runtime to support
* running crun with older versions of libcriu.so.2.
*/
bool join_ns_support = criu_check_version (31601) == 1;
# endif

/* If a namespace defined in config.json we are telling
* CRIU use that namespace when restoring the process tree.
*
* CRIU expects the information about the namespace like this:
* --inherit-fd fd[<fd>]:<key>
* The <key> needs to be the same as during checkpointing (extRootNetNS). */
Expand All @@ -673,6 +687,32 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru

criu_add_inherit_fd (inherit_new_pid_fd, CRIU_EXT_PIDNS);
}

# ifdef CRIU_JOIN_NS_SUPPORT
if (value == CLONE_NEWTIME && def->linux->namespaces[i]->path != NULL)
{
if (join_ns_support)
criu_join_ns_add ("time", def->linux->namespaces[i]->path, NULL);
else
return crun_make_error (err, 0, "Shared time namespace restore is supported in CRIU >= 3.16.1");
}

if (value == CLONE_NEWIPC && def->linux->namespaces[i]->path != NULL)
{
if (join_ns_support)
criu_join_ns_add ("ipc", def->linux->namespaces[i]->path, NULL);
else
return crun_make_error (err, 0, "Shared ipc namespace restore is supported in CRIU >= 3.16.1");
}

if (value == CLONE_NEWUTS && def->linux->namespaces[i]->path != NULL)
{
if (join_ns_support)
criu_join_ns_add ("uts", def->linux->namespaces[i]->path, NULL);
else
return crun_make_error (err, 0, "Shared uts namespace restore is supported in CRIU >= 3.16.1");
}
# endif
}

/* Tell CRIU if cgroup v1 needs to be handled. */
Expand Down
6 changes: 6 additions & 0 deletions tests/test_checkpoint_restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ def test_cr_with_ext_ns():
ns.update({'path': os.path.join(ns_path, 'pid')})
if ns['type'] == 'network':
ns.update({'path': os.path.join(ns_path, 'net')})
if ns['type'] == 'ipc':
ns.update({'path': os.path.join(ns_path, 'ipc')})
if ns['type'] == 'uts':
ns.update({'path': os.path.join(ns_path, 'uts')})
if ns['type'] == 'time':
ns.update({'path': os.path.join(ns_path, 'time')})

return run_cr_test(conf)

Expand Down

0 comments on commit b30c6fc

Please sign in to comment.