[CRIU] [PATCH] timerfd: show procfs fdinfo helper, and now accepts write()

Andrew Vagin avagin at parallels.com
Tue Feb 4 11:31:31 PST 2014


Hello Shawn,

The comment for the patch is not enough detailed.

I think this patch must be splited on two patches:
* fdinfo
* interface for restoring a state of timefd

I would prefer to move intermediate discussions in criu at openvz.org and
to send the final version in lkml.

I think we need to develop the kernel patch together with an userspace
patch for criu. In this case we will be sure, that we take into account
all problems.

On Mon, Feb 03, 2014 at 08:01:13AM -0800, Shawn Landden wrote:
> | pos:	0
> | flags:	02004002
> | clockid:	0
> | ticks:        6
> 
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Alexander Viro <viro at zeniv.linux.org.uk>
> Signed-off-by: Shawn Landden <shawn at churchofgit.com>
> ---
>  fs/timerfd.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/fs/timerfd.c b/fs/timerfd.c
> index 9293121..2e81bdb 100644
> --- a/fs/timerfd.c
> +++ b/fs/timerfd.c
> @@ -25,6 +25,7 @@
>  #include <linux/syscalls.h>
>  #include <linux/compat.h>
>  #include <linux/rcupdate.h>
> +#include <linux/seq_file.h>
>  
>  struct timerfd_ctx {
>  	union {
> @@ -284,10 +285,73 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
>  	return res;
>  }
>  
> +#ifdef CONFIG_PROC_FS
> +static int timerfd_show_fdinfo(struct seq_file *m, struct file *f)
> +{
> +	struct timerfd_ctx *ctx = f->private_data;
> +
> +	seq_printf(m, "clockid:\t%d\n"
> +		      "ticks:\t%llu\n", ctx->clockid, ctx->ticks);
> +
> +	return 0;
> +}
> +#endif
> +
> +static ssize_t timerfd_write(struct file *file, const char __user *buf, size_t count,
> +			 loff_t *ppos)
> +{

What does this function do?

Today I have looked at the timefd code and I have idea how to restore ticks.
We can add a new TFD_RESTORE flag and use the fourth argument of
timerfd_settime() for restoring ticks. What do you think about that?

> +	struct timerfd_ctx *ctx = file->private_data;
> +	ssize_t res;
> +	__u64 ucnt;
> +	DECLARE_WAITQUEUE(wait, current);
> +
> +	if (count < sizeof(ucnt))
> +		return -EINVAL;
> +	if (copy_from_user(&ucnt, buf, sizeof(ucnt)))
> +		return -EFAULT;
> +	if (ucnt == ULLONG_MAX)
> +		return -EINVAL;
> +	spin_lock_irq(&ctx->wqh.lock);
> +	res = -EAGAIN;
> +	if (ULLONG_MAX - ctx->ticks > ucnt)
> +		res = sizeof(ucnt);
> +	else if (!(file->f_flags & O_NONBLOCK)) {
> +		__add_wait_queue(&ctx->wqh, &wait);
> +		for (res = 0;;) {
> +			set_current_state(TASK_INTERRUPTIBLE);
> +			if (ULLONG_MAX - ctx->ticks > ucnt) {
> +				res = sizeof(ucnt);
> +				break;
> +			}
> +			if (signal_pending(current)) {
> +				res = -ERESTARTSYS;
> +				break;
> +			}
> +			spin_unlock_irq(&ctx->wqh.lock);
> +			schedule();
> +			spin_lock_irq(&ctx->wqh.lock);
> +		}
> +		__remove_wait_queue(&ctx->wqh, &wait);
> +		__set_current_state(TASK_RUNNING);
> +	}
> +	if (likely(res > 0)) {
> +		ctx->ticks += ucnt;
> +		if (waitqueue_active(&ctx->wqh))
> +			wake_up_locked_poll(&ctx->wqh, POLLIN);
> +	}
> +	spin_unlock_irq(&ctx->wqh.lock);
> +
> +	return res;
> +}
> +
>  static const struct file_operations timerfd_fops = {
> +#ifdef CONFIG_PROC_FS
> +	.show_fdinfo	= timerfd_show_fdinfo,
> +#endif
>  	.release	= timerfd_release,
>  	.poll		= timerfd_poll,
>  	.read		= timerfd_read,
> +	.write		= timerfd_write,
>  	.llseek		= noop_llseek,
>  };
>  
> -- 
> 1.8.5.2.297.g3e57c29
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list