From 58a8c9eb07c2cff6232c20f9a59edc634bb1e5e0 Mon Sep 17 00:00:00 2001 From: Jingxian He Date: Wed, 19 May 2021 21:59:24 +0800 Subject: [PATCH 32/72] task_exit_notify: add task exit notify mask method for criu Add task exit notify mask method for criu during kernel module upgrade. Signed-off-by: Jingxian He Signed-off-by: fu.lin --- criu/Makefile.crtools | 1 + criu/config.c | 1 + criu/cr-restore.c | 10 ++++++++++ criu/crtools.c | 1 + criu/exit-notify.c | 34 ++++++++++++++++++++++++++++++++++ criu/include/cr_options.h | 1 + criu/include/exit-notify.h | 10 ++++++++++ criu/seize.c | 10 +++++++++- 8 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 criu/exit-notify.c create mode 100644 criu/include/exit-notify.h diff --git a/criu/Makefile.crtools b/criu/Makefile.crtools index 2e82912..65cc215 100644 --- a/criu/Makefile.crtools +++ b/criu/Makefile.crtools @@ -93,6 +93,7 @@ obj-y += timens.o obj-y += pin-mem.o obj-y += devname.o obj-y += files-chr.o +obj-y += exit-notify.o obj-$(CONFIG_HAS_LIBBPF) += bpfmap.o obj-$(CONFIG_COMPAT) += pie-util-vdso-elf32.o CFLAGS_pie-util-vdso-elf32.o += -DCONFIG_VDSO_32 diff --git a/criu/config.c b/criu/config.c index cf99fb1..bd0f84d 100644 --- a/criu/config.c +++ b/criu/config.c @@ -703,6 +703,7 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd, BOOL_OPT("with-notifier", &opts.with_notifier_kup), BOOL_OPT("dump-char-dev", &opts.dump_char_dev), BOOL_OPT("with-fd-cred", &opts.with_fd_cred), + BOOL_OPT("mask-exit-notify", &opts.mask_exit_notify), {}, }; diff --git a/criu/cr-restore.c b/criu/cr-restore.c index ac677a1..09f135b 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -82,6 +82,7 @@ #include "apparmor.h" #include "pin-mem.h" #include "notifier.h" +#include "exit-notify.h" #include "parasite-syscall.h" #include "files-reg.h" @@ -1542,6 +1543,15 @@ static inline int fork_with_pid(struct pstree_item *item) pr_debug("PID: real %d virt %d\n", item->pid->real, vpid(item)); } + if (opts.mask_exit_notify) { + int pid = ret; + + pr_info("Start unmask exit notifier for pid %d\n", pid); + ret = mask_task_exit_notify(pid, false); + if (ret) + pr_err("Can't unmask exit notifier for pid %d\n", pid); + } + err_unlock: if (!(ca.clone_flags & CLONE_NEWPID)) unlock_last_pid(); diff --git a/criu/crtools.c b/criu/crtools.c index ed7bd99..1a41be4 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -454,6 +454,7 @@ usage: " --dump-char-dev Dump char dev files as normal file with repair cmd\n" \ " --with-fd-cred Allow to make the restored process has the same cred\n" + " --mask-exit-notify Mask task exit notify during dump and restore\n" "\n" "Check options:\n" " Without options, \"criu check\" checks availability of absolutely required\n" diff --git a/criu/exit-notify.c b/criu/exit-notify.c new file mode 100644 index 0000000..5c86724 --- /dev/null +++ b/criu/exit-notify.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +#include "exit-notify.h" +#include "log.h" + +int mask_task_exit_notify(int pid, bool mask) +{ + int fd, retval; + char buf[PID_BUF_SIZE] = {0}; + + if (pid <= 0) + return -1; + + snprintf(buf, PID_BUF_SIZE - 1, "%d", pid); + if (mask) + fd = open(MASK_EXIT_NOTIFY_DIR, O_WRONLY, 0); + else + fd = open(UNMASK_EXIT_NOTIFY_DIR, O_WRONLY, 0); + + if (fd < 0) { + pr_err("open mask exit notify file fail\n"); + return fd; + } + + retval = write(fd, buf, PID_BUF_SIZE); + if (retval < 0) + pr_err("Write mask exit pid: %s fail\n", buf); + close(fd); + + return retval < 0 ? -1 : 0; +} diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h index 1d6ddcf..26ae5b6 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -195,6 +195,7 @@ struct cr_options { int with_notifier_kup; int dump_char_dev; int with_fd_cred; + int mask_exit_notify; }; extern struct cr_options opts; diff --git a/criu/include/exit-notify.h b/criu/include/exit-notify.h new file mode 100644 index 0000000..34f2c8d --- /dev/null +++ b/criu/include/exit-notify.h @@ -0,0 +1,10 @@ +#ifndef __CRIU_EXIT_NOTIFY_H__ +#define __CRIU_EXIT_NOTIFY_H__ + +#define PID_BUF_SIZE 32 +#define MASK_EXIT_NOTIFY_DIR "/sys/kernel/mask_exit_notify" +#define UNMASK_EXIT_NOTIFY_DIR "/sys/kernel/unmask_exit_notify" + +int mask_task_exit_notify(int pid, bool mask); + +#endif /* __CRIU_EXIT_NOTIFY_H__ */ diff --git a/criu/seize.c b/criu/seize.c index 8a35c3c..1e127ff 100644 --- a/criu/seize.c +++ b/criu/seize.c @@ -24,6 +24,8 @@ #include "xmalloc.h" #include "util.h" #include "pin-mem.h" +#include "mem.h" +#include "exit-notify.h" #define NR_ATTEMPTS 5 @@ -636,7 +638,7 @@ free: static void unseize_task_and_threads(const struct pstree_item *item, int st) { - int i; + int i, ret; if (item->pid->state == TASK_DEAD) return; @@ -646,6 +648,12 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st) dump_task_special_pages(item->threads[i].real); } + if (opts.mask_exit_notify && (st == TASK_DEAD)) { + ret = mask_task_exit_notify(item->threads[0].real, true); + if (ret) + pr_err("mask exit notify for %d fail.\n", item->threads[0].real); + } + /* * The st is the state we want to switch tasks into, * the item->state is the state task was in when we seized one. -- 2.34.1