[lxc-devel] [PATCH] Add remove_snapshots_entry()

Christian Brauner christianvanbrauner at gmail.com
Fri Sep 11 06:43:45 UTC 2015


When creating ephemeral containers that have the option lxc.ephemeral = 1 set
in their config, they will be destroyed on shutdown. As they are simple overlay
clones of an existing container they should be registered in the lxc_snapshots
file of the original container to stay consistent and adhere to the
expectancies of the users. Most of all, it ensure that we cannot remove a
container that has clones, even if they are just ephemeral snapshot-clones. The
function adds further consistency because remove_snapshots_entry() ensures that
ephemeral clone-snapshots deregister themselves from the lxc_snapshots file
when they are destroyed.

Signed-off-by: Christian Brauner <christianvanbrauner at gmail.com>
---
 src/lxc/start.c | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index 93c039c..f58d9a4 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -84,7 +84,7 @@ const struct ns_info ns_info[LXC_NS_MAX] = {
 	[LXC_NS_NET] = {"net", CLONE_NEWNET}
 };
 
-static void update_clone_snapshots(struct lxc_handler *handler, const char *name);
+static void remove_snapshot_entry(struct lxc_handler *handler, const char *name);
 static bool do_destroy_container(struct lxc_conf *conf);
 static int lxc_rmdir_onedev_wrapper(void *data);
 static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
@@ -1324,7 +1324,7 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
 		return;
 	}
 
-	update_clone_snapshots(handler, name);
+	remove_snapshot_entry(handler, name);
 
 	if (am_unpriv())
 		ret = userns_exec_1(handler->conf, lxc_rmdir_onedev_wrapper, destroy);
@@ -1353,7 +1353,7 @@ static bool do_destroy_container(struct lxc_conf *conf) {
         return bdev_destroy(conf);
 }
 
-static void update_clone_snapshots(struct lxc_handler *handler, const char *name)
+static void remove_snapshot_entry(struct lxc_handler *handler, const char *name)
 {
 	char rdepfile[MAXPATHLEN];
 	char path[MAXPATHLEN];
@@ -1365,9 +1365,9 @@ static void update_clone_snapshots(struct lxc_handler *handler, const char *name
 	char *origpath = NULL;
 	char *origname = NULL;
 	int ret = 0;
+	int bytes = 0;
 	int fd = -1;
 	size_t len = 0;
-	size_t difflen = 0;
 	struct stat fbuf;
 
 	ret = snprintf(rdepfile, MAXPATHLEN, "%s/%s/lxc_rdepends", handler->lxcpath, name);
@@ -1435,7 +1435,13 @@ static void update_clone_snapshots(struct lxc_handler *handler, const char *name
 	}
 
 	if (fbuf.st_size != 0) {
-		buf = mmap(NULL, fbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+		/* write terminating \0-byte to file */
+		if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
+			close(fd);
+			return;
+		}
+
+		buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 		if (buf == MAP_FAILED) {
 			SYSERROR("Failed to create mapping %s", path);
 			close(fd);
@@ -1443,25 +1449,16 @@ static void update_clone_snapshots(struct lxc_handler *handler, const char *name
 		}
 
 		len = strlen(newpath);
+		while ((del = strstr((char *)buf, newpath))) {
+			memmove(del, del + len, strlen(del) - len + 1);
+			bytes += len;
+		}
 
-		/* mmap()ed memory is only \0-terminated when it is not
-		 * a multiple of a pagesize. Hence, we'll use memmem(). */
-		if ((del = memmem(buf, fbuf.st_size, newpath, len))) {
-			/* remove container entry */
-			if (del != buf + fbuf.st_size - len) {
-				difflen = fbuf.st_size - (del - buf);
-				memmove(del, del + len, strnlen(del, difflen) - len);
-			}
-
-			munmap(buf, fbuf.st_size);
-
-			if (ftruncate(fd, fbuf.st_size - len) < 0) {
-				SYSERROR("Failed to truncate file %s", path);
-				close(fd);
-				return;
-			}
-		} else {
-			munmap(buf, fbuf.st_size);
+		munmap(buf, fbuf.st_size + 1);
+		if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
+			SYSERROR("Failed to truncate file %s", path);
+			close(fd);
+			return;
 		}
 	}
 
-- 
2.5.1



More information about the lxc-devel mailing list