[CRIU] [PATCH v8 06/15] files: new "used" files list introduced

Kirill Tkhai ktkhai at virtuozzo.com
Thu May 26 06:20:14 PDT 2016


В Ср, 16/03/2016 в 16:17 +0300, Stanislav Kinsburskiy пишет:
> This list contains all per-process used file fdinfo's, sorted by fd
> number.
> Will be used to safely create new artificial file descriptors and
> also allow
> to recreate temporary descriptors with original number, if possible,
> like
> AutoFS tries to preserve original pipe write end descriptor, when it
> was
> closed.
> This patch also adds a couple of simple helpers to find unused file
> descriptor:
> 1) fd_is_used() does exactly what it is named
> 2) find_unused_fd() returns "hint_fd" if unused or last used
> descriptor plus
> one.
> 
> Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
> ---
>  criu/files.c            |    3 +++
>  criu/include/files.h    |   33 +++++++++++++++++++++++++++++++++
>  criu/include/rst_info.h |    1 +
>  3 files changed, 37 insertions(+)
> 
> diff --git a/criu/files.c b/criu/files.c
> index 8a7d85f..40bb13a 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -646,6 +646,8 @@ static int collect_fd(int pid, FdinfoEntry *e,
> struct rst_info *rst_info)
>  	else
>  		collect_gen_fd(new_le, rst_info);
>  
> +	collect_used_fd(new_le, rst_info);
> +
>  	list_add_tail(&new_le->desc_list, &le->desc_list);
>  	new_le->desc = fdesc;
>  
> @@ -686,6 +688,7 @@ int prepare_fd_pid(struct pstree_item *item)
>  	pid_t pid = item->pid.virt;
>  	struct rst_info *rst_info = rsti(item);
>  
> +	INIT_LIST_HEAD(&rst_info->used);
>  	INIT_LIST_HEAD(&rst_info->fds);
>  	INIT_LIST_HEAD(&rst_info->eventpoll);
>  	INIT_LIST_HEAD(&rst_info->tty_slaves);
> diff --git a/criu/include/files.h b/criu/include/files.h
> index 5db6ab1..d38dbfd 100644
> --- a/criu/include/files.h
> +++ b/criu/include/files.h
> @@ -67,6 +67,7 @@ struct fdinfo_list_entry {
>  	struct list_head	desc_list;	/* To chain
> on  @fd_info_head */
>  	struct file_desc	*desc;		/* Associated
> file descriptor */
>  	struct list_head	ps_list;	/* To chain  per-
> task files */
> +	struct list_head	used_list;	/* To chain per-
> task used fds */
>  	int			pid;
>  	futex_t			real_pid;
>  	FdinfoEntry		*fe;
> @@ -108,11 +109,43 @@ struct file_desc_ops {
>  	char *			(*name)(struct file_desc *,
> char *b, size_t s);
>  };
>  
> +static inline void collect_used_fd(struct fdinfo_list_entry
> *new_fle, struct rst_info *ri)
> +{
> +	struct fdinfo_list_entry *fle;
> +
> +	list_for_each_entry(fle, &ri->used, used_list) {
> +		if (new_fle->fe->fd < fle->fe->fd)
> +			break;
> +	}
> +
> +	list_add_tail(&new_fle->used_list, &fle->used_list);
> +}
> +
>  static inline void collect_gen_fd(struct fdinfo_list_entry *fle,
> struct rst_info *ri)
>  {
>  	list_add_tail(&fle->ps_list, &ri->fds);
>  }
>  
> +static inline bool fd_is_used(struct list_head *head, int fd)
> +{
> +	struct fdinfo_list_entry *fle;
> +
> +	list_for_each_entry(fle, head, used_list) {
> +		if (fle->fe->fd == fd)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +static inline unsigned int find_unused_fd(struct list_head *head,
> int hint_fd)
> +{
> +	if ((hint_fd >= 0) && (!fd_is_used(head, hint_fd)))
> +		return hint_fd;
> +	/* Return last used fd +1 */
> +	return list_entry(head->prev, typeof(struct
> fdinfo_list_entry), used_list)->fe->fd + 1;

What is guarantee that we have a space between the last fd and
INT/UINT_MAX?

> +}
> +
>  struct file_desc {
>  	u32			id;		/* File id,
> unique */
>  	struct hlist_node	hash;		/* Descriptor
> hashing and lookup */
> diff --git a/criu/include/rst_info.h b/criu/include/rst_info.h
> index b6d378e..562e2f0 100644
> --- a/criu/include/rst_info.h
> +++ b/criu/include/rst_info.h
> @@ -27,6 +27,7 @@ struct fdt {
>  struct _MmEntry;
>  
>  struct rst_info {
> +	struct list_head	used;
>  	struct list_head	fds;
>  	struct list_head	eventpoll;
>  	struct list_head	tty_slaves;
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list