[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