We currently support /etc/lxc/lxc.conf containing a customizable default
lxcpath.  With this patch, /etc/lxc/lxc.conf can also contain

        zfsroot = custom1
        lvm_vg = vg0

Otherwise the defaults are 'lxc' for lvm_vg, and 'lxc' for zfsroot.

Note - I'm stacking these patches up at github.com/hallyn/lxc #s.b.clone2
With these patches, I can

        # create a regular directory-backed container
        lxc-create -t ubuntu -n dir1
        # clone onto an lvm container
        lxc-clone -B lvm dir1 lvm1
        # create a snapshot of the lvm container
        lxc-clone -s lvm1 lvm2
        lxc-destroy -n lvm1 # refused, lvm2 snapshot depends on lvm1
        # Create a zfs backed container
        lxc-clone -B zfs dir1 zfs1
        # Create a snapshot of the zfs container
        lxc-clone -s zfs1 zfs2
        # Create an overlayfs snapshot overlayind dir1
        lxc-clone -s -B overlayfs dir1 o1
        # Create a clone of o1
        lxc-clone -s o1 o2
        # convert overlayfs back into plain dir for easy tar'ing
        lxc-clone -B dir o2 dir3

        # after mounting a btrfs filesystem at /home/serge/lxcbase
        # clone dir1 to a btrfs backed container
        lxc-clone -B btrfs -P /home/serge/lxcbase dir1 btr1
        # create a snapshot of the btrfs container
        lxc-clone -s -p /home/serge/lxcbase btr1 btr2

A single command to tar up a container (config+rootfs) for easy shipping
to another host should, from here, be a short python script using the
clone api.

Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
---
 src/lxc/bdev.c  | 39 +++++++++++++++---------------
 src/lxc/utils.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/utils.h |  2 ++
 3 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index 4ba550c..a3577a2 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -492,34 +492,33 @@ static int zfs_clone(const char *opath, const char 
*npath, const char *oname,
 {
        // use the 'zfs list | grep opath' entry to get the zfsroot
        char output[MAXPATHLEN], option[MAXPATHLEN], *p;
+       const char *zfsroot = output;
        int ret;
        pid_t pid;
 
-       if (!zfs_list_entry(opath, output))
-               // default is tank.  I'd prefer lxc, but apparently this is
-               // tradition.
-               sprintf(output, "tank");
-
-       if ((p = index(output, ' ')) == NULL)
-               return -1;
-       *p = '\0';
-       if ((p = rindex(output, '/')) == NULL)
-               return -1;
-       *p = '\0';
+       if (zfs_list_entry(opath, output)) {
+               // zfsroot is output up to ' '
+               if ((p = index(output, ' ')) == NULL)
+                       return -1;
+               *p = '\0';
+               if ((p = rindex(output, '/')) == NULL)
+                       return -1;
+               *p = '\0';
+       } else
+               zfsroot = default_zfs_root();
 
        ret = snprintf(option, MAXPATHLEN, "-omountpoint=%s/%s/rootfs",
                lxcpath, nname);
        if (ret < 0  || ret >= MAXPATHLEN)
                return -1;
 
-       // zfsroot is output up to ' '
        // zfs create -omountpoint=$lxcpath/$lxcname $zfsroot/$nname
        if (!snapshot) {
                if ((pid = fork()) < 0)
                        return -1;
                if (!pid) {
                        char dev[MAXPATHLEN];
-                       ret = snprintf(dev, MAXPATHLEN, "%s/%s", output, nname);
+                       ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, 
nname);
                        if (ret < 0  || ret >= MAXPATHLEN)
                                exit(1);
                        execlp("zfs", "zfs", "create", option, dev, NULL);
@@ -532,11 +531,11 @@ static int zfs_clone(const char *opath, const char 
*npath, const char *oname,
                // zfs clone zfsroot/oname@nname zfsroot/nname
                char path1[MAXPATHLEN], path2[MAXPATHLEN];
 
-               ret = snprintf(path1, MAXPATHLEN, "%s/%s@%s", output,
+               ret = snprintf(path1, MAXPATHLEN, "%s/%s@%s", zfsroot,
                        oname, nname);
                if (ret < 0 || ret >= MAXPATHLEN)
                        return -1;
-               (void) snprintf(path2, MAXPATHLEN, "%s/%s", output, nname);
+               (void) snprintf(path2, MAXPATHLEN, "%s/%s", zfsroot, nname);
 
                // if the snapshot exists, delete it
                if ((pid = fork()) < 0)
@@ -758,18 +757,18 @@ static int lvm_clonepaths(struct bdev *orig, struct bdev 
*new, const char *oldna
                return -1;
 
        if (strcmp(orig->type, "lvm")) {
+               const char *vg;
+
                if (snap) {
                        ERROR("LVM snapshot from %s backing store is not 
supported",
                                orig->type);
                        return -1;
                }
-               // Use VG 'lxc' by default
-               // We will want to support custom VGs, at least as specified 
through
-               // /etc/lxc/lxc.conf, preferably also over cmdline
-               len = strlen("/dev/lxc/") + strlen(cname) + 1;
+               vg = default_lvm_vg();
+               len = strlen("/dev/") + strlen(vg) + strlen(cname) + 2;
                if ((new->src = malloc(len)) == NULL)
                        return -1;
-               ret = snprintf(new->src, len, "/dev/lxc/%s", cname);
+               ret = snprintf(new->src, len, "/dev/%s/%s", vg, cname);
                if (ret < 0 || ret >= len)
                        return -1;
        } else {
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 2fa2b0c..be1ce88 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -137,7 +137,80 @@ static char *copypath(char *p)
 }
 
 char *default_lxcpath;
+#define DEFAULT_VG "lxc"
+char *default_lvmvg;
+#define DEFAULT_ZFSROOT "lxc"
+char *default_zfsroot;
 
+const char *default_lvm_vg(void)
+{
+       char buf[1024], *p;
+       FILE *fin;
+
+       if (default_lvmvg)
+               return default_lvmvg;
+
+       fin = fopen(LXC_GLOBAL_CONF, "r");
+       if (fin) {
+               while (fgets(buf, 1024, fin)) {
+                       if (buf[0] == '#')
+                               continue;
+                       p = strstr(buf, "lvm_vg");
+                       if (!p)
+                               continue;
+                       p = strchr(p, '=');
+                       if (!p)
+                               continue;
+                       p++;
+                       while (*p && (*p == ' ' || *p == '\t')) p++;
+                       if (!*p)
+                               continue;
+                       default_lvmvg = copypath(p);
+                       goto out;
+               }
+       }
+       default_lvmvg = DEFAULT_VG;
+
+out:
+       if (fin)
+               fclose(fin);
+       return default_lvmvg;
+}
+
+const char *default_zfs_root(void)
+{
+       char buf[1024], *p;
+       FILE *fin;
+
+       if (default_zfsroot)
+               return default_zfsroot;
+
+       fin = fopen(LXC_GLOBAL_CONF, "r");
+       if (fin) {
+               while (fgets(buf, 1024, fin)) {
+                       if (buf[0] == '#')
+                               continue;
+                       p = strstr(buf, "zfsroot");
+                       if (!p)
+                               continue;
+                       p = strchr(p, '=');
+                       if (!p)
+                               continue;
+                       p++;
+                       while (*p && (*p == ' ' || *p == '\t')) p++;
+                       if (!*p)
+                               continue;
+                       default_zfsroot = copypath(p);
+                       goto out;
+               }
+       }
+       default_zfsroot = DEFAULT_ZFSROOT;
+
+out:
+       if (fin)
+               fclose(fin);
+       return default_zfsroot;
+}
 const char *default_lxc_path(void)
 {
        char buf[1024], *p;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 0a27903..75c747f 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -31,6 +31,8 @@ extern int mkdir_p(const char *dir, mode_t mode);
  * path.  Caller must free this buffer.
  */
 extern const char *default_lxc_path(void);
+extern const char *default_zfs_root(void);
+extern const char *default_lvm_vg(void);
 
 /*
  * wait on a child we forked
-- 
1.8.1.2


------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to