[lxc-devel] [PATCH 1/2 v2] Add clone_update_unexp_ovl_dir() function

Serge Hallyn serge.hallyn at ubuntu.com
Fri Oct 30 15:08:37 UTC 2015


Quoting Christian Brauner (christianvanbrauner at gmail.com):
> This functions updates absolute paths for overlay upper- and workdirs so users
> can simply clone and start new containers without worrying about absolute paths
> in lxc.mount.entry overlay entries.
> 
> Signed-off-by: Christian Brauner <christianvanbrauner at gmail.com>
> ---
>  src/lxc/confile.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/confile.h |   3 ++
>  2 files changed, 106 insertions(+)
> 
> diff --git a/src/lxc/confile.c b/src/lxc/confile.c
> index f7d6814..bc5b7ef 100644
> --- a/src/lxc/confile.c
> +++ b/src/lxc/confile.c
> @@ -2598,6 +2598,109 @@ void clear_unexp_config_line(struct lxc_conf *conf, const char *key, bool rm_sub
>  	}
>  }
>  
> +bool clone_update_unexp_ovl_dir(struct lxc_conf *conf, const char *oldpath,
> +				const char *newpath, const char *oldname,
> +				const char *newname, const char *ovldir)
> +{
> +	const char *key = "lxc.mount.entry";
> +	int ret;
> +	char *lstart = conf->unexpanded_config;
> +	char *lend;
> +	char *p;
> +	char *q;
> +	size_t newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2;
> +	size_t olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 2;
> +	char *olddir = alloca(olddirlen + 1);
> +	char *newdir = alloca(newdirlen + 1);
> +
> +	ret = snprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, oldname);
> +	if (ret < 0 || ret >= olddirlen + 1) {
> +		ERROR("Bug in %s", __func__);
> +		return false;
> +	}
> +	ret = snprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, newname);
> +	if (ret < 0 || ret >= newdirlen + 1) {
> +		ERROR("Bug in %s", __func__);
> +		return false;
> +	}
> +	if (!conf->unexpanded_config)
> +		return true;
> +	while (*lstart) {
> +		lend = strchr(lstart, '\n');
> +		if (!lend)
> +			lend = lstart + strlen(lstart);
> +		else
> +			lend++;
> +		if (strncmp(lstart, key, strlen(key)) != 0) {
> +			lstart = lend;
> +			continue;
> +		}
> +		p = strchr(lstart + strlen(key), '=');
> +		if (!p) {
> +			lstart = lend;
> +			continue;
> +		}
> +		p++;
> +		while (isblank(*p))
> +			p++;
> +		if (!*p)
> +			return true;

I think you should 

		if (p >= lend)
			continue;

(and then you can skip the !*p check above as this should catch that)

What you have will only get confused on invalid configs, but this would
be stricter and make me feel better.

> +		/* We check that when an lxc.mount.entry is found the substrings
> +		 * " overlay " or " aufs " are present before we try to update
> +		 * the line. This seems like a bit more safety. We can check for
> +		 * " overlay " and " aufs " since both substrings need to have
> +		 * at least one space before and after them. When the space
> +		 * before or after is missing it is very likely that these
> +		 * substrings are part of a path or something else. So we
> +		 * shouldn't bother to do any further work...
> +		 */
> +		if (!strstr(p, " overlay ") && !strstr(p, " aufs ")) {
> +			lstart = lend;
> +			continue;
> +		}

But this will find " overlay " in any subsequent lines too right?  Don't you
need to limit your search to the line?  Maybe by saving *lend and setting
*lend = '\0'?

> +		if (!(q = strstr(p, olddir))) {
> +			lstart = lend;
> +			continue;
> +		}
> +
> +		/* replace the olddir with newdir */
> +		if (olddirlen >= newdirlen) {
> +			size_t diff = olddirlen - newdirlen;
> +			memcpy(q, newdir, newdirlen);
> +			if (olddirlen != newdirlen) {
> +				memmove(q + newdirlen, q + newdirlen + diff,
> +					strlen(q) - newdirlen - diff + 1);
> +				lend -= diff;
> +				conf->unexpanded_len -= diff;
> +			}
> +			lstart = lend;
> +		} else {
> +			char *new;
> +			size_t diff = newdirlen - olddirlen;
> +			size_t oldlen = conf->unexpanded_len;
> +			size_t newlen = oldlen + diff;
> +			size_t poffset = q - conf->unexpanded_config;
> +			new = realloc(conf->unexpanded_config, newlen + 1);
> +			if (!new) {
> +				ERROR("Out of memory");
> +				return false;
> +			}
> +			conf->unexpanded_len = newlen;
> +			conf->unexpanded_alloced = newlen + 1;
> +			new[newlen-1] = '\0';
> +			lend = new + (lend - conf->unexpanded_config);
> +			/* move over the remainder to make room for the newdir */
> +			memmove(new + poffset + newdirlen,
> +				new + poffset + olddirlen,
> +				oldlen - poffset - olddirlen + 1);
> +			conf->unexpanded_config = new;
> +			memcpy(new + poffset, newdir, newdirlen);
> +			lstart = lend + diff;

Heh, I *think* the above bit is all right.

> +		}
> +	}
> +	return true;
> +}
> +
>  bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
>  	const char *newpath, const char *oldname, const char *newname)
>  {
> diff --git a/src/lxc/confile.h b/src/lxc/confile.h
> index 8da3699..66af832 100644
> --- a/src/lxc/confile.h
> +++ b/src/lxc/confile.h
> @@ -61,5 +61,8 @@ extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
>  extern void clear_unexp_config_line(struct lxc_conf *conf, const char *key, bool rm_subkeys);
>  extern bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
>  	const char *newpath, const char *oldname, const char *newmame);
> +bool clone_update_unexp_ovl_dir(struct lxc_conf *conf, const char *oldpath,
> +				const char *newpath, const char *oldname,
> +				const char *newname, const char *ovldir);
>  extern bool network_new_hwaddrs(struct lxc_conf *conf);
>  #endif
> -- 
> 2.6.2
> 


More information about the lxc-devel mailing list