Commit 34c9119a authored by Begunkov Pavel's avatar Begunkov Pavel Committed by Pavel Emelyanov

locks: Add ofd locks c/r

OFD locks logic reuses existing locks c/r functionality.

https://github.com/xemul/criu/issues/42
travis-ci: success for series starting with [1/2] locks: Add ofd locks c/r
Signed-off-by: 's avatarBegunkov Pavel <asml.silence@gmail.com>
Signed-off-by: 's avatarEugene Batalov <eabatalov89@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent cf72cedd
...@@ -205,6 +205,57 @@ static int lock_check_fd(int lfd, struct file_lock *fl) ...@@ -205,6 +205,57 @@ static int lock_check_fd(int lfd, struct file_lock *fl)
return 1; return 1;
} }
static int lock_ofd_check_fd(int lfd, struct file_lock *fl)
{
int ret;
struct flock lck = {
.l_whence = SEEK_SET,
.l_type = F_WRLCK,
.l_start = fl->start
};
if (strcmp(fl->end, "EOF")) {
unsigned long end;
ret = sscanf(fl->end, "%lu", &end);
if (ret <= 0) {
pr_err("Invalid lock entry\n");
return -1;
}
lck.l_len = end - fl->start + 1;
} else {
lck.l_len = 0;
}
ret = fcntl(lfd, F_OFD_SETLK, &lck);
pr_debug(" `- %d/%d\n", ret, errno);
if (ret != 0) {
if (errno != EAGAIN) {
pr_err("Bogus lock test result %d\n", ret);
return -1;
}
return 0;
} else {
/*
* The ret == 0 means, that new lock doesn't conflict
* with any others on the file. But since we do know,
* that there should be some other one (file is found
* in /proc/locks), it means that the lock is already
* on file pointed by fd.
*/
pr_debug(" `- downgrading lock back\n");
if (fl->fl_ltype & LOCK_WRITE)
lck.l_type = F_WRLCK;
else
lck.l_type = F_RDLCK;
fcntl(lfd, F_OFD_SETLK, &lck);
}
return 1;
}
int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p) int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
{ {
struct file_lock *fl; struct file_lock *fl;
...@@ -233,11 +284,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p) ...@@ -233,11 +284,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
*/ */
if (fl->fl_owner != pid->real) if (fl->fl_owner != pid->real)
continue; continue;
} else /* fl->fl_kind == FL_FLOCK */ { } else /* fl->fl_kind == FL_FLOCK || fl->fl_kind == FL_OFD */ {
int ret; int ret;
/* /*
* FLOCKs can be inherited across fork, * OFD locks & FLOCKs can be inherited across fork,
* thus we can have any task as lock * thus we can have any task as lock
* owner. But the creator is preferred * owner. But the creator is preferred
* anyway. * anyway.
...@@ -248,7 +299,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p) ...@@ -248,7 +299,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
continue; continue;
pr_debug("Checking lock holder %d:%d\n", pid->real, fd); pr_debug("Checking lock holder %d:%d\n", pid->real, fd);
ret = lock_check_fd(lfd, fl); if (fl->fl_kind == FL_FLOCK)
ret = lock_check_fd(lfd, fl);
else
ret = lock_ofd_check_fd(lfd, fl);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret == 0) if (ret == 0)
...@@ -313,6 +368,25 @@ static int restore_file_lock(FileLockEntry *fle) ...@@ -313,6 +368,25 @@ static int restore_file_lock(FileLockEntry *fle)
pr_err("Can not set posix lock!\n"); pr_err("Can not set posix lock!\n");
goto err; goto err;
} }
} else if (fle->flag & FL_OFD) {
struct flock flk = {
.l_whence = SEEK_SET,
.l_start = fle->start,
.l_len = fle->len,
.l_pid = 0,
.l_type = fle->type
};
pr_info("(ofd)flag: %d, type: %d, pid: %d, fd: %d, "
"start: %8"PRIx64", len: %8"PRIx64"\n",
fle->flag, fle->type, fle->pid, fle->fd,
fle->start, fle->len);
ret = fcntl(fle->fd, F_OFD_SETLK, &flk);
if (ret < 0) {
pr_err("Can not set ofd lock!\n");
goto err;
}
} else { } else {
pr_err("Unknown file lock style!\n"); pr_err("Unknown file lock style!\n");
goto err; goto err;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define FL_UNKNOWN -1 #define FL_UNKNOWN -1
#define FL_POSIX 1 #define FL_POSIX 1
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_OFD 4
/* for posix fcntl() and lockf() */ /* for posix fcntl() and lockf() */
#ifndef F_RDLCK #ifndef F_RDLCK
...@@ -17,6 +18,13 @@ ...@@ -17,6 +18,13 @@
#define F_UNLCK 2 #define F_UNLCK 2
#endif #endif
/* for OFD locks fcntl() */
#ifndef F_OFD_GETLK
#define F_OFD_GETLK 36
#define F_OFD_SETLK 37
#define F_OFD_SETLKW 38
#endif
/* operations for bsd flock(), also used by the kernel implementation */ /* operations for bsd flock(), also used by the kernel implementation */
#define LOCK_SH 1 /* shared lock */ #define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */ #define LOCK_EX 2 /* exclusive lock */
......
...@@ -1973,6 +1973,8 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl, ...@@ -1973,6 +1973,8 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
fl->fl_kind = FL_POSIX; fl->fl_kind = FL_POSIX;
else if (!strcmp(fl_flag, "FLOCK")) else if (!strcmp(fl_flag, "FLOCK"))
fl->fl_kind = FL_FLOCK; fl->fl_kind = FL_FLOCK;
else if (!strcmp(fl_flag, "OFDLCK"))
fl->fl_kind = FL_OFD;
else else
fl->fl_kind = FL_UNKNOWN; fl->fl_kind = FL_UNKNOWN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment