[CRIU] [PATCHv2 4/5] locks: Add leases c/r for kernels v4.0 and older
Pavel Emelyanov
xemul at virtuozzo.com
Tue Aug 15 17:51:25 MSK 2017
On 08/14/2017 02:49 AM, Pavel Begunkov wrote:
> Information about locks in /proc/<pid>/fdinfo is presented only since
> kernel v4.1. This patch adds logic to *note_file_lock* to match leases
> and OFDs.
OFDs? Can you shed more light on this, why have OFDs popped up?
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> ---
> criu/file-lock.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 83 insertions(+), 2 deletions(-)
>
> diff --git a/criu/file-lock.c b/criu/file-lock.c
> index 5b0580782..b7462dc77 100644
> --- a/criu/file-lock.c
> +++ b/criu/file-lock.c
> @@ -266,6 +266,81 @@ static int lock_ofd_check_fd(int lfd, struct file_lock *fl)
> return 1;
> }
>
> +static int lease_check_fd(int fd, int file_flags, struct file_lock *fl)
> +{
> + int file_lease_type, err;
> + int lease_type = fl->fl_ltype & (~LEASE_BREAKING);
> +
> + if ((file_flags & O_ACCMODE) != O_RDONLY) {
> + /*
> + * Write OFD conflicts with any lease not associated
> + * with it, therefore there is can't be other lease
> + * or OFD for this file.
> + */
> + return 1;
> + }
> +
> + file_lease_type = fcntl(fd, F_GETLEASE);
> + if (file_lease_type < 0) {
> + pr_err("Can't get lease type\n");
> + return -1;
> + }
> +
> + /*
> + * Only read OFDs can be present for the file. If
> + * read and write OFDs with at least one lease had
> + * presented, it would have conflicted.
> + */
> + if (fl->fl_ltype & LEASE_BREAKING) {
> + /*
> + * Only read leases are possible for read OFDs
> + * and they all should be in breaking state,
> + * because the current one is.
> + */
> + int compatible_type = file_lease_type;
> +
> + if (compatible_type != F_UNLCK) {
> + pr_err("Lease doesn't conflicts but breaks\n");
> + return -1;
> + }
> +
> + /*
> + * Due to activated breaking sequence we can't
> + * get actual lease type with F_GETLEASE.
> + * The err == 0 after lease upgrade means, that
> + * there is already read lease. Otherwise it
> + * will fail because of breaking sequence.
> + */
> + err = fcntl(fd, F_SETLEASE, F_RDLCK);
> + if (err < 0) {
> + if (errno != EAGAIN) {
> + pr_perror("Can't set lease (fd %i)", fd);
> + return -1;
> + }
> + return 0;
> + } else {
> + return 1;
> + }
> + } else {
> + /*
> + * The file can have only non-breaking read
> + * leases, because otherwise the current one
> + * also would have broke.
> + */
> + if (lease_type != F_RDLCK) {
> + pr_err("Incorrect lease type\n");
> + return -1;
> + }
> +
> + if (file_lease_type == F_UNLCK)
> + return 0;
> + if (file_lease_type == F_RDLCK)
> + return 1;
> + pr_err("Invalid file lease type\n");
> + return -1;
> + }
> +}
> +
> int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
> {
> struct file_lock *fl;
> @@ -295,8 +370,14 @@ 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;
> + if (fl->owners_fd >= 0)
> + continue;
> +
> + ret = lease_check_fd(lfd, p->flags, fl);
> + if (ret < 0)
> + return ret;
> + if (ret == 0)
> + continue;
> } else /* fl->fl_kind == FL_FLOCK || fl->fl_kind == FL_OFD */ {
> int ret;
>
>
More information about the CRIU
mailing list