[lxc-devel] [lxc/master] Option to force lxc-copy and lxc-snapshot for running domains

Anthony25 on Github lxc-bot at linuxcontainers.org
Sat Nov 5 02:25:42 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 467 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161105/9fbf0f6d/attachment.bin>
-------------- next part --------------
From 102544634d0dc18d96ea5554af48870ed0d88668 Mon Sep 17 00:00:00 2001
From: Anthony Ruhier <anthony.ruhier at 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.ruhier at 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;


More information about the lxc-devel mailing list