[lxc-devel] [PATCH] c/r: factor out network dump/restore code
Serge Hallyn
serge.hallyn at ubuntu.com
Mon Oct 13 14:13:28 UTC 2014
Quoting Tycho Andersen (tycho.andersen at canonical.com):
> 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>
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.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
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
More information about the lxc-devel
mailing list