[CRIU] [PATCH 1/5] zdtm/ia32: fcntl() wrapper for old glibc(s)
Dmitry Safonov
dima at arista.com
Thu May 2 04:34:41 MSK 2019
A bit nasty, but does the job to run ofd tests on glibc < v2.28.
Other way would be to update glibc on Travis-CI ia32 tests, but
I thought someone might want to run the tests outside Travis-CI.
Signed-off-by: Dmitry Safonov <dima at arista.com>
---
test/zdtm/static/file_locks06.c | 2 +-
test/zdtm/static/file_locks07.c | 2 +-
test/zdtm/static/file_locks08.c | 2 +-
test/zdtm/static/ofd_file_locks.c | 60 +++++++++++++++++++++++++++++--
test/zdtm/static/ofd_file_locks.h | 1 +
5 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/test/zdtm/static/file_locks06.c b/test/zdtm/static/file_locks06.c
index 9bc70c47d63b..780fb07eaa32 100644
--- a/test/zdtm/static/file_locks06.c
+++ b/test/zdtm/static/file_locks06.c
@@ -26,7 +26,7 @@ int init_lock(int *fd, struct flock *lck)
lck->l_len = 0;
lck->l_pid = 0;
- if (fcntl(*fd, F_OFD_SETLK, lck) < 0) {
+ if (zdtm_fcntl(*fd, F_OFD_SETLK, lck) < 0) {
pr_perror("Can't set ofd lock");
return -1;
}
diff --git a/test/zdtm/static/file_locks07.c b/test/zdtm/static/file_locks07.c
index b36f23011fcf..2fe169fcfb31 100644
--- a/test/zdtm/static/file_locks07.c
+++ b/test/zdtm/static/file_locks07.c
@@ -45,7 +45,7 @@ int init_file_locks(void)
}
for (i = 0; i < FILE_NUM; ++i)
- if (fcntl(fds[i], F_OFD_SETLKW, &lcks[i]) < 0) {
+ if (zdtm_fcntl(fds[i], F_OFD_SETLKW, &lcks[i]) < 0) {
pr_perror("Can't set ofd lock");
return -1;
}
diff --git a/test/zdtm/static/file_locks08.c b/test/zdtm/static/file_locks08.c
index 2d25b4b09719..fea8d9e7ee06 100644
--- a/test/zdtm/static/file_locks08.c
+++ b/test/zdtm/static/file_locks08.c
@@ -28,7 +28,7 @@ int init_file_lock(int *fd, struct flock *lck)
lck->l_len = 0; /* lock whole file */
lck->l_pid = 0; /* should be 0 for ofd lock */
- if (fcntl(*fd, F_OFD_SETLKW, lck) < 0) {
+ if (zdtm_fcntl(*fd, F_OFD_SETLKW, lck) < 0) {
pr_perror("Can't set ofd lock");
return -1;
}
diff --git a/test/zdtm/static/ofd_file_locks.c b/test/zdtm/static/ofd_file_locks.c
index c4a6336250ea..5b19532f8bba 100644
--- a/test/zdtm/static/ofd_file_locks.c
+++ b/test/zdtm/static/ofd_file_locks.c
@@ -86,7 +86,7 @@ int check_lock_exists(const char *filename, struct flock *lck)
if (lck->l_type == F_RDLCK) {
/* check, that there is no write lock */
- ret = fcntl(fd, F_OFD_GETLK, lck);
+ ret = zdtm_fcntl(fd, F_OFD_GETLK, lck);
if (ret) {
pr_err("fcntl failed (%i)\n", ret);
goto out;
@@ -99,7 +99,7 @@ int check_lock_exists(const char *filename, struct flock *lck)
/* check, that lock is set */
lck->l_type = F_WRLCK;
- ret = fcntl(fd, F_OFD_GETLK, lck);
+ ret = zdtm_fcntl(fd, F_OFD_GETLK, lck);
if (ret) {
pr_err("fcntl failed (%i)\n", ret);
goto out;
@@ -136,3 +136,59 @@ int check_file_lock_restored(int pid, int fd, struct flock *lck)
}
return 0;
}
+
+/*
+ * fcntl() wrapper for ofd locks.
+ *
+ * Kernel requires ia32 processes to use fcntl64() syscall for ofd:
+ * COMPAT_SYSCALL_DEFINE3(fcntl, [..])
+ * {
+ * switch (cmd) {
+ * case F_GETLK64:
+ * case F_SETLK64:
+ * case F_SETLKW64:
+ * case F_OFD_GETLK:
+ * case F_OFD_SETLK:
+ * case F_OFD_SETLKW:
+ * return -EINVAL;
+ * }
+ *
+ * Glibc does all the needed wraps for fcntl(), but only from v2.28.
+ * To make ofd tests run on the older glibc's - provide zdtm wrap.
+ *
+ * Note: we don't need the wraps in CRIU itself as parasite/restorer
+ * run in 64-bit mode as long as possible, including the time to play
+ * with ofd (and they are dumped from CRIU).
+ */
+int zdtm_fcntl(int fd, int cmd, struct flock *f)
+{
+#if defined(__i386__)
+#ifndef __NR_fcntl64
+# define __NR_fcntl64 221
+#endif
+ struct flock64 f64 = {};
+ int ret;
+
+ switch (cmd) {
+ case F_OFD_SETLK:
+ case F_OFD_SETLKW:
+ f64.l_type = f->l_type;
+ f64.l_whence = f->l_whence;
+ f64.l_start = f->l_start;
+ f64.l_len = f->l_len;
+ f64.l_pid = f->l_pid;
+ return syscall(__NR_fcntl64, fd, cmd, &f64);
+ case F_OFD_GETLK:
+ ret = syscall(__NR_fcntl64, fd, cmd, &f64);
+ f->l_type = f64.l_type;
+ f->l_whence = f64.l_whence;
+ f->l_start = f64.l_start;
+ f->l_len = f64.l_len;
+ f->l_pid = f64.l_pid;
+ return ret;
+ default:
+ break;
+ }
+#endif
+ return fcntl(fd, cmd, f);
+}
diff --git a/test/zdtm/static/ofd_file_locks.h b/test/zdtm/static/ofd_file_locks.h
index 6978446dfea0..1b206a238bf4 100644
--- a/test/zdtm/static/ofd_file_locks.h
+++ b/test/zdtm/static/ofd_file_locks.h
@@ -16,5 +16,6 @@
extern int check_lock_exists(const char *filename, struct flock *lck);
extern int check_file_lock_restored(int pid, int fd, struct flock *lck);
+extern int zdtm_fcntl(int fd, int cmd, struct flock *f);
#endif /* ZDTM_OFD_FILE_LOCKS_H_ */
--
2.21.0
More information about the CRIU
mailing list