[CRIU] [PATCHv3 1/2] unix: sysctl -- Preserve max_dgram_qlen value

Andrei Vagin avagin at gmail.com
Sun Nov 3 19:55:16 MSK 2019


On Fri, Nov 01, 2019 at 12:00:20PM +0000, Alexander Mikhalitsyn wrote:
> The /proc/sys/net/unix/max_dgram_qlen is a per-net variable and
> we already noticed that systemd inside a container may change its value
> (for example it sets it to 512 by now instead of kernel's default
> value 10), thus we need keep it inside image and restore then.
> 
> Based-on-patch-by: Cyrill Gorcunov <gorcunov at gmail.com>

This might mean that the author should be Cyrill.

https://github.com/torvalds/linux/blob/master/Documentation/process/submitting-patches.rst#12-when-to-use-acked-by-cc-and-co-developed-by

Cyrill, could you review this patch?

> Signed-off-by: Alexander Mikhalitsyn <alexander at mihalicyn.com>
> Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
> ---
>  criu/net.c          | 102 +++++++++++++++++++++++++++++++++++++++++++-
>  images/netdev.proto |   1 +
>  2 files changed, 102 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/net.c b/criu/net.c
> index fe9b51ad..843f74d7 100644
> --- a/criu/net.c
> +++ b/criu/net.c
> @@ -210,6 +210,15 @@ char *devconfs6[] = {
>  #define MAX_CONF_OPT_PATH IFNAMSIZ+60
>  #define MAX_STR_CONF_LEN 200
>  
> +static char *unix_conf_entries[] = {
> +	"max_dgram_qlen",
> +};
> +
> +#define CONF_UNIX_BASE		"net/unix"
> +#define CONF_UNIX_FMT		CONF_UNIX_BASE"/%s"
> +#define MAX_CONF_UNIX_OPT_PATH	32
> +#define MAX_CONF_UNIX_PATH	(sizeof(CONF_UNIX_FMT) + MAX_CONF_UNIX_OPT_PATH - 2)
> +
>  static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto,
>  		struct sysctl_req *req, char (*path)[MAX_CONF_OPT_PATH], int size,
>  		char **devconfs, SysctlEntry **def_conf)
> @@ -339,6 +348,72 @@ static int ipv6_conf_op(char *tgt, SysctlEntry **conf, int n, int op, SysctlEntr
>  			devconfs6, def_conf);
>  }
>  
> +static int unix_conf_op(SysctlEntry ***rconf, size_t *n, int op)
> +{
> +	int i, ret = -1, flags = op == CTL_READ ? CTL_FLAGS_OPTIONAL : 0;
> +	char path[ARRAY_SIZE(unix_conf_entries)][MAX_CONF_UNIX_PATH] = { };
> +	struct sysctl_req req[ARRAY_SIZE(unix_conf_entries)] = { };
> +	SysctlEntry **conf = *rconf;
> +
> +	if (*n != ARRAY_SIZE(unix_conf_entries)) {
> +		pr_err("unix: Unexpected entries in config (%u %u)\n",
> +		       (unsigned)*n, (unsigned)ARRAY_SIZE(unix_conf_entries));
> +		return -EINVAL;
> +	}
> +
> +	if (opts.weak_sysctls)
> +		flags = CTL_FLAGS_OPTIONAL;
> +
> +	for (i = 0; i < *n; i++) {
> +		snprintf(path[i], MAX_CONF_UNIX_PATH, CONF_UNIX_FMT,
> +			 unix_conf_entries[i]);
> +		req[i].name = path[i];
> +		req[i].flags = flags;
> +
> +		switch (conf[i]->type) {
> +		case SYSCTL_TYPE__CTL_32:
> +			req[i].type = CTL_32;
> +			req[i].arg = &conf[i]->iarg;
> +			break;
> +		default:
> +			pr_err("unix: Unknown config type %d\n",
> +			       (unsigned)conf[i]->type);
> +			return -1;
> +		}
> +	}
> +
> +	ret = sysctl_op(req, *n, op, CLONE_NEWNET);
> +	if (ret < 0) {
> +		pr_err("unix: Failed to %s %s/<confs>\n",
> +		       (op == CTL_READ) ? "read" : "write",
> +		       CONF_UNIX_BASE);
> +		return -1;
> +	}
> +
> +	if (op == CTL_READ) {
> +		bool has_entries = false;
> +
> +		for (i = 0; i < *n; i++) {
> +			if (req[i].flags & CTL_FLAGS_HAS) {
> +				conf[i]->has_iarg = true;
> +				if (!has_entries)
> +					has_entries = true;
> +			}
> +		}
> +
> +		/*
> +		 * Zap the whole section of data.
> +		 * Unix conf is optional.
> +		 */
> +		if (!has_entries) {
> +			*n = 0;
> +			*rconf = NULL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * I case if some entry is missing in
>   * the kernel, simply write DEVCONFS_UNUSED
> @@ -1824,6 +1899,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>  	int ret = -1;
>  	int i;
>  	NetnsEntry netns = NETNS_ENTRY__INIT;
> +	SysctlEntry *unix_confs = NULL;
> +	size_t sizex = ARRAY_SIZE(unix_conf_entries);
>  	SysctlEntry *def_confs4 = NULL, *all_confs4 = NULL;
>  	int size4 = ARRAY_SIZE(devconfs4);
>  	SysctlEntry *def_confs6 = NULL, *all_confs6 = NULL;
> @@ -1840,7 +1917,8 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>  	o_buf = buf = xmalloc(
>  			i * (sizeof(NetnsId*) + sizeof(NetnsId)) +
>  			size4 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 +
> -			size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2
> +			size6 * (sizeof(SysctlEntry*) + sizeof(SysctlEntry)) * 2 +
> +			sizex * (sizeof(SysctlEntry*) + sizeof(SysctlEntry))

need to add a comment which explains what all these mean

>  		     );
>  	if (!buf)
>  		goto out;
> @@ -1896,6 +1974,16 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>  		}
>  	}
>  
> +	netns.n_unix_conf = sizex;
> +	netns.unix_conf = xptr_pull_s(&buf, sizex * sizeof(SysctlEntry*));
> +	unix_confs = xptr_pull_s(&buf, sizex * sizeof(SysctlEntry));
> +
> +	for (i = 0; i < sizex; i++) {
> +		sysctl_entry__init(&unix_confs[i]);
> +		netns.unix_conf[i] = &unix_confs[i];
> +		netns.unix_conf[i]->type = SYSCTL_TYPE__CTL_32;
> +	}
> +
>  	ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL);
>  	if (ret < 0)
>  		goto err_free;
> @@ -1910,6 +1998,12 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
>  	if (ret < 0)
>  		goto err_free;
>  
> +	ret = unix_conf_op(&netns.unix_conf, &netns.n_unix_conf, CTL_READ);
> +	if (ret < 0)
> +		goto err_free;
> +
> +
> +

too many empty lines

>  	ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS);
>  err_free:
>  	xfree(o_buf);
> @@ -2148,6 +2242,12 @@ static int restore_netns_conf(struct ns_id *ns)
>  		ret = ipv6_conf_op("default", (netns)->def_conf6, (netns)->n_def_conf6, CTL_WRITE, NULL);
>  	}
>  
> +	if ((netns)->unix_conf) {
> +		ret = unix_conf_op(&(netns)->unix_conf, &(netns)->n_unix_conf, CTL_WRITE);
> +		if (ret)
> +			goto out;
> +	}
> +
>  	ns->net.netns = netns;
>  out:
>  	return ret;
> diff --git a/images/netdev.proto b/images/netdev.proto
> index 476a92ce..ae9c9953 100644
> --- a/images/netdev.proto
> +++ b/images/netdev.proto
> @@ -71,4 +71,5 @@ message netns_entry {
>  
>  	repeated netns_id nsids		= 7;
>  	optional string	ext_key		= 8;
> +	repeated sysctl_entry unix_conf	= 9;
>  }
> -- 
> 2.17.1
> 
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list