[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