[CRIU] [PATCH 1/2] locks: Add ofd locks c/r

Andrei Vagin avagin at virtuozzo.com
Wed Jan 4 17:47:37 PST 2017


On Tue, Dec 20, 2016 at 01:24:38PM +0300, Pavel Begunkov wrote:
> From: Begunkov Pavel <asml.silence at gmail.com>
> 
> OFD locks logic reuses existing locks c/r functionality.
> 
> Signed-off-by: Begunkov Pavel <asml.silence at gmail.com>
> Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
> ---
>  criu/file-lock.c         | 80 ++++++++++++++++++++++++++++++++++++++++++++++--
>  criu/include/file-lock.h |  8 +++++
>  criu/proc_parse.c        |  2 ++
>  3 files changed, 87 insertions(+), 3 deletions(-)
> 
> diff --git a/criu/file-lock.c b/criu/file-lock.c
> index 1ab1e58..fbb963b 100644
> --- a/criu/file-lock.c
> +++ b/criu/file-lock.c
> @@ -204,6 +204,57 @@ static int lock_check_fd(int lfd, struct file_lock *fl)
>  	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);

	
CID 173734 (#1 of 1): Unchecked return value from library (CHECKED_RETURN)
7. check_return: Calling fcntl(lfd, 37, &lck) without checking return
value. This library function may fail and return an error code.

> +	}
> +
> +	return 1;
> +}
> +
>  int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
>  {
>  	struct file_lock *fl;
> @@ -232,11 +283,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
>  			 */
>  			if (fl->fl_owner != pid->real)
>  				continue;
> -		} else /* fl->fl_kind == FL_FLOCK */ {
> +		} else /* fl->fl_kind == FL_FLOCK || fl->fl_kind == FL_OFD */ {
>  			int ret;
>  
>  			/*
> -			 * FLOCKs can be inherited across fork,
> +			 * OFD locks & FLOCKs can be inherited across fork,
>  			 * thus we can have any task as lock
>  			 * owner. But the creator is preferred
>  			 * anyway.
> @@ -247,7 +298,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
>  				continue;
>  
>  			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)
>  				return ret;
>  			if (ret == 0)
> @@ -312,6 +367,25 @@ static int restore_file_lock(FileLockEntry *fle)
>  			pr_err("Can not set posix lock!\n");
>  			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 {
>  		pr_err("Unknown file lock style!\n");
>  		goto err;
> diff --git a/criu/include/file-lock.h b/criu/include/file-lock.h
> index 5c1bb5b..c3f2dab 100644
> --- a/criu/include/file-lock.h
> +++ b/criu/include/file-lock.h
> @@ -9,6 +9,7 @@
>  #define FL_UNKNOWN	-1
>  #define FL_POSIX	1
>  #define FL_FLOCK	2
> +#define FL_OFD		4
>  
>  /* for posix fcntl() and lockf() */
>  #ifndef F_RDLCK
> @@ -17,6 +18,13 @@
>  #define F_UNLCK		2
>  #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 */
>  #define LOCK_SH		1	/* shared lock */
>  #define LOCK_EX		2	/* exclusive lock */
> diff --git a/criu/proc_parse.c b/criu/proc_parse.c
> index 7c48b33..1f0bff8 100644
> --- a/criu/proc_parse.c
> +++ b/criu/proc_parse.c
> @@ -1973,6 +1973,8 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
>  		fl->fl_kind = FL_POSIX;
>  	else if (!strcmp(fl_flag, "FLOCK"))
>  		fl->fl_kind = FL_FLOCK;
> +	else if (!strcmp(fl_flag, "OFDLCK"))
> +		fl->fl_kind = FL_OFD;
>  	else
>  		fl->fl_kind = FL_UNKNOWN;
>  
> -- 
> 2.10.0
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list