[CRIU] [PATCH 12/12] compel/criu: Add __must_check

Dmitry Safonov dima at arista.com
Sun Nov 10 01:20:45 MSK 2019


All those compel functions can fail by various reasons.
It may be status of the system, interruption by user or anything else.
It's really desired to handle as many PIE related errors as possible
otherwise it's hard to analyze statuses of parasite/restorer
and the C/R process.

At least warning for logs should be produced or even C/R stopped.

Signed-off-by: Dmitry Safonov <dima at arista.com>
---
 compel/include/uapi/cpu.h                |  2 +-
 compel/include/uapi/infect-rpc.h         |  6 ++--
 compel/include/uapi/infect-util.h        |  5 ++-
 compel/include/uapi/infect.h             | 39 +++++++++++++-----------
 compel/include/uapi/ptrace.h             |  7 +++--
 compel/include/uapi/sigframe-common.h    |  5 +--
 compel/plugins/include/uapi/plugin-fds.h |  2 +-
 compel/plugins/include/uapi/std/infect.h |  8 +++--
 compel/plugins/include/uapi/std/log.h    |  1 +
 criu/seize.c                             |  2 +-
 include/common/compiler.h                | 27 ++++++++++++++++
 11 files changed, 71 insertions(+), 33 deletions(-)

diff --git a/compel/include/uapi/cpu.h b/compel/include/uapi/cpu.h
index 6f827d44721f..72c8a516c2c0 100644
--- a/compel/include/uapi/cpu.h
+++ b/compel/include/uapi/cpu.h
@@ -6,7 +6,7 @@
 
 #include <compel/asm/cpu.h>
 
-extern int compel_cpuid(compel_cpuinfo_t *info);
+extern int /* TODO: __must_check */ compel_cpuid(compel_cpuinfo_t *info);
 extern bool compel_cpu_has_feature(unsigned int feature);
 extern bool compel_fpu_has_feature(unsigned int feature);
 extern uint32_t compel_fpu_feature_size(unsigned int feature);
diff --git a/compel/include/uapi/infect-rpc.h b/compel/include/uapi/infect-rpc.h
index 0176c114250d..180dedf1f6cd 100644
--- a/compel/include/uapi/infect-rpc.h
+++ b/compel/include/uapi/infect-rpc.h
@@ -6,9 +6,9 @@
 #include <stdint.h>
 
 struct parasite_ctl;
-extern int compel_rpc_sync(unsigned int cmd, struct parasite_ctl *ctl);
-extern int compel_rpc_call(unsigned int cmd, struct parasite_ctl *ctl);
-extern int compel_rpc_call_sync(unsigned int cmd, struct parasite_ctl *ctl);
+extern int __must_check compel_rpc_sync(unsigned int cmd, struct parasite_ctl *ctl);
+extern int __must_check compel_rpc_call(unsigned int cmd, struct parasite_ctl *ctl);
+extern int __must_check compel_rpc_call_sync(unsigned int cmd, struct parasite_ctl *ctl);
 extern int compel_rpc_sock(struct parasite_ctl *ctl);
 
 #define PARASITE_USER_CMDS	64
diff --git a/compel/include/uapi/infect-util.h b/compel/include/uapi/infect-util.h
index 7307ba57a0ef..4e32d13dc46d 100644
--- a/compel/include/uapi/infect-util.h
+++ b/compel/include/uapi/infect-util.h
@@ -1,6 +1,9 @@
 #ifndef __COMPEL_INFECT_UTIL_H__
 #define __COMPEL_INFECT_UTIL_H__
+
+#include "common/compiler.h"
+
 struct parasite_ctl;
-extern int compel_util_send_fd(struct parasite_ctl *ctl, int fd);
+extern int __must_check compel_util_send_fd(struct parasite_ctl *ctl, int fd);
 extern int compel_util_recv_fd(struct parasite_ctl *ctl, int *pfd);
 #endif
diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index 08beaffcdf34..dd672bc1c9a2 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -13,7 +13,7 @@
 
 #define PARASITE_START_AREA_MIN	(4096)
 
-extern int compel_interrupt_task(int pid);
+extern int __must_check compel_interrupt_task(int pid);
 
 struct seize_task_status {
 	unsigned long long	sigpnd;
@@ -23,27 +23,28 @@ struct seize_task_status {
 	int			seccomp_mode;
 };
 
-extern int compel_wait_task(int pid, int ppid,
+extern int __must_check compel_wait_task(int pid, int ppid,
 		int (*get_status)(int pid, struct seize_task_status *, void *data),
 		void (*free_status)(int pid, struct seize_task_status *, void *data),
 		struct seize_task_status *st, void *data);
 
-extern int compel_stop_task(int pid);
+extern int __must_check compel_stop_task(int pid);
 extern int compel_resume_task(pid_t pid, int orig_state, int state);
 
 struct parasite_ctl;
 struct parasite_thread_ctl;
 
-extern struct parasite_ctl *compel_prepare(int pid);
-extern struct parasite_ctl *compel_prepare_noctx(int pid);
-extern int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
-extern struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid);
+extern struct parasite_ctl __must_check *compel_prepare(int pid);
+extern struct parasite_ctl __must_check *compel_prepare_noctx(int pid);
+extern int __must_check compel_infect(struct parasite_ctl *ctl,
+		unsigned long nr_threads, unsigned long args_size);
+extern struct parasite_thread_ctl __must_check *compel_prepare_thread(struct parasite_ctl *ctl, int pid);
 extern void compel_release_thread(struct parasite_thread_ctl *);
 
-extern int compel_stop_daemon(struct parasite_ctl *ctl);
-extern int compel_cure_remote(struct parasite_ctl *ctl);
-extern int compel_cure_local(struct parasite_ctl *ctl);
-extern int compel_cure(struct parasite_ctl *ctl);
+extern int __must_check compel_stop_daemon(struct parasite_ctl *ctl);
+extern int __must_check compel_cure_remote(struct parasite_ctl *ctl);
+extern int __must_check compel_cure_local(struct parasite_ctl *ctl);
+extern int __must_check compel_cure(struct parasite_ctl *ctl);
 
 #define PARASITE_ARG_SIZE_MIN	( 1 << 12)
 
@@ -58,15 +59,16 @@ extern int compel_cure(struct parasite_ctl *ctl);
 extern void *compel_parasite_args_p(struct parasite_ctl *ctl);
 extern void *compel_parasite_args_s(struct parasite_ctl *ctl, unsigned long args_size);
 
-extern int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret,
+extern int __must_check compel_syscall(struct parasite_ctl *ctl,
+		int nr, long *ret,
 		unsigned long arg1,
 		unsigned long arg2,
 		unsigned long arg3,
 		unsigned long arg4,
 		unsigned long arg5,
 		unsigned long arg6);
-extern int compel_run_in_thread(struct parasite_thread_ctl *tctl, unsigned int cmd);
-extern int compel_run_at(struct parasite_ctl *ctl, unsigned long ip, user_regs_struct_t *ret_regs);
+extern int __must_check compel_run_in_thread(struct parasite_thread_ctl *tctl, unsigned int cmd);
+extern int __must_check compel_run_at(struct parasite_ctl *ctl, unsigned long ip, user_regs_struct_t *ret_regs);
 
 /*
  * The PTRACE_SYSCALL will trap task twice -- on
@@ -80,12 +82,13 @@ enum trace_flags {
 	TRACE_EXIT,
 };
 
-extern int compel_stop_on_syscall(int tasks, int sys_nr,
+extern int __must_check compel_stop_on_syscall(int tasks, int sys_nr,
 		int sys_nr_compat, enum trace_flags trace);
 
-extern int compel_stop_pie(pid_t pid, void *addr, enum trace_flags *tf, bool no_bp);
+extern int __must_check compel_stop_pie(pid_t pid, void *addr,
+		enum trace_flags *tf, bool no_bp);
 
-extern int compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
+extern int __must_check compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
 
 extern int compel_mode_native(struct parasite_ctl *ctl);
 
@@ -159,7 +162,7 @@ struct parasite_blob_desc {
 
 extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *);
 
-extern int compel_get_thread_regs(struct parasite_thread_ctl *, save_regs_t, void *);
+extern int __must_check compel_get_thread_regs(struct parasite_thread_ctl *, save_regs_t, void *);
 
 extern void compel_relocs_apply(void *mem, void *vbase, size_t size, compel_reloc_t *elf_relocs, size_t nr_relocs);
 
diff --git a/compel/include/uapi/ptrace.h b/compel/include/uapi/ptrace.h
index 4df00b6e1b68..13eed72328e2 100644
--- a/compel/include/uapi/ptrace.h
+++ b/compel/include/uapi/ptrace.h
@@ -1,6 +1,7 @@
 #ifndef UAPI_COMPEL_PTRACE_H__
 #define UAPI_COMPEL_PTRACE_H__
 
+#include "common/compiler.h"
 /*
  * We'd want to include both sys/ptrace.h and linux/ptrace.h,
  * hoping that most definitions come from either one or another.
@@ -75,8 +76,8 @@ typedef struct {
 
 extern int ptrace_suspend_seccomp(pid_t pid);
 
-extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
-extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes);
-extern int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes);
+extern int __must_check ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
+extern int __must_check ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes);
+extern int __must_check ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes);
 
 #endif /* UAPI_COMPEL_PTRACE_H__ */
diff --git a/compel/include/uapi/sigframe-common.h b/compel/include/uapi/sigframe-common.h
index fc93c5480b47..177bf4c48ae0 100644
--- a/compel/include/uapi/sigframe-common.h
+++ b/compel/include/uapi/sigframe-common.h
@@ -8,6 +8,7 @@
 # error "Direct inclusion is forbidden, use <compel/asm/sigframe.h> instead"
 #endif
 
+#include "common/compiler.h"
 #include <signal.h>
 #include <compel/plugins/std/asm/syscall-types.h>
 
@@ -56,7 +57,7 @@ struct rt_ucontext {
 	unsigned long		uc_regspace[128] __attribute__((aligned(8)));
 };
 
-extern int sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
-				    struct rt_sigframe *rframe);
+extern int __must_check sigreturn_prep_fpu_frame(struct rt_sigframe *frame,
+						 struct rt_sigframe *rframe);
 
 #endif /* UAPI_COMPEL_SIGFRAME_COMMON_H__ */
diff --git a/compel/plugins/include/uapi/plugin-fds.h b/compel/plugins/include/uapi/plugin-fds.h
index cececb21d940..e995b4b66aa7 100644
--- a/compel/plugins/include/uapi/plugin-fds.h
+++ b/compel/plugins/include/uapi/plugin-fds.h
@@ -1,7 +1,7 @@
 #ifndef COMPEL_PLUGIN_STD_STD_H__
 #define COMPEL_PLUGIN_STD_STD_H__
 
-extern int fds_send_fd(int fd);
+extern int __must_check fds_send_fd(int fd);
 extern int fds_recv_fd(void);
 
 #endif /* COMPEL_PLUGIN_STD_STD_H__ */
diff --git a/compel/plugins/include/uapi/std/infect.h b/compel/plugins/include/uapi/std/infect.h
index 800df250954e..1e784f8b4371 100644
--- a/compel/plugins/include/uapi/std/infect.h
+++ b/compel/plugins/include/uapi/std/infect.h
@@ -1,14 +1,16 @@
 #ifndef COMPEL_PLUGIN_STD_INFECT_H__
 #define COMPEL_PLUGIN_STD_INFECT_H__
 
+#include "common/compiler.h"
+
 extern int parasite_get_rpc_sock(void);
-extern int parasite_service(unsigned int cmd, void *args);
+extern int __must_check parasite_service(unsigned int cmd, void *args);
 
 /*
  * Must be supplied by user plugins.
  */
-extern int parasite_daemon_cmd(int cmd, void *args);
-extern int parasite_trap_cmd(int cmd, void *args);
+extern int __must_check parasite_daemon_cmd(int cmd, void *args);
+extern int __must_check parasite_trap_cmd(int cmd, void *args);
 extern void parasite_cleanup(void);
 
 /*
diff --git a/compel/plugins/include/uapi/std/log.h b/compel/plugins/include/uapi/std/log.h
index f21b6df0d943..91462c85b74f 100644
--- a/compel/plugins/include/uapi/std/log.h
+++ b/compel/plugins/include/uapi/std/log.h
@@ -2,6 +2,7 @@
 #define COMPEL_PLUGIN_STD_LOG_H__
 
 #include "compel/loglevels.h"
+#include "common/compiler.h"
 
 #define STD_LOG_SIMPLE_CHUNK	256
 
diff --git a/criu/seize.c b/criu/seize.c
index cce8911b924b..e1e6b8195650 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -483,7 +483,7 @@ static int collect_children(struct pstree_item *item)
 
 		if (!opts.freeze_cgroup)
 			/* fails when meets a zombie */
-			compel_interrupt_task(pid);
+			__ignore_value(compel_interrupt_task(pid));
 
 		ret = compel_wait_task(pid, item->pid->real, parse_pid_status, NULL, &creds.s, NULL);
 		if (ret < 0) {
diff --git a/include/common/compiler.h b/include/common/compiler.h
index fc8abcfef48b..1d431a5293cc 100644
--- a/include/common/compiler.h
+++ b/include/common/compiler.h
@@ -22,6 +22,7 @@
 #define __used			__attribute__((__used__))
 #define __maybe_unused		__attribute__((unused))
 #define __always_unused		__attribute__((unused))
+#define __must_check		__attribute__((__warn_unused_result__))
 
 #define __section(S)		__attribute__ ((__section__(#S)))
 
@@ -99,4 +100,30 @@
 
 #define is_log2(v)		(((v) & ((v) - 1)) == 0)
 
+/*
+ * Use "__ignore_value" to avoid a warning when using a function declared with
+ * gcc's warn_unused_result attribute, but for which you really do want to
+ * ignore the result.  Traditionally, people have used a "(void)" cast to
+ * indicate that a function's return value is deliberately unused.  However,
+ * if the function is declared with __attribute__((warn_unused_result)),
+ * gcc issues a warning even with the cast.
+ *
+ * Caution: most of the time, you really should heed gcc's warning, and
+ * check the return value.  However, in those exceptional cases in which
+ * you're sure you know what you're doing, use this function.
+ *
+ * Normally casting an expression to void discards its value, but GCC
+ * versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
+ * which may cause unwanted diagnostics in that case.  Use __typeof__
+ * and __extension__ to work around the problem, if the workaround is
+ * known to be needed.
+ * Written by Jim Meyering, Eric Blake and Pádraig Brady.
+ * (See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 for the details)
+ */
+#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
+# define __ignore_value(x)	({ __typeof__ (x) __x = (x); (void) __x; })
+#else
+# define __ignore_value(x) ((void) (x))
+#endif
+
 #endif /* __CR_COMPILER_H__ */
-- 
2.24.0



More information about the CRIU mailing list