[CRIU] [PATCH v4 4/8] save net device confs bunched with criu sysctl API

Pavel Emelyanov xemul at parallels.com
Wed Oct 8 08:27:56 PDT 2014


On 10/08/2014 05:21 PM, Pavel Tikhomirov wrote:
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at parallels.com>
> ---
>  net.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 53 insertions(+), 1 deletion(-)
> 
> diff --git a/net.c b/net.c
> index def4fdc..f56f095 100644
> --- a/net.c
> +++ b/net.c
> @@ -18,6 +18,7 @@
>  #include "tun.h"
>  #include "util-pie.h"
>  #include "plugin.h"
> +#include "sysctl.h"
>  
>  #include "protobuf.h"
>  #include "protobuf/netdev.pb-c.h"
> @@ -78,6 +79,42 @@ char *devconfs[] = {
>  };
>  
>  #define NET_DEV_CONF_SIZE 27
> +#define NET_CONF_PATH "net/ipv4/conf"
> +
> +static int ipv4_conf_op(char *tgt, int *conf, int op)
> +{
> +	int ret;
> +	int i, j;
> +	struct sysctl_req req[NET_DEV_CONF_SIZE + 1];
> +	int sdir = strlen(tgt) + strlen(NET_CONF_PATH) + 1;
> +
> +	for (i = 0; devconfs[i]; i++) {
> +		char *path;
> +		int size = sdir + strlen(devconfs[i]) + 2;
> +
> +		path = xmalloc(size);

Size of NET_CONF_PATH is known, maximum size of device name is
IFNAMSIZ, size of "default" and "all" is known, maximum size of
devconfs[i] can be roughly set to 32. I'd say we don't need the
precise size xmalloc, just an upper estimation for it would
work.

Can we make the path-s non-xmalloc-ed as well, btw?

> +		if (!path) {
> +			ret = -1;
> +			goto free;
> +		}
> +		snprintf(path, size, "%s/%s/%s", NET_CONF_PATH, tgt, devconfs[i]);
> +
> +		req[i].name = path;
> +		req[i].arg = &conf[i];
> +		req[i].type = CTL_32;
> +	}
> +	req[i].name = NULL;
> +
> +	ret = sysctl_op(req, op);
> +	if (ret < 0)
> +		pr_err("Failed to read %s/<confs>\n", tgt);
> +free:
> +	for (j = 0; j < i; j++)
> +		xfree(req[j].name);
> +	if (ret < 0)
> +		return -1;
> +	return 0;

3 above lines can be replaced with return ret;

> +}
>  
>  int write_netdev_img(NetDeviceEntry *nde, struct cr_fdset *fds)
>  {
> @@ -88,6 +125,7 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
>  		struct rtattr **tb, struct cr_fdset *fds,
>  		int (*dump)(NetDeviceEntry *, struct cr_fdset *))
>  {
> +	int ret;
>  	NetDeviceEntry netdev = NET_DEVICE_ENTRY__INIT;
>  
>  	if (!tb[IFLA_IFNAME]) {
> @@ -110,10 +148,24 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
>  				(int)netdev.address.len, netdev.name);
>  	}
>  
> +	netdev.n_conf = NET_DEV_CONF_SIZE;
> +	netdev.conf = xmalloc(sizeof(int) * NET_DEV_CONF_SIZE);
> +	if (!netdev.conf)
> +		return -1;
> +
> +	ret = ipv4_conf_op(netdev.name, netdev.conf, CTL_READ);
> +	if (ret < 0) {
> +		pr_err("failed to get net device ipv4 conf");

On error message in ipv4_conf_op is more than enough.

> +		goto err_free;
> +	}
> +
>  	if (!dump)
>  		dump = write_netdev_img;
>  
> -	return dump(&netdev, fds);
> +	ret = dump(&netdev, fds);
> +err_free:
> +	xfree(netdev.conf);
> +	return ret;
>  }
>  
>  static char *link_kind(struct ifinfomsg *ifi, struct rtattr **tb)
> 



More information about the CRIU mailing list