The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1277
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Hello, This PR is linked with the issue #1254. It adds a flag to force the clone of a container, even if it is running. The python API has not been touched, though.
From 102544634d0dc18d96ea5554af48870ed0d88668 Mon Sep 17 00:00:00 2001 From: Anthony Ruhier <anthony.ruh...@gmail.com> Date: Sat, 5 Nov 2016 00:58:45 +0100 Subject: [PATCH 1/2] Add option to force lxc-copy Force copy even if the target container is running Linked with issue #1254 --- doc/lxc-copy.sgml.in | 15 ++++++++++++++- src/lxc/lxccontainer.c | 2 +- src/lxc/lxccontainer.h | 4 +++- src/lxc/tools/lxc_copy.c | 11 +++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/lxc-copy.sgml.in b/doc/lxc-copy.sgml.in index 475feb0..116d7b0 100644 --- a/doc/lxc-copy.sgml.in +++ b/doc/lxc-copy.sgml.in @@ -57,6 +57,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA <arg choice="opt">-s, --snapshot</arg> <arg choice="opt">-K, --keepname</arg> <arg choice="opt">-D, --keepdata</arg> + <arg choice="opt">-f, --force</arg> <arg choice="opt">-M, --keepmac</arg> <arg choice="opt">-L, --fssize <replaceable>size [unit]</replaceable></arg> <arg choice="opt">-- hook arguments</arg> @@ -72,6 +73,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA <arg choice="opt">-s, --snapshot</arg> <arg choice="opt">-K, --keepname</arg> <arg choice="opt">-D, --keepdata</arg> + <arg choice="opt">-f, --force</arg> <arg choice="opt">-M, --keepmac</arg> <arg choice="opt">-L, --fssize <replaceable>size [unit]</replaceable></arg> <arg choice="opt">-- hook arguments</arg> @@ -117,7 +119,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA support snapshots. This currently includes aufs, btrfs, lvm (lvm devices do not support snapshots of snapshots.), overlay, and zfs. </para> - + <para> The copy's backing storage will be of the same type as the original container. aufs or overlayfs snapshots of directory backed containers are @@ -209,6 +211,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA </varlistentry> <varlistentry> + <term> <option>-f,--force </option> </term> + <listitem> + <para> Force the copy even if the container is running. Please be + careful with this mode, as it can produce non-persistent data + (typically with non-locked running databases, etc…). Has no effect + during a rename, as it would totally break a running + container.</para> + </listitem> + </varlistentry> + + <varlistentry> <term> <option>-F,--foreground</option> </term> <listitem> <para>Run the snapshot in the foreground. The snapshots console will diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 3a9e1e3..5ea32fb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -3064,7 +3064,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char if (container_mem_lock(c)) return NULL; - if (!is_stopped(c)) { + if (!(flags & LXC_CLONE_FORCE) && !is_stopped(c)) { ERROR("error: Original container (%s) is running", c->name); goto out; } diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 06bec58..fbb40bf 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -39,7 +39,8 @@ extern "C" { #define LXC_CLONE_SNAPSHOT (1 << 2) /*!< Snapshot the original filesystem(s) */ #define LXC_CLONE_KEEPBDEVTYPE (1 << 3) /*!< Use the same bdev type */ #define LXC_CLONE_MAYBE_SNAPSHOT (1 << 4) /*!< Snapshot only if bdev supports it, else copy */ -#define LXC_CLONE_MAXFLAGS (1 << 5) /*!< Number of \c LXC_CLONE_* flags */ +#define LXC_CLONE_FORCE (1 << 5) /*!< Ignore warning if the target domain is running, and force clone */ +#define LXC_CLONE_MAXFLAGS (1 << 6) /*!< Number of \c LXC_CLONE_* flags */ #define LXC_CREATE_QUIET (1 << 0) /*!< Redirect \c stdin to \c /dev/zero and \c stdout and \c stderr to \c /dev/null */ #define LXC_CREATE_MAXFLAGS (1 << 1) /*!< Number of \c LXC_CREATE* flags */ @@ -547,6 +548,7 @@ struct lxc_container { * - \ref LXC_CLONE_KEEPNAME * - \ref LXC_CLONE_KEEPMACADDR * - \ref LXC_CLONE_SNAPSHOT + * - \ref LXC_CLONE_FORCE * \param bdevtype Optionally force the cloned bdevtype to a specified plugin. * By default the original is used (subject to snapshot requirements). * \param bdevdata Information about how to create the new storage diff --git a/src/lxc/tools/lxc_copy.c b/src/lxc/tools/lxc_copy.c index 4d0c17d..49891cb 100644 --- a/src/lxc/tools/lxc_copy.c +++ b/src/lxc/tools/lxc_copy.c @@ -88,6 +88,7 @@ static const struct option my_longopts[] = { { "keepname", no_argument, 0, 'K'}, { "keepmac", no_argument, 0, 'M'}, { "tmpfs", no_argument, 0, 't'}, + { "force", no_argument, 0, 'f'}, LXC_COMMON_OPTIONS }; @@ -102,8 +103,8 @@ static char *const keys[] = { static struct lxc_arguments my_args = { .progname = "lxc-copy", .help = "\n\ ---name=NAME [-P lxcpath] -N newname [-p newpath] [-B backingstorage] [-s] [-K] [-M] [-L size [unit]] -- hook options\n\ ---name=NAME [-P lxcpath] [-N newname] [-p newpath] [-B backingstorage] -e [-d] [-D] [-K] [-M] [-m {bind,aufs,overlay}=/src:/dest] -- hook options\n\ +--name=NAME [-P lxcpath] -N newname [-p newpath] [-B backingstorage] [-f] [-s] [-K] [-M] [-L size [unit]] -- hook options\n\ +--name=NAME [-P lxcpath] [-N newname] [-p newpath] [-B backingstorage] -e [-f] [-d] [-D] [-K] [-M] [-m {bind,aufs,overlay}=/src:/dest] -- hook options\n\ --name=NAME [-P lxcpath] -N newname -R\n\ \n\ lxc-copy clone a container\n\ @@ -114,6 +115,7 @@ Options :\n\ -p, --newpath=NEWPATH NEWPATH for the container to be stored\n\ -R, --rename rename container\n\ -s, --snapshot create snapshot instead of clone\n\ + -f, --force force the copy even if the container is running\n\ -F, --foreground start with current tty attached to /dev/console\n\ -d, --daemon daemonize the container (default)\n\ -e, --ephemeral start ephemeral container\n\ @@ -203,6 +205,8 @@ int main(int argc, char *argv[]) flags |= LXC_CLONE_KEEPNAME; if (my_args.keepmac) flags |= LXC_CLONE_KEEPMACADDR; + if (my_args.force) + flags |= LXC_CLONE_FORCE; if (!my_args.newpath) my_args.newpath = (char *)my_args.lxcpath[0]; @@ -605,6 +609,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) case 's': args->task = SNAP; break; + case 'f': + args->force = 1; + break; case 'F': args->daemonize = 0; break; From daaca4f920eb4fb9f49d8087ddc6e606ab579d90 Mon Sep 17 00:00:00 2001 From: Anthony Ruhier <anthony.ruh...@gmail.com> Date: Sat, 5 Nov 2016 03:18:07 +0100 Subject: [PATCH 2/2] Add option to force lxc-snapshot Force snapshot even if the target container is running Linked with issue #1254 --- doc/lxc-snapshot.sgml.in | 12 ++++++++++++ src/lxc/lxccontainer.c | 8 ++++---- src/lxc/lxccontainer.h | 4 +++- src/lxc/tools/lxc_snapshot.c | 26 ++++++++++++++++++-------- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/doc/lxc-snapshot.sgml.in b/doc/lxc-snapshot.sgml.in index 2986a3b..383bbc9 100644 --- a/doc/lxc-snapshot.sgml.in +++ b/doc/lxc-snapshot.sgml.in @@ -51,6 +51,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA <command>lxc-snapshot</command> <arg choice="req">-n, --name <replaceable>name</replaceable></arg> <arg choice="opt">-c, --comment <replaceable>file</replaceable></arg> + <arg choice="opt">-f, --force</arg> </cmdsynopsis> <cmdsynopsis> <command>lxc-snapshot</command> @@ -127,6 +128,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA </varlistentry> <varlistentry> + <term> <option>-f,--force </option> </term> + <listitem> + <para> Force the snapshot even if the container is running. Please + be careful with this mode, as it can produce non-persistent data + (typically with non-locked running databases, etc…). Has no effect + for a restoration, as it would totally break a running + container.</para> + </listitem> + </varlistentry> + + <varlistentry> <term> <option>-N, --newname</option> </term> <listitem> <para> When restoring a snapshot, the last optional argument if not given explicitly via <command>--newname</command> is the name to use for the restored container. If the newname is identical to the original name of the container, then the original container will be destroyed and the restored container will take its place. Note that deleting the original snapshot is not possible in the case of aufs, overlayfs or zfs backed snapshots.</para> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 5ea32fb..729457a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -3357,9 +3357,9 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath) return true; } -static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) +static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile, int flags) { - int i, flags, ret; + int i, ret; struct lxc_container *c2; char snappath[MAXPATHLEN], newname[20]; @@ -3390,7 +3390,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) * We pass LXC_CLONE_SNAPSHOT to make sure that a rdepends file entry is * created in the original container */ - flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME | + flags |= LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME | LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT; if (bdev_is_dir(c->lxc_conf, c->lxc_conf->rootfs.path)) { ERROR("Snapshot of directory-backed container requested."); @@ -3447,7 +3447,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) return i; } -WRAP_API_1(int, lxcapi_snapshot, const char *) +WRAP_API_2(int, lxcapi_snapshot, const char *, int) static void lxcsnap_free(struct lxc_snapshot *s) { diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index fbb40bf..d58f9e3 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -663,12 +663,14 @@ struct lxc_container { * \param c Container. * \param commentfile Full path to file containing a description * of the snapshot. + * \param flags Additional \c LXC_CLONE* flags to change the cloning behaviour: + * - \ref LXC_CLONE_FORCE * * \return -1 on error, or zero-based snapshot number. * * \note \p commentfile may be \c NULL but this is discouraged. */ - int (*snapshot)(struct lxc_container *c, const char *commentfile); + int (*snapshot)(struct lxc_container *c, const char *commentfile, int flags); /*! * \brief Obtain a list of container snapshots. diff --git a/src/lxc/tools/lxc_snapshot.c b/src/lxc/tools/lxc_snapshot.c index 1a79a7a..4f79864 100644 --- a/src/lxc/tools/lxc_snapshot.c +++ b/src/lxc/tools/lxc_snapshot.c @@ -44,13 +44,14 @@ static const struct option my_longopts[] = { {"destroy", required_argument, 0, 'd'}, {"comment", required_argument, 0, 'c'}, {"showcomments", no_argument, 0, 'C'}, + { "force", no_argument, 0, 'f'}, LXC_COMMON_OPTIONS }; static struct lxc_arguments my_args = { .progname = "lxc-snapshot", .help = "\ ---name=NAME [-P lxcpath] [-L [-C]] [-c commentfile] [-r snapname [-N newname]]\n\ +--name=NAME [-P lxcpath] [-L [-C]] [-c commentfile] [-f] [-r snapname [-N newname]]\n\ \n\ lxc-snapshot snapshots a container\n\ \n\ @@ -61,6 +62,7 @@ Options :\n\ -N, --newname=NEWNAME NEWNAME for the restored container\n\ -d, --destroy=NAME destroy snapshot NAME, e.g. 'snap0'\n\ use ALL to destroy all snapshots\n\ + -f, --force force the snapshot even if the container is running\n\ -c, --comment=FILE add FILE as a comment\n\ -C, --showcomments show snapshot comments\n\ --rcfile=FILE Load configuration file FILE\n", @@ -70,17 +72,19 @@ Options :\n\ .task = SNAP, }; -static int do_snapshot(struct lxc_container *c, char *commentfile); +static int do_snapshot(struct lxc_container *c, char *commentfile, int flags); static int do_snapshot_destroy(struct lxc_container *c, char *snapname); static int do_snapshot_list(struct lxc_container *c, int print_comments); static int do_snapshot_restore(struct lxc_container *c, struct lxc_arguments *args); -static int do_snapshot_task(struct lxc_container *c, enum task task); +static int do_snapshot_task(struct lxc_container *c, enum task task, + int flags); static void print_file(char *path); int main(int argc, char *argv[]) { struct lxc_container *c; + int flags = 0; int ret; if (lxc_arguments_parse(&my_args, argc, argv)) @@ -102,6 +106,9 @@ int main(int argc, char *argv[]) } } + if (my_args.force) + flags |= LXC_CLONE_FORCE; + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { fprintf(stderr, "System error loading container\n"); @@ -130,7 +137,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - ret = do_snapshot_task(c, my_args.task); + ret = do_snapshot_task(c, my_args.task, flags); lxc_container_put(c); @@ -139,7 +146,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } -static int do_snapshot_task(struct lxc_container *c, enum task task) +static int do_snapshot_task(struct lxc_container *c, enum task task, int flags) { int ret = 0; @@ -154,7 +161,7 @@ static int do_snapshot_task(struct lxc_container *c, enum task task) ret = do_snapshot_restore(c, &my_args); break; case SNAP: - ret = do_snapshot(c, my_args.commentfile); + ret = do_snapshot(c, my_args.commentfile, flags); break; default: ret = 0; @@ -181,6 +188,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) args->task = DESTROY; args->snapname = arg; break; + case 'f': + args->force = 1; + break; case 'c': args->commentfile = arg; break; @@ -192,11 +202,11 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) return 0; } -static int do_snapshot(struct lxc_container *c, char *commentfile) +static int do_snapshot(struct lxc_container *c, char *commentfile, int flags) { int ret; - ret = c->snapshot(c, commentfile); + ret = c->snapshot(c, commentfile, flags); if (ret < 0) { ERROR("Error creating a snapshot"); return -1;
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel