Commit 49cd3eb2 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Andrei Vagin

locks: Add c/r of non broken leases (kernel>=v4.1)

Leases in breaking state are not supported. In that case criu will
report an error during the dumping. Also lock info in
/proc/<pid>/fdinfo should be presented (since kernel 4.1).

Before taking out new lease it modifies process fsuid to match file uid
(see fcntl F_SETLEASE).
Signed-off-by: 's avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent b2494eae
......@@ -5,6 +5,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fsuid.h>
#include <sys/sysmacros.h>
#include "cr_options.h"
......@@ -292,6 +293,9 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
*/
if (fl->fl_owner != pid->real)
continue;
} else if (fl->fl_kind == FL_LEASE) {
pr_err("Leases are not supported for kernel <= v4.0");
return -1;
} else /* fl->fl_kind == FL_FLOCK || fl->fl_kind == FL_OFD */ {
int ret;
......@@ -329,6 +333,30 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
return 0;
}
static int set_file_lease(int fd, int type)
{
int old_fsuid, ret;
struct stat st;
if (fstat(fd, &st)) {
pr_perror("Can't get file stat (%i)\n", fd);
return -1;
}
/*
* An unprivileged process may take out a lease only if
* uid of the file matches the fsuid of the process.
*/
old_fsuid = setfsuid(st.st_uid);
ret = fcntl(fd, F_SETLEASE, type);
if (ret < 0)
pr_perror("Can't set lease\n");
setfsuid(old_fsuid);
return ret;
}
static int restore_file_lock(FileLockEntry *fle)
{
int ret = -1;
......@@ -395,6 +423,16 @@ static int restore_file_lock(FileLockEntry *fle)
pr_err("Can not set ofd lock!\n");
goto err;
}
} else if (fle->flag & FL_LEASE) {
pr_info("(lease)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 = set_file_lease(fle->fd, fle->type);
if (ret < 0) {
pr_perror("Can't set lease!\n");
goto err;
}
} else {
pr_err("Unknown file lock style!\n");
goto err;
......
......@@ -10,6 +10,7 @@
#define FL_POSIX 1
#define FL_FLOCK 2
#define FL_OFD 4
#define FL_LEASE 8
/* for posix fcntl() and lockf() */
#ifndef F_RDLCK
......
......@@ -2014,6 +2014,8 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
fl->fl_kind = FL_FLOCK;
else if (!strcmp(fl_flag, "OFDLCK"))
fl->fl_kind = FL_OFD;
else if (!strcmp(fl_flag, "LEASE"))
fl->fl_kind = FL_LEASE;
else
fl->fl_kind = FL_UNKNOWN;
......@@ -2030,6 +2032,9 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
pr_err("Unknown lock option!\n");
return -1;
}
} else if (fl->fl_kind == FL_LEASE && !strcmp(fl_type, "BREAKING")) {
pr_err("Breaking leases are not supported (%d): %s\n",
num, buf);
} else {
if (!strcmp(fl_option, "UNLCK")) {
fl->fl_ltype |= F_UNLCK;
......
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