[lxc-devel] [PATCH] rename physical nics at shutdown

Stéphane Graber stgraber at ubuntu.com
Tue Dec 4 19:08:52 UTC 2012


On 12/04/2012 01:19 PM, Serge Hallyn wrote:
> When a physical nic is being set up, store its ifindex and original name
> in struct lxc_conf.  At reboot, reset the original name.
> We can't just go over the original network list in lxc_conf at shutdown
> because that may be tweaked in the meantime through the C api.  The
> saved_nics list is only setup during lxc_spawn(), and restored and
> freed after lxc_start.
> 
> Without this patch, if you take a container with physical nic eth1
> renamed to eth0, start it, shut it down, and restart it, the last
> restart will fail.
> 
> Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1086244
> 
> Reported-by: Avijit Ghosh <avijit.ghosh at aricent.com>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Just one comment below, but looks good.

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  src/lxc/conf.c    |   28 ++++++++++++++++++++++++++++
>  src/lxc/conf.h    |    9 +++++++++
>  src/lxc/execute.c |    6 ++++--
>  src/lxc/start.c   |   38 ++++++++++++++++++++++++++++++++++++++
>  4 files changed, 79 insertions(+), 2 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 79d96d7..45e0b31 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -1821,6 +1821,21 @@ static int setup_network(struct lxc_list *network)
>  	return 0;
>  }
>  
> +void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf)
> +{
> +	int i;
> +
> +	INFO("running to reset %d nic names", conf->num_savednics);
> +	for (i=0; i<conf->num_savednics; i++) {
> +		struct saved_nic *s = &conf->saved_nics[i];
> +		INFO("resetting nic %d to %s\n", s->ifindex, s->orig_name);
> +		lxc_netdev_rename_by_index(s->ifindex, s->orig_name);
> +		free(s->orig_name);
> +	}
> +	conf->num_savednics = 0;
> +	free(conf->saved_nics);
> +}
> +
>  static int setup_private_host_hw_addr(char *veth1)
>  {
>  	struct ifreq ifr;
> @@ -2710,6 +2725,18 @@ int lxc_clear_hooks(struct lxc_conf *c, const char *key)
>  	return 0;
>  }
>  
> +void lxc_clear_saved_nics(struct lxc_conf *conf)
> +{
> +	int i;
> +
> +	if (!conf->num_savednics)
> +		return;
> +	for (i=0; i < conf->num_savednics; i++)
> +		free(conf->saved_nics[i].orig_name);
> +	conf->saved_nics = 0;
> +	free(conf->saved_nics);
> +}
> +
>  void lxc_conf_free(struct lxc_conf *conf)
>  {
>  	if (!conf)
> @@ -2737,5 +2764,6 @@ void lxc_conf_free(struct lxc_conf *conf)
>  	lxc_clear_cgroups(conf, "lxc.cgroup");
>  	lxc_clear_hooks(conf, "lxc.hook");
>  	lxc_clear_mount_entries(conf);
> +	lxc_clear_saved_nics(conf);
>  	free(conf);
>  }
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index 694bce4..3f6181f 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -211,6 +211,11 @@ enum lxchooks {
>  	LXCHOOK_POSTSTOP, NUM_LXC_HOOKS};
>  extern char *lxchook_names[NUM_LXC_HOOKS];
>  
> +struct saved_nic {
> +	int ifindex;
> +	char *orig_name;
> +};
> +
>  struct lxc_conf {
>  	char *fstab;
>  	int tty;
> @@ -221,6 +226,8 @@ struct lxc_conf {
>  	struct utsname *utsname;
>  	struct lxc_list cgroup;
>  	struct lxc_list network;
> +	struct saved_nic *saved_nics;
> +	int num_savednics;
>  	struct lxc_list mount_list;
>  	struct lxc_list caps;
>  	struct lxc_tty_info tty_info;
> @@ -273,4 +280,6 @@ extern int lxc_clear_hooks(struct lxc_conf *c, const char *key);
>   */
>  
>  extern int lxc_setup(const char *name, struct lxc_conf *lxc_conf);
> +
> +extern void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf);
>  #endif
> diff --git a/src/lxc/execute.c b/src/lxc/execute.c
> index 487765f..730b793 100644
> --- a/src/lxc/execute.c
> +++ b/src/lxc/execute.c
> @@ -27,7 +27,6 @@
>  #include <unistd.h>
>  #include <stdlib.h>
>  
> -
>  #include "log.h"
>  #include "start.h"
>  
> @@ -134,9 +133,12 @@ int lxc_execute(const char *name, char *const argv[], int quiet,
>  		.argv = argv,
>  		.quiet = quiet
>  	};
> +	int ret;
>  
>  	if (lxc_check_inherited(conf, -1))
>  		return -1;
>  
> -	return __lxc_start(name, conf, &execute_start_ops, &args);
> +	ret = __lxc_start(name, conf, &execute_start_ops, &args);
> +
> +	return ret;
>  }

What's the reason for that bit? Looks to me as functionally identical.

> diff --git a/src/lxc/start.c b/src/lxc/start.c
> index 3e26b27..7320d74 100644
> --- a/src/lxc/start.c
> +++ b/src/lxc/start.c
> @@ -579,6 +579,37 @@ out_warn_father:
>  	return -1;
>  }
>  
> +int save_phys_nics(struct lxc_conf *conf)
> +{
> +	struct lxc_list *iterator;
> +
> +	lxc_list_for_each(iterator, &conf->network) {
> +		struct lxc_netdev *netdev = iterator->elem;
> +
> +		if (netdev->type != LXC_NET_PHYS)
> +			continue;
> +		conf->saved_nics = realloc(conf->saved_nics,
> +				(conf->num_savednics+1)*sizeof(struct saved_nic));
> +		if (!conf->saved_nics) {
> +			SYSERROR("failed to allocate memory");
> +			return -1;
> +		}
> +		conf->saved_nics[conf->num_savednics].ifindex = netdev->ifindex;
> +		conf->saved_nics[conf->num_savednics].orig_name = strdup(netdev->link);
> +		if (!conf->saved_nics[conf->num_savednics].orig_name) {
> +			SYSERROR("failed to allocate memory");
> +			return -1;
> +		}
> +		INFO("stored saved_nic #%d idx %d name %s\n", conf->num_savednics,
> +			conf->saved_nics[conf->num_savednics].ifindex,
> +			conf->saved_nics[conf->num_savednics].orig_name);
> +		conf->num_savednics++;
> +	}
> +
> +	return 0;
> +}
> +
> +
>  int lxc_spawn(struct lxc_handler *handler)
>  {
>  	int failed_before_rename = 0;
> @@ -613,6 +644,11 @@ int lxc_spawn(struct lxc_handler *handler)
>  		}
>  	}
>  
> +	if (save_phys_nics(handler->conf)) {
> +		ERROR("failed to save physical nic info");
> +		goto out_abort;
> +	}
> +
>  	/*
>  	 * if the rootfs is not a blockdev, prevent the container from
>  	 * marking it readonly.
> @@ -739,6 +775,8 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
>  		}
>          }
>  
> +	lxc_rename_phys_nics_on_shutdown(handler->conf);
> +
>  	err =  lxc_error_set_and_log(handler->pid, status);
>  out_fini:
>  	lxc_delete_network(handler);
> 


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121204/7e4b1300/attachment.pgp>


More information about the lxc-devel mailing list