diff --git a/Makefile.crtools b/Makefile.crtools index f55bdb783..ea813e539 100644 --- a/Makefile.crtools +++ b/Makefile.crtools @@ -75,6 +75,7 @@ obj-y += plugin.o obj-y += cr-errno.o obj-y += pie/pie-relocs.o obj-y += seize.o +obj-y += fault-injection.o obj-y += pie/util-fd.o obj-y += pie/util.o diff --git a/cr-dump.c b/cr-dump.c index 8eaf523c1..fea3be63f 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -81,6 +81,7 @@ #include "lsm.h" #include "seccomp.h" #include "seize.h" +#include "fault-injection.h" #include "asm/dump.h" @@ -1195,6 +1196,11 @@ static int dump_one_task(struct pstree_item *item) goto err; } + if (fault_injected(FI_DUMP_EARLY)) { + pr_info("fault: CRIU sudden detach\n"); + BUG(); + } + if (root_ns_mask & CLONE_NEWPID && root_item == item) { int pfd; diff --git a/cr-restore.c b/cr-restore.c index 2c812cda5..a33273c07 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -76,7 +76,7 @@ #include "security.h" #include "lsm.h" #include "seccomp.h" - +#include "fault-injection.h" #include "parasite-syscall.h" #include "protobuf.h" @@ -1531,6 +1531,11 @@ static int restore_task_with_children(void *_arg) if (prepare_sigactions() < 0) goto err_fini_mnt; + if (fault_injected(FI_RESTORE_ROOT_ONLY)) { + pr_info("fault: Restore root task failure!\n"); + BUG(); + } + if (create_children_and_session()) goto err_fini_mnt; diff --git a/crtools.c b/crtools.c index ea8b889f0..d3812a18f 100644 --- a/crtools.c +++ b/crtools.c @@ -40,6 +40,7 @@ #include "action-scripts.h" #include "security.h" #include "irmap.h" +#include "fault-injection.h" #include "setproctitle.h" @@ -257,6 +258,9 @@ int main(int argc, char *argv[], char *envp[]) BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); + if (fault_injection_init()) + return 1; + cr_pb_init(); if (restrict_uid(getuid(), getgid())) return 1; diff --git a/fault-injection.c b/fault-injection.c new file mode 100644 index 000000000..f239fd9db --- /dev/null +++ b/fault-injection.c @@ -0,0 +1,22 @@ +#include +#include "fault-injection.h" + +enum faults fi_strategy; + +int fault_injection_init() +{ + char *val; + int strat; + + val = getenv("CRIU_FAULT"); + if (val == NULL) + return 0; + + strat = atoi(val); + + if (strat <= 0 || strat >= FI_MAX) + return -1; + + fi_strategy = strat; + return 0; +} diff --git a/include/fault-injection.h b/include/fault-injection.h new file mode 100644 index 000000000..989f654b2 --- /dev/null +++ b/include/fault-injection.h @@ -0,0 +1,19 @@ +#ifndef __CR_FAULT_INJECTION_H__ +#define __CR_FAULT_INJECTION_H__ +#include + +enum faults { + FI_NONE = 0, + FI_DUMP_EARLY, + FI_RESTORE_ROOT_ONLY, + FI_MAX, +}; + +extern enum faults fi_strategy; +extern int fault_injection_init(void); + +static inline bool fault_injected(enum faults f) +{ + return fi_strategy == f; +} +#endif