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

Christian Brauner christianvanbrauner at gmail.com
Tue Oct 27 20:32:49 UTC 2015


Signed-off-by: Christian Brauner <christianvanbrauner at gmail.com>
---
 src/lxc/confile.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/confile.h |  3 ++
 2 files changed, 101 insertions(+)

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index f7d6814..098fd3d 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -2598,6 +2598,104 @@ 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) + 1 + 1;
+	size_t olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 1 + 1;
+	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;
+		/* 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 "))
+			continue;
+		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(lend-diff, lend, strlen(lend)+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);
+			if (!new) {
+				ERROR("Out of memory");
+				return false;
+			}
+			conf->unexpanded_len = newlen;
+			new[newlen-1] = '\0';
+			lend = new + (lend - conf->unexpanded_config);
+			/* move over the remainder, /$hookname\n$rest */
+			memmove(new+poffset+newdirlen,
+					new+poffset+olddirlen,
+					oldlen-poffset-olddirlen);
+			conf->unexpanded_config = new;
+			memcpy(new+poffset, newdir, newdirlen);
+			lstart = lend + diff;
+		}
+	}
+	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