[CRIU] [PATCH] pipes: Restore pipe size via userns call

Pavel Emelyanov xemul at virtuozzo.com
Mon Feb 6 02:22:39 PST 2017


On 02/03/2017 09:28 PM, Cyrill Gorcunov wrote:
> From: Cyrill Gorcunov <gorcunov at virtuozzo.com>
> 
> In vanilla kernels starting from v4.4-6172-g759c011
> pipes allocation is limited per user-namespace, and
> what is more interesting is that if hard limit is
> zero but softlimit is not, then it is possible to
> create new pipes with one buffer but setting its
> size if not allowed until we're having CAP_SYS_RESOURCE
> and CAP_SYS_ADMIN caps granted.
> 
> So to be able to restore this resource we need
> to use userns daemon.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
> ---
>  criu/pipes.c | 32 +++++++++++++++++++++++++-------
>  1 file changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/criu/pipes.c b/criu/pipes.c
> index 7be1d5f047a1..26aa2b4c359f 100644
> --- a/criu/pipes.c
> +++ b/criu/pipes.c
> @@ -11,6 +11,7 @@
>  #include "pipes.h"
>  #include "util-pie.h"
>  #include "autofs.h"
> +#include "namespaces.h"
>  
>  #include "protobuf.h"
>  #include "util.h"
> @@ -142,6 +143,25 @@ static int mark_pipe_master(void *unused)
>  
>  static struct pipe_data_rst *pd_hash_pipes[PIPE_DATA_HASH_SIZE];
>  
> +typedef struct {
> +	unsigned int	pipe_id;
> +	size_t		size;
> +} pipe_set_size_arg_t;
> +
> +static int pipe_set_size(void *arg, int fd, int pid)
> +{
> +	pipe_set_size_arg_t *p = arg;
> +
> +	pr_info("Restoring size %#zx for %#x\n", p->size, p->pipe_id);

You don't need pipe_id here, just print it before calling userns_call and
remove this ugly pipe_set_size_arg_t.

> +
> +	if (fcntl(fd, F_SETPIPE_SZ, p->size) < 0) {
> +		pr_perror("Can't restore pipe size");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash)
>  {
>  	int ret;
> @@ -201,13 +221,11 @@ int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash
>  out:
>  	ret = 0;
>  	if (pd->pde->has_size) {
> -		pr_info("Restoring size %#x for %#x\n",
> -				pd->pde->size, pd->pde->pipe_id);
> -		ret = fcntl(pfd, F_SETPIPE_SZ, pd->pde->size);
> -		if (ret < 0)
> -			pr_perror("Can't restore pipe size");
> -		else
> -			ret = 0;
> +		pipe_set_size_arg_t args = {
> +			.pipe_id	= pd->pde->pipe_id,
> +			.size		= (size_t)pd->pde->size,
> +		};
> +		ret = userns_call(pipe_set_size, UNS_ASYNC, &args, sizeof(args), pfd);
>  	}
>  err:
>  	return ret;
> 



More information about the CRIU mailing list