From: Tycho Andersen Date: Fri, 10 Oct 2014 14:55:37 +0000 (+0000) Subject: c/r: factor out network dump/restore code X-Git-Tag: lxc-1.1.0.alpha3~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bbd4e13ea5c23480968bad1934a44db50d674d76;p=thirdparty%2Flxc.git c/r: factor out network dump/restore code 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 Signed-off-by: Serge Hallyn --- diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 1f1f9ea90..c4cb0ab3c 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -3746,30 +3746,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) { @@ -3781,49 +3772,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; @@ -3855,10 +3856,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; @@ -3944,7 +3977,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"); @@ -3959,34 +3992,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; }