2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 13:58:34 +00:00

zdtm/ia32: fcntl() wrapper for old glibc(s)

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.

Fixes: #745

Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
Dmitry Safonov 2019-05-02 02:34:41 +01:00 committed by Andrei Vagin
parent 2a3e34155c
commit 6d66dd5d89
5 changed files with 62 additions and 5 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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_ */