[CRIU] [PATCH] cr-check: Inspect errno on syscall failures

Filipe Brandenburger filbranden at google.com
Mon Mar 14 10:43:09 PDT 2016


After replacing sys_kcmp with syscall() and sys_prctl with prctl(), the
API is changed to return -1 and set errno on failure (instead of
returning the negative value of the error code directly on return.)

Commit 8ceab588a5ce91 ("crtools: no more linked with builtin syscall")
replaced calls to sys_kcmp and sys_prctl, but did not update the checks
for ret to check for -1 and errno, so update them here.

Also make the comparisons for the return value explicit checks for a
negative value (expected -1) instead of just failing on a non-zero value
with the implicit comparison.

Add %m to report what errno was set to on failed syscalls, to make it
easier to troubleshoot a check failure.

Tested that now `criu check --ms` stopped reporting the misleading:
  prctl: One needs CAP_SYS_RESOURCE capability to perform testing.
Instead, now it reports:
  Error (cr-check.c:165): System call kcmp is not supported: No such process
  Warn  (cr-check.c:195): Skipping unssuported PR_SET_MM_MAP: Invalid argument
  prctl: PR_SET_MM is not supported: Invalid argument
And those messages include the error message that explains why the
syscall failed.

Reported-by: Saied Kazemi <saied at google.com>
Fixes: 8ceab588a5ce91 ("crtools: no more linked with builtin syscall")
Cc: Laurent Dufour <ldufour at linux.vnet.ibm.com>
Signed-off-by: Filipe Brandenburger <filbranden at google.com>
---
 criu/cr-check.c        | 45 ++++++++++++++++++++++-----------------------
 criu/cr-dump.c         |  8 ++++----
 criu/cr-restore.c      |  1 -
 criu/fsnotify.c        |  2 --
 criu/include/sk-inet.h |  2 +-
 criu/kerndat.c         |  2 +-
 6 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 2896b0280924..87180e510f23 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -161,12 +161,12 @@ static int check_kcmp(void)
 {
 	int ret = syscall(SYS_kcmp, getpid(), -1, -1, -1, -1);
 
-	if (ret != -ENOSYS)
-		return 0;
+	if (ret < 0 && errno != ENOSYS) {
+		pr_perror("System call kcmp is not supported");
+		return -1;
+	}
 
-	errno = -ret;
-	pr_perror("System call kcmp is not supported");
-	return -1;
+	return 0;
 }
 
 static int check_prctl(void)
@@ -177,8 +177,8 @@ static int check_prctl(void)
 	int ret;
 
 	ret = prctl(PR_GET_TID_ADDRESS, (unsigned long)&tid_addr, 0, 0, 0);
-	if (ret) {
-		pr_msg("prctl: PR_GET_TID_ADDRESS is not supported");
+	if (ret < 0) {
+		pr_msg("prctl: PR_GET_TID_ADDRESS is not supported: %m");
 		return -1;
 	}
 
@@ -186,32 +186,32 @@ static int check_prctl(void)
 	 * Either new or old interface must be supported in the kernel.
 	 */
 	ret = prctl(PR_SET_MM, PR_SET_MM_MAP_SIZE, (unsigned long)&size, 0, 0);
-	if (ret) {
+	if (ret < 0) {
 		if (!opts.check_ms_kernel) {
 			pr_msg("prctl: PR_SET_MM_MAP is not supported, which "
-			       "is required for restoring user namespaces\n");
+			       "is required for restoring user namespaces: %m\n");
 			return -1;
 		} else
-			pr_warn("Skipping unssuported PR_SET_MM_MAP\n");
+			pr_warn("Skipping unssuported PR_SET_MM_MAP: %m\n");
 
 		ret = prctl(PR_SET_MM, PR_SET_MM_BRK, brk(0), 0, 0);
-		if (ret) {
-			if (ret == -EPERM)
+		if (ret < 0) {
+			if (errno == EPERM)
 				pr_msg("prctl: One needs CAP_SYS_RESOURCE capability to perform testing\n");
 			else
-				pr_msg("prctl: PR_SET_MM is not supported\n");
+				pr_msg("prctl: PR_SET_MM is not supported: %m\n");
 			return -1;
 		}
 
 		ret = prctl(PR_SET_MM, PR_SET_MM_EXE_FILE, -1, 0, 0);
-		if (ret != -EBADF) {
-			pr_msg("prctl: PR_SET_MM_EXE_FILE is not supported (%d)\n", ret);
+		if (ret < 0 && errno != EBADF) {
+			pr_msg("prctl: PR_SET_MM_EXE_FILE is not supported: %m\n");
 			return -1;
 		}
 
 		ret = prctl(PR_SET_MM, PR_SET_MM_AUXV, (long)&user_auxv, sizeof(user_auxv), 0);
-		if (ret) {
-			pr_msg("prctl: PR_SET_MM_AUXV is not supported\n");
+		if (ret < 0) {
+			pr_msg("prctl: PR_SET_MM_AUXV is not supported: %m\n");
 			return -1;
 		}
 	}
@@ -523,7 +523,7 @@ static int check_sigqueuinfo()
 
 	signal(SIGUSR1, SIG_IGN);
 
-	if (syscall(SYS_rt_sigqueueinfo, getpid(), SIGUSR1, &info)) {
+	if (syscall(SYS_rt_sigqueueinfo, getpid(), SIGUSR1, &info) < 0) {
 		pr_perror("Unable to send siginfo with positive si_code to itself");
 		return -1;
 	}
@@ -744,7 +744,7 @@ static int check_aio_remap(void)
 	int r;
 
 	if (syscall(SYS_io_setup, 16, &ctx) < 0) {
-		pr_err("No AIO syscall\n");
+		pr_err("No AIO syscall: %m\n");
 		return -1;
 	}
 
@@ -767,10 +767,10 @@ static int check_aio_remap(void)
 	r = syscall(SYS_io_getevents, ctx, 0, 1, NULL, NULL);
 	if (r < 0) {
 		if (!opts.check_ms_kernel) {
-			pr_err("AIO remap doesn't work properly\n");
+			pr_err("AIO remap doesn't work properly: %m\n");
 			return -1;
 		} else
-			pr_warn("Skipping unsupported AIO remap\n");
+			pr_warn("Skipping unsupported AIO remap: %m\n");
 	}
 
 	return 0;
@@ -925,8 +925,7 @@ static int check_userns(void)
 	}
 
 	ret = prctl(PR_SET_MM, PR_SET_MM_MAP_SIZE, (unsigned long)&size, 0, 0);
-	if (ret) {
-		errno = -ret;
+	if (ret < 0) {
 		pr_perror("No new prctl API");
 		return -1;
 	}
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index c61a9aa0902a..95f662c2d7d6 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -168,9 +168,8 @@ static int dump_sched_info(int pid, ThreadCoreEntry *tc)
 	 * in kernel. Thus we have to take it with us in the image.
 	 */
 
-	errno = 0;
 	ret = getpriority(PRIO_PROCESS, pid);
-	if (errno) {
+	if (ret < 0) {
 		pr_perror("Can't get nice for %d", pid);
 		return -1;
 	}
@@ -522,7 +521,7 @@ static int get_task_futex_robust_list(pid_t pid, ThreadCoreEntry *info)
 	int ret;
 
 	ret = syscall(SYS_get_robust_list, pid, &head, &len);
-	if (ret == -ENOSYS) {
+	if (ret < 0 && errno == ENOSYS) {
 		/*
 		 * If the kernel says get_robust_list is not implemented, then
 		 * check whether set_robust_list is also not implemented, in
@@ -534,7 +533,8 @@ static int get_task_futex_robust_list(pid_t pid, ThreadCoreEntry *info)
 		 * implemented, in which case it will return -EINVAL because
 		 * len should be greater than zero.
 		 */
-		if (syscall(SYS_set_robust_list, NULL, 0) != -ENOSYS)
+		ret = syscall(SYS_set_robust_list, NULL, 0);
+		if (ret == 0 || (ret < 0 && errno != ENOSYS))
 			goto err;
 
 		head = NULL;
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 9d7495985838..e35d5b12f6e5 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -747,7 +747,6 @@ static int prepare_sigactions(void)
 		 */
 		ret = syscall(SYS_rt_sigaction, sig, &act, NULL, sizeof(k_rtsigset_t));
 		if (ret < 0) {
-			errno = -ret;
 			pr_perror("Can't restore sigaction");
 			goto err;
 		}
diff --git a/criu/fsnotify.c b/criu/fsnotify.c
index f633b406f30e..371ab6aa0a4a 100644
--- a/criu/fsnotify.c
+++ b/criu/fsnotify.c
@@ -209,7 +209,6 @@ static int open_handle(unsigned int s_dev, unsigned long i_ino,
 
 	fd = userns_call(open_by_handle, UNS_FDOUT, &handle, sizeof(handle), mntfd);
 	if (fd < 0) {
-		errno = -fd;
 		pr_perror("Can't open file handle for 0x%08x:0x%016lx",
 				s_dev, i_ino);
 	}
@@ -718,7 +717,6 @@ static int open_fanotify_fd(struct file_desc *d)
 
 	ret = fanotify_init(flags, info->ffe->evflags);
 	if (ret < 0) {
-		errno = -ret;
 		pr_perror("Can't init fanotify mark (%d)", ret);
 		return -1;
 	}
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index 3f273f4fdd27..ae6082d81801 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -61,7 +61,7 @@ static inline void tcp_repair_off(int fd)
 
 	ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux));
 	if (ret < 0)
-		pr_err("Failed to turn off repair mode on socket (%d)\n", ret);
+		pr_err("Failed to turn off repair mode on socket: %m\n");
 }
 
 extern void tcp_locked_conn_add(struct inet_sk_info *);
diff --git a/criu/kerndat.c b/criu/kerndat.c
index eb296033e5d9..362e8a9ad1fc 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -394,7 +394,7 @@ static bool kerndat_has_memfd_create(void)
 	else if (ret == -1 && errno == EFAULT)
 		kdat.has_memfd = true;
 	else {
-		pr_err("Unexpected error %d from memfd_create(NULL, 0)\n", ret);
+		pr_err("Unexpected error from memfd_create(NULL, 0): %m\n");
 		return -1;
 	}
 
-- 
2.7.0.rc3.207.g0ac5344



More information about the CRIU mailing list