[lxc-devel] [PATCH] c/r: factor out network dump/restore code

Tycho Andersen tycho.andersen at canonical.com
Fri Oct 10 14:55:37 UTC 2014


Break the monolithic ->checkpoint and ->restore functions into smaller ones.
This is in preparation for the checkpoint/restore tty work, which has a similar
need to dump information outside of criu.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/lxccontainer.c | 128 ++++++++++++++++++++++++++-----------------------
 1 file changed, 69 insertions(+), 59 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 4c3d4d5..703042a 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -3698,30 +3698,21 @@ static bool criu_ok(struct lxc_container *c)
 	return true;
 }
 
-static bool lxcapi_checkpoint(struct lxc_container *c, char *directory, bool stop, bool verbose)
+static bool dump_net_info(struct lxc_container *c, char *directory)
 {
-	int netnr, status;
+	int netnr;
 	struct lxc_list *it;
-	bool error = false;
-	pid_t pid;
-
-	if (!criu_ok(c))
-		return false;
-
-	if (mkdir(directory, 0700) < 0 && errno != EEXIST)
-		return false;
 
 	netnr = 0;
 	lxc_list_for_each(it, &c->lxc_conf->network) {
 		char *veth = NULL, *bridge = NULL, veth_path[PATH_MAX], eth[128];
 		struct lxc_netdev *n = it->elem;
+		bool has_error = true;
 		int pret;
 
 		pret = snprintf(veth_path, PATH_MAX, "lxc.network.%d.veth.pair", netnr);
-		if (pret < 0 || pret >= PATH_MAX) {
-			error = true;
+		if (pret < 0 || pret >= PATH_MAX)
 			goto out;
-		}
 
 		veth = lxcapi_get_running_config_item(c, veth_path);
 		if (!veth) {
@@ -3733,49 +3724,59 @@ static bool lxcapi_checkpoint(struct lxc_container *c, char *directory, bool sto
 		}
 
 		pret = snprintf(veth_path, PATH_MAX, "lxc.network.%d.link", netnr);
-		if (pret < 0 || pret >= PATH_MAX) {
-			error = true;
+		if (pret < 0 || pret >= PATH_MAX)
 			goto out;
-		}
 
 		bridge = lxcapi_get_running_config_item(c, veth_path);
-		if (!bridge) {
-			error = true;
+		if (!bridge)
 			goto out;
-		}
 
 		pret = snprintf(veth_path, PATH_MAX, "%s/veth%d", directory, netnr);
-		if (pret < 0 || pret >= PATH_MAX || print_to_file(veth_path, veth) < 0) {
-			error = true;
+		if (pret < 0 || pret >= PATH_MAX || print_to_file(veth_path, veth) < 0)
 			goto out;
-		}
 
 		pret = snprintf(veth_path, PATH_MAX, "%s/bridge%d", directory, netnr);
-		if (pret < 0 || pret >= PATH_MAX || print_to_file(veth_path, bridge) < 0) {
-			error = true;
+		if (pret < 0 || pret >= PATH_MAX || print_to_file(veth_path, bridge) < 0)
 			goto out;
-		}
 
 		if (n->name) {
-			if (strlen(n->name) >= 128) {
-				error = true;
+			if (strlen(n->name) >= 128)
 				goto out;
-			}
 			strncpy(eth, n->name, 128);
 		} else
 			sprintf(eth, "eth%d", netnr);
 
 		pret = snprintf(veth_path, PATH_MAX, "%s/eth%d", directory, netnr);
 		if (pret < 0 || pret >= PATH_MAX || print_to_file(veth_path, eth) < 0)
-			error = true;
+			goto out;
 
+		has_error = false;
 out:
-		free(veth);
-		free(bridge);
-		if (error)
+		if (veth)
+			free(veth);
+		if (bridge);
+			free(bridge);
+		if (has_error)
 			return false;
 	}
 
+	return true;
+}
+
+static bool lxcapi_checkpoint(struct lxc_container *c, char *directory, bool stop, bool verbose)
+{
+	pid_t pid;
+	int status;
+
+	if (!criu_ok(c))
+		return false;
+
+	if (mkdir(directory, 0700) < 0 && errno != EEXIST)
+		return false;
+
+	if (!dump_net_info(c, directory))
+		return false;
+
 	pid = fork();
 	if (pid < 0)
 		return false;
@@ -3807,10 +3808,42 @@ out:
 	}
 }
 
+static bool restore_net_info(struct lxc_container *c, char *directory)
+{
+	struct lxc_list *it;
+	bool has_error = true;
+	int netnr = 0;
+
+	if (container_mem_lock(c))
+		return false;
+
+	lxc_list_for_each(it, &c->lxc_conf->network) {
+		char eth[128], veth[128];
+		struct lxc_netdev *netdev = it->elem;
+
+		if (read_criu_file(directory, "veth", netnr, veth))
+			goto out_unlock;
+
+		if (read_criu_file(directory, "eth", netnr, eth))
+			goto out_unlock;
+
+		netdev->priv.veth_attr.pair = strdup(veth);
+		if (!netdev->priv.veth_attr.pair)
+			goto out_unlock;
+
+		netnr++;
+	}
+
+	has_error = false;
+
+out_unlock:
+	container_mem_unlock(c);
+	return !has_error;
+}
+
 static bool lxcapi_restore(struct lxc_container *c, char *directory, bool verbose)
 {
 	pid_t pid;
-	struct lxc_list *it;
 	struct lxc_rootfs *rootfs;
 	char pidfile[L_tmpnam];
 	struct lxc_handler *handler;
@@ -3896,7 +3929,7 @@ static bool lxcapi_restore(struct lxc_container *c, char *directory, bool verbos
 				goto out_fini_handler;
 			}
 			else {
-				int netnr = 0, ret;
+				int ret;
 				FILE *f = fopen(pidfile, "r");
 				if (!f) {
 					perror("reading pidfile");
@@ -3911,34 +3944,11 @@ static bool lxcapi_restore(struct lxc_container *c, char *directory, bool verbos
 					goto out_fini_handler;
 				}
 
-				if (container_mem_lock(c))
+				if (!restore_net_info(c, directory)) {
+					ERROR("failed restoring network info");
 					goto out_fini_handler;
-
-				lxc_list_for_each(it, &c->lxc_conf->network) {
-					char eth[128], veth[128];
-					struct lxc_netdev *netdev = it->elem;
-
-					if (read_criu_file(directory, "veth", netnr, veth)) {
-						container_mem_unlock(c);
-						goto out_fini_handler;
-					}
-
-					if (read_criu_file(directory, "eth", netnr, eth)) {
-						container_mem_unlock(c);
-						goto out_fini_handler;
-					}
-
-					netdev->priv.veth_attr.pair = strdup(veth);
-					if (!netdev->priv.veth_attr.pair) {
-						container_mem_unlock(c);
-						goto out_fini_handler;
-					}
-
-					netnr++;
 				}
 
-				container_mem_unlock(c);
-
 				if (lxc_set_state(c->name, handler, RUNNING))
 					goto out_fini_handler;
 			}
-- 
1.9.1



More information about the lxc-devel mailing list