[CRIU] [PATCH v2 1/2] locks: Remove duplicated locks

Andrei Vagin avagin at virtuozzo.com
Thu Nov 9 01:12:55 MSK 2017


On Sun, Oct 22, 2017 at 11:46:25PM +0300, Pavel Begunkov (Silence) wrote:
> From: Pavel Begunkov <asml.silence at gmail.com>
> 
> CRIU creates dictinct lock record for each file descriptor on the same
> OFD. The patch removes this duplicates. To do so, it adds new field into
> struct file_lock, which stores pid of fd, on which lock was found.
> 'owner pid' is not actually helpful, because the original fd, on which
> lock have been set, can be already closed.
> 
> Also it purges crutches doing the same stuff but only for file leases.
> 
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> ---
>  criu/file-lock.c         | 20 ++++++++++++++++----
>  criu/files.c             |  2 ++
>  criu/include/file-lock.h |  6 +++---
>  criu/proc_parse.c        |  3 +--
>  4 files changed, 22 insertions(+), 9 deletions(-)
> 
> diff --git a/criu/file-lock.c b/criu/file-lock.c
> index b7adc097..dd8f03ce 100644
> --- a/criu/file-lock.c
> +++ b/criu/file-lock.c
> @@ -58,6 +58,7 @@ struct file_lock *alloc_file_lock(void)
>  	INIT_LIST_HEAD(&flock->list);
>  	flock->real_owner = -1;
>  	flock->owners_fd = -1;
> +	flock->fl_holder = -1;
>  
>  	return flock;
>  }
> @@ -106,8 +107,6 @@ int dump_file_locks(void)
>  
>  			continue;
>  		}
> -		if (fl->fl_kind == FL_LEASE && !fl->updated)
> -			continue;
>  
>  		file_lock_entry__init(&fle);
>  		fle.pid = fl->real_owner;
> @@ -410,6 +409,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
>  				continue;
>  		}
>  
> +		fl->fl_holder = pid->real;
>  		fl->real_owner = pid->ns[0].virt;
>  		fl->owners_fd = fd;
>  
> @@ -421,6 +421,19 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
>  	return 0;
>  }
>  
> +void discard_dup_locks_tail(pid_t pid, int fd)
> +{

We need a comment before this function which explains why all duplicated
locks will be at the end of this list.

> +	while (!list_empty(&file_lock_list)) {
> +		struct file_lock *fl = container_of(file_lock_list.prev, struct file_lock, list);

		struct file_lock *fl = list_entry(file_lock_list.prev, struct file_lock, list);
> +
> +		if (fl->owners_fd != fd || pid != fl->fl_holder)
> +			break;
> +
> +		list_del(&fl->list);
> +		xfree(fl);
> +	}
> +}
> +
>  int correct_file_leases_type(struct pid *pid, int fd, int lfd)
>  {
>  	struct file_lock *fl;
> @@ -428,10 +441,9 @@ int correct_file_leases_type(struct pid *pid, int fd, int lfd)
>  
>  	list_for_each_entry(fl, &file_lock_list, list) {
>  		/* owners_fd should be set before usage */
> -		if (fl->fl_owner != pid->real || fl->owners_fd != fd)
> +		if (fl->fl_holder != pid->real || fl->owners_fd != fd)
>  			continue;
>  
> -		fl->updated = true;
>  		if (fl->fl_kind == FL_LEASE &&
>  			(fl->fl_ltype & LEASE_BREAKING)) {
>  			/*
> diff --git a/criu/files.c b/criu/files.c
> index 30ecb4bb..977d65cb 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -321,6 +321,8 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
>  	ret = fd_id_generate(p->pid, e, p);
>  	if (ret == 1) /* new ID generated */
>  		ret = ops->dump(lfd, e->id, p);
> +	else if (S_ISREG(p->stat.st_mode))
> +		discard_dup_locks_tail(p->pid, e->fd);
>  
>  	return ret;
>  }
> diff --git a/criu/include/file-lock.h b/criu/include/file-lock.h
> index 14a33b43..f79eedc5 100644
> --- a/criu/include/file-lock.h
> +++ b/criu/include/file-lock.h
> @@ -46,7 +46,8 @@ struct file_lock {
>  	int		fl_kind;
>  	int		fl_ltype;
>  
> -	pid_t		fl_owner;
> +	pid_t		fl_owner; /* process, which created the lock */
> +	pid_t		fl_holder; /* pid of fd on whose the lock is found */
>  	int		maj, min;
>  	unsigned long	i_no;
>  	long long	start;
> @@ -56,8 +57,6 @@ struct file_lock {
>  
>  	int		real_owner;
>  	int		owners_fd;
> -
> -	bool		updated;	/* used to remove duplicate leases */
>  };
>  
>  extern struct list_head file_lock_list;
> @@ -70,6 +69,7 @@ extern struct collect_image_info file_locks_cinfo;
>  
>  struct pid;
>  struct fd_parms;
> +extern void discard_dup_locks_tail(pid_t pid, int fd);
>  extern int correct_file_leases_type(struct pid *, int fd, int lfd);
>  extern int note_file_lock(struct pid *, int fd, int lfd, struct fd_parms *);
>  extern int dump_file_locks(void);
> diff --git a/criu/proc_parse.c b/criu/proc_parse.c
> index a4d6998d..42cb5fe7 100644
> --- a/criu/proc_parse.c
> +++ b/criu/proc_parse.c
> @@ -1780,6 +1780,7 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, void *arg)
>  			}
>  
>  			fl->real_owner = fdinfo->owner;
> +			fl->fl_holder = pid;
>  			fl->owners_fd = fd;
>  			list_add_tail(&fl->list, &file_lock_list);
>  		}
> @@ -2073,8 +2074,6 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
>  		return -1;
>  	}
>  
> -	fl->updated = false;
> -
>  	if (!strcmp(fl_flag, "POSIX"))
>  		fl->fl_kind = FL_POSIX;
>  	else if (!strcmp(fl_flag, "FLOCK"))
> -- 
> 2.14.1.473.g3ec7d702a8
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list