]> git.proxmox.com Git - mirror_lxc.git/commitdiff
overlay: simplify and adapt to "overlay"
authorChristian Brauner <christian.brauner@ubuntu.com>
Sat, 15 Jul 2017 19:49:44 +0000 (21:49 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 31 Jul 2017 21:34:13 +0000 (23:34 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/bdev/bdev.c
src/lxc/bdev/lxcoverlay.c
src/lxc/bdev/lxcoverlay.h
src/lxc/bdev/storage_utils.c
src/lxc/conf.c
src/lxc/lxccontainer.c

index ffc9d46a092bd4b26fa796aae4421b5b80285a98..8f1d0145c2ad0ff01c23bdae5eafa7bd1214a5ee 100644 (file)
@@ -194,6 +194,7 @@ static const struct bdev_type bdevs[] = {
        { .name = "rbd",       .ops = &rbd_ops,   },
        { .name = "btrfs",     .ops = &btrfs_ops, },
        { .name = "aufs",      .ops = &aufs_ops,  },
+       { .name = "overlay",   .ops = &ovl_ops,   },
        { .name = "overlayfs", .ops = &ovl_ops,   },
        { .name = "loop",      .ops = &loop_ops,  },
        { .name = "nbd",       .ops = &nbd_ops,   },
@@ -374,10 +375,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
         */
        if (!bdevtype && !keepbdevtype && snap &&
            strcmp(orig->type, "dir") == 0)
-               bdevtype = "overlayfs";
+               bdevtype = "overlay";
 
        if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
-               ERROR("Unsupported snapshot type for unprivileged users");
+               ERROR("Unsupported snapshot type \"%s\" for unprivileged users",
+                     bdevtype ? bdevtype : "(null)");
                bdev_put(orig);
                return NULL;
        }
@@ -385,7 +387,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
        *needs_rdep = 0;
        if (bdevtype && strcmp(orig->type, "dir") == 0 &&
            (strcmp(bdevtype, "aufs") == 0 ||
-            strcmp(bdevtype, "overlayfs") == 0)) {
+            strcmp(bdevtype, "overlayfs") == 0 ||
+            strcmp(bdevtype, "overlay") == 0)) {
                *needs_rdep = 1;
        } else if (snap && strcmp(orig->type, "lvm") == 0 &&
                   !lvm_is_thin_volume(orig->src)) {
@@ -411,8 +414,10 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
                goto err;
        }
 
-       src_no_prefix = lxc_storage_get_path(new->src, new->type);
-
+       if (!strcmp(new->type, "overlay") || !strcmp(new->type, "overlayfs"))
+               src_no_prefix = ovl_get_lower(new->src);
+       else
+               src_no_prefix = lxc_storage_get_path(new->src, new->type);
        if (am_unpriv() && chown_mapped_root(src_no_prefix, c0->lxc_conf) < 0)
                WARN("Failed to update ownership of %s", new->dest);
 
index 50a72e26a6e6f5a0de90bb02d683d9ae06e0e95f..85f4650a2f072103d7e33fcf6010d9a5588c1fa1 100644 (file)
@@ -34,6 +34,7 @@
 #include "lxccontainer.h"
 #include "lxcoverlay.h"
 #include "lxcrsync.h"
+#include "storage_utils.h"
 #include "utils.h"
 
 lxc_log_define(lxcoverlay, lxc);
@@ -41,10 +42,6 @@ lxc_log_define(lxcoverlay, lxc);
 static char *ovl_name;
 static char *ovl_version[] = {"overlay", "overlayfs"};
 
-/* defined in lxccontainer.c: needs to become common helper */
-extern char *dir_new_path(char *src, const char *oldname, const char *name,
-                         const char *oldpath, const char *lxcpath);
-
 static char *ovl_detect_name(void);
 static int ovl_do_rsync(struct bdev *orig, struct bdev *new,
                        struct lxc_conf *conf);
@@ -61,16 +58,18 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
         char *src;
 
        if (!snap) {
-               ERROR("overlayfs is only for snapshot clones");
+               ERROR("overlay is only for snapshot clones");
                return -22;
        }
 
        if (!orig->src || !orig->dest)
                return -1;
 
-       new->dest = dir_new_path(orig->dest, oldname, cname, oldpath, lxcpath);
+       new->dest = lxc_string_join(
+           "/", (const char *[]){lxcpath, cname, "rootfs", NULL}, false);
        if (!new->dest)
                return -1;
+
        if (mkdir_p(new->dest, 0755) < 0)
                return -1;
 
@@ -143,11 +142,11 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
                        free(delta);
                        return -ENOMEM;
                }
-               ret = snprintf(new->src, len, "overlayfs:%s:%s", src, delta);
+               ret = snprintf(new->src, len, "overlay:%s:%s", src, delta);
                free(delta);
                if (ret < 0 || ret >= len)
-                       return -ENOMEM;
-       } else if (strcmp(orig->type, "overlayfs") == 0) {
+                       return -1;
+       } else if (!strcmp(orig->type, "overlayfs") || !strcmp(orig->type, "overlay")) {
                /*
                 * What exactly do we want to do here?  I think we want to use
                 * the original lowerdir, with a private delta which is
@@ -156,26 +155,44 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
                char *osrc, *odelta, *nsrc, *ndelta, *work;
                char *lastslash;
                int len, ret, lastslashidx;
-               if (!(osrc = strdup(orig->src)))
+
+               osrc = strdup(orig->src);
+               if (!osrc) {
+                        SYSERROR("Failed to duplicate \"%s\"", orig->src);
                        return -22;
+                }
+
                nsrc = strchr(osrc, ':') + 1;
-               if (nsrc != osrc + 10 || (odelta = strchr(nsrc, ':')) == NULL) {
+               if ((nsrc != osrc + 8) && (nsrc != osrc + 10)) {
+                       free(osrc);
+                        ERROR("Detected \":\" in \"%s\" at wrong position", osrc);
+                       return -22;
+                }
+
+               odelta = strchr(nsrc, ':');
+               if (!odelta) {
                        free(osrc);
+                        ERROR("Failed to find \":\" in \"%s\"", nsrc);
                        return -22;
                }
+
                *odelta = '\0';
                odelta++;
-               ndelta = dir_new_path(odelta, oldname, cname, oldpath, lxcpath);
-               if (!ndelta) {
+                ndelta = lxc_string_join("/", (const char *[]){lxcpath, cname, "rootfs", NULL}, false);
+                if (!ndelta) {
                        free(osrc);
+                        ERROR("Failed to create new path");
                        return -ENOMEM;
-               }
-               if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
-                       SYSERROR("error: mkdir %s", ndelta);
+                }
+
+               ret = mkdir(ndelta, 0755);
+               if (ret < 0 && errno != EEXIST) {
                        free(osrc);
                        free(ndelta);
+                       SYSERROR("Failed to create \"%s\"", ndelta);
                        return -1;
                }
+
                if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
                        WARN("Failed to update ownership of %s", ndelta);
 
@@ -187,6 +204,7 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
                if (!lastslash) {
                        free(osrc);
                        free(ndelta);
+                       ERROR("Failed to detect \"/\" in \"%s\"", ndelta);
                        return -1;
                }
                lastslash++;
@@ -196,37 +214,43 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
                if (!work) {
                        free(osrc);
                        free(ndelta);
+                       ERROR("Failed to allocate memory");
                        return -1;
                }
                strncpy(work, ndelta, lastslashidx + 1);
                strcpy(work + lastslashidx, "olwork");
-               if ((mkdir(work, 0755) < 0) && errno != EEXIST) {
-                       SYSERROR("error: mkdir %s", work);
+               ret = mkdir(work, 0755);
+               if (ret < 0 && errno != EEXIST) {
                        free(osrc);
                        free(ndelta);
                        free(work);
+                       SYSERROR("Failed to create \"%s\"", ndelta);
                        return -1;
                }
+
                if (am_unpriv() && chown_mapped_root(work, conf) < 0)
                        WARN("Failed to update ownership of %s", work);
                free(work);
 
-               len = strlen(nsrc) + strlen(ndelta) + 12;
+               len = strlen(nsrc) + strlen(ndelta) + 10;
                new->src = malloc(len);
                if (!new->src) {
                        free(osrc);
                        free(ndelta);
+                       ERROR("Failed to allocate memory");
                        return -ENOMEM;
                }
-               ret = snprintf(new->src, len, "overlayfs:%s:%s", nsrc, ndelta);
+               ret = snprintf(new->src, len, "overlay:%s:%s", nsrc, ndelta);
                free(osrc);
                free(ndelta);
-               if (ret < 0 || ret >= len)
-                       return -ENOMEM;
+               if (ret < 0 || ret >= len) {
+                       ERROR("Failed to create string");
+                       return -1;
+                }
 
                return ovl_do_rsync(orig, new, conf);
        } else {
-               ERROR("overlayfs clone of %s container is not yet supported",
+               ERROR("overlay clone of %s container is not yet supported",
                      orig->type);
                /*
                 * Note, supporting this will require ovl_mount supporting
@@ -239,7 +263,7 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
 }
 
 /*
- * to say 'lxc-create -t ubuntu -n o1 -B overlayfs' means you want
+ * to say 'lxc-create -t ubuntu -n o1 -B overlay' means you want
  * $lxcpath/$lxcname/rootfs to have the created container, while all
  * changes after starting the container are written to
  * $lxcpath/$lxcname/delta0
@@ -267,14 +291,14 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n,
                return -1;
        }
 
-       // overlayfs:lower:upper
-       newlen = (2 * len) + strlen("overlayfs:") + 2;
+       // overlay:lower:upper
+       newlen = (2 * len) + strlen("overlay:") + 2;
        bdev->src = malloc(newlen);
        if (!bdev->src) {
                ERROR("Out of memory");
                return -1;
        }
-       ret = snprintf(bdev->src, newlen, "overlayfs:%s:%s", dest, delta);
+       ret = snprintf(bdev->src, newlen, "overlay:%s:%s", dest, delta);
        if (ret < 0 || ret >= newlen)
                return -1;
 
@@ -288,14 +312,23 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n,
 
 int ovl_destroy(struct bdev *orig)
 {
-       char *upper;
+        bool ovl;
+       char *upper = orig->src;
 
-       if (strncmp(orig->src, "overlayfs:", 10) != 0)
+        ovl = !strncmp(upper, "overlay:", 8);
+       if (!ovl && strncmp(upper, "overlayfs:", 10))
                return -22;
-       upper = strchr(orig->src + 10, ':');
+
+        if (ovl)
+                upper += 8;
+        else
+                upper += 10;
+
+       upper = strchr(upper, ':');
        if (!upper)
                return -22;
        upper++;
+
        return lxc_rmdir_onedev(upper, NULL);
 }
 
@@ -310,14 +343,6 @@ int ovl_detect(const char *path)
        return 0;
 }
 
-char *ovl_getlower(char *p)
-{
-       char *p1 = strchr(p, ':');
-       if (p1)
-               *p1 = '\0';
-       return p;
-}
-
 int ovl_mount(struct bdev *bdev)
 {
        char *tmp, *options, *dup, *lower, *upper;
@@ -328,8 +353,9 @@ int ovl_mount(struct bdev *bdev)
        char *mntdata;
        int ret, ret2;
 
-       if (strcmp(bdev->type, "overlayfs"))
+       if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
                return -22;
+
        if (!bdev->src || !bdev->dest)
                return -22;
 
@@ -423,7 +449,7 @@ int ovl_mount(struct bdev *bdev)
        ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
                                    MS_MGC_VAL | mntflags, options_work);
        if (ret < 0) {
-               INFO("Overlayfs: Error mounting %s onto %s with options %s. "
+               INFO("Overlay: Error mounting %s onto %s with options %s. "
                     "Retrying without workdir: %s.",
                     lower, bdev->dest, options_work, strerror(errno));
 
@@ -431,15 +457,15 @@ int ovl_mount(struct bdev *bdev)
                ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
                                          MS_MGC_VAL | mntflags, options);
                if (ret < 0)
-                       SYSERROR("Overlayfs: Error mounting %s onto %s with "
+                       SYSERROR("Overlay: Error mounting %s onto %s with "
                                 "options %s: %s.",
                                 lower, bdev->dest, options,
                                 strerror(errno));
                else
-                       INFO("Overlayfs: Mounted %s onto %s with options %s.",
+                       INFO("Overlay: Mounted %s onto %s with options %s.",
                             lower, bdev->dest, options);
        } else {
-               INFO("Overlayfs: Mounted %s onto %s with options %s.", lower,
+               INFO("Overlay: Mounted %s onto %s with options %s.", lower,
                     bdev->dest, options_work);
        }
        return ret;
@@ -447,13 +473,31 @@ int ovl_mount(struct bdev *bdev)
 
 int ovl_umount(struct bdev *bdev)
 {
-       if (strcmp(bdev->type, "overlayfs"))
+       if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs"))
                return -22;
+
        if (!bdev->src || !bdev->dest)
                return -22;
+
        return umount(bdev->dest);
 }
 
+char *ovl_get_lower(const char *rootfs_path)
+{
+       char *s1;
+       s1 = strstr(rootfs_path, ":/");
+       if (!s1)
+               return NULL;
+       s1++;
+
+       s1 = strstr(s1, ":/");
+       if (!s1)
+               return NULL;
+       s1++;
+
+       return s1;
+}
+
 char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen)
 {
        char *rootfsdir = NULL;
@@ -762,7 +806,7 @@ static int ovl_do_rsync(struct bdev *orig, struct bdev *new, struct lxc_conf *co
        else
                ret = ovl_rsync(&rdata);
        if (ret)
-               ERROR("copying overlayfs delta");
+               ERROR("copying overlay delta");
 
        return ret;
 }
index 8ef277b833389f9bd0dcc3c317d88cf748fc5b5f..fe70d3dbc2530275cce7c599c205dd810ede6695 100644 (file)
@@ -76,7 +76,7 @@ int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path,
  * To be called from functions in lxccontainer.c: Get lower directory for
  * overlay rootfs.
  */
-char *ovl_getlower(char *p);
+char *ovl_get_lower(const char *rootfs_path);
 
 /*
  * Get rootfs path for overlay backed containers. Allocated memory must be freed
index 0cf9710fb760d93c9e3ec37131161ac6305ee793..5e3f1fc3b078a0a4e904dd9c07053dfde6d0fd25 100644 (file)
@@ -415,6 +415,7 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
                // overlayfs -- which is also allowed)
                if (strcmp(b->type, "dir") == 0 ||
                    strcmp(b->type, "aufs") == 0 ||
+                   strcmp(b->type, "overlay") == 0 ||
                    strcmp(b->type, "overlayfs") == 0 ||
                    strcmp(b->type, "btrfs") == 0 ||
                    strcmp(b->type, "loop") == 0)
@@ -427,6 +428,7 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
        // and loop.  In particular, not zfs, btrfs, or lvm.
        if (strcmp(t, "dir") == 0 ||
            strcmp(t, "aufs") == 0 ||
+           strcmp(t, "overlay") == 0 ||
            strcmp(t, "overlayfs") == 0 ||
            strcmp(t, "btrfs") == 0 ||
            strcmp(t, "loop") == 0)
index ab038d36db5fb6b0ee6d403c039b56d2720fbc16..317b4e8d60796454258b2ff032b8d95c65274a85 100644 (file)
@@ -3722,7 +3722,6 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
 {
        uid_t rootuid, rootgid;
        unsigned long val;
-       char *chownpath = path;
        int hostuid, hostgid, ret;
        struct stat sb;
        char map1[100], map2[100], map3[100], map4[100], map5[100];
@@ -3758,23 +3757,6 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
        }
        rootgid = (gid_t)val;
 
-       /*
-        * In case of overlay, we want only the writeable layer to be chowned
-        */
-       if (strncmp(path, "overlayfs:", 10) == 0 || strncmp(path, "aufs:", 5) == 0) {
-               chownpath = strchr(path, ':');
-               if (!chownpath) {
-                       ERROR("Bad overlay path: %s", path);
-                       return -1;
-               }
-               chownpath = strchr(chownpath + 1, ':');
-               if (!chownpath) {
-                       ERROR("Bad overlay path: %s", path);
-                       return -1;
-               }
-               chownpath++;
-       }
-       path = chownpath;
        if (hostuid == 0) {
                if (chown(path, rootuid, rootgid) < 0) {
                        ERROR("Error chowning %s", path);
index 663fe547d99aec6239699b8297ab02fe7ee927a6..4818eb644102bb4ecf97474596b0917b3fa37bdf 100644 (file)
@@ -3254,8 +3254,8 @@ static int clone_update_rootfs_wrapper(void *data)
 sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \
         -p|--lvprefix lvprefix -t|--fstype fstype  -B backingstore
 
--s [ implies overlayfs]
--s -B overlayfs
+-s [ implies overlay]
+-s -B overlay
 -s -B aufs
 
 only rootfs gets converted (copied/snapshotted) on clone.
@@ -3636,7 +3636,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
        if (bdev_is_dir(c->lxc_conf, c->lxc_conf->rootfs.path)) {
                ERROR("Snapshot of directory-backed container requested.");
                ERROR("Making a copy-clone.  If you do want snapshots, then");
-               ERROR("please create an aufs or overlayfs clone first, snapshot that");
+               ERROR("please create an aufs or overlay clone first, snapshot that");
                ERROR("and keep the original container pristine.");
                flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
        }