]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Split bdev into modules: lxcaufs
authorChristian Brauner <christian.brauner@mailbox.org>
Wed, 30 Dec 2015 13:38:44 +0000 (14:38 +0100)
committerChristian Brauner <christian.brauner@mailbox.org>
Tue, 12 Jan 2016 07:50:45 +0000 (08:50 +0100)
The functions

- aufs_clonepaths();
- aufs_create();
- aufs_destroy();
- aufs_detect();
- aufs_mount();
- aufs_umount();

move from bdev.c to lxcaufs.{c,h}. All functions which previously were static
become extern.

Adapt Makefile.am to include lxcaufs.{c,h}.

The structs

       - struct bdev; /* defined in bdev.h */
       - struct bdev_specs; /* defined in lxccontainer.h */
       - struct lxc_conf; /* defined conf.h */

are forward declared/put as incomplete types into lxcaufs.h as the functions
associated with aufs need access to it.

Signed-off-by: Christian Brauner <christian.brauner@mailbox.org>
src/lxc/Makefile.am
src/lxc/bdev/bdev.c
src/lxc/bdev/lxcaufs.c [new file with mode: 0644]
src/lxc/bdev/lxcaufs.h [new file with mode: 0644]

index 65a770d6de9aad4c160c1a98ceaed6fc311716bc..df5a51e17d1f2fb6849cafb50ec1ed638a960a7f 100644 (file)
@@ -7,6 +7,7 @@ noinst_HEADERS = \
        arguments.h \
        attach.h \
        bdev/bdev.h \
+       bdev/lxcaufs.h \
        bdev/lxcbtrfs.h \
        bdev/lxclvm.h \
        bdev/lxcoverlay.h \
@@ -65,6 +66,7 @@ endif
 liblxc_so_SOURCES = \
        arguments.c arguments.h \
        bdev/bdev.c bdev/bdev.h \
+       bdev/lxcaufs.c bdev/lxcaufs.h \
        bdev/lxcbtrfs.c bdev/lxcbtrfs.h \
        bdev/lxclvm.c bdev/lxclvm.h \
        bdev/lxcoverlay.c bdev/lxcoverlay.h \
index 343dcda87213786f96814ee28c79e19178b43b4b..af5b972a424ec9ec7d611f2e1b7f84b3f25a7453 100644 (file)
@@ -53,6 +53,7 @@
 #include "error.h"
 #include "log.h"
 #include "lxc.h"
+#include "lxcaufs.h"
 #include "lxcbtrfs.h"
 #include "lxclock.h"
 #include "lxclvm.h"
 
 lxc_log_define(bdev, lxc);
 
+/* aufs */
+static const struct bdev_ops aufs_ops = {
+       .detect = &aufs_detect,
+       .mount = &aufs_mount,
+       .umount = &aufs_umount,
+       .clone_paths = &aufs_clonepaths,
+       .destroy = &aufs_destroy,
+       .create = &aufs_create,
+       .can_snapshot = true,
+       .can_backup = true,
+};
+
 /* btrfs */
 static const struct bdev_ops btrfs_ops = {
        .detect = &btrfs_detect,
@@ -125,18 +138,6 @@ static const struct bdev_ops zfs_ops = {
        .can_backup = true,
 };
 
-/* functions associated with an aufs bdev struct */
-static int aufs_clonepaths(struct bdev *orig, struct bdev *new,
-               const char *oldname, const char *cname,
-               const char *oldpath, const char *lxcpath, int snap,
-               uint64_t newsize, struct lxc_conf *conf);
-static int aufs_create(struct bdev *bdev, const char *dest, const char *n,
-               struct bdev_specs *specs);
-static int aufs_destroy(struct bdev *orig);
-static int aufs_detect(const char *path);
-static int aufs_mount(struct bdev *bdev);
-static int aufs_umount(struct bdev *bdev);
-
 /* functions associated with a dir bdev struct */
 static int dir_clonepaths(struct bdev *orig, struct bdev *new,
                const char *oldname, const char *cname,
@@ -209,7 +210,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
 
 /* the bulk of this needs to become a common helper */
 char *dir_new_path(char *src, const char *oldname, const char *name,
-                  const char *oldpath, const char *lxcpath)
+               const char *oldpath, const char *lxcpath)
 {
        char *ret, *p, *p2;
        int l1, l2, nlen;
@@ -1083,293 +1084,6 @@ static const struct bdev_ops loop_ops = {
        .can_backup = true,
 };
 
-//
-// aufs ops
-//
-
-static int aufs_detect(const char *path)
-{
-       if (strncmp(path, "aufs:", 5) == 0)
-               return 1; // take their word for it
-       return 0;
-}
-
-//
-// XXXXXXX plain directory bind mount ops
-//
-static int aufs_mount(struct bdev *bdev)
-{
-       char *options, *dup, *lower, *upper;
-       int len;
-       unsigned long mntflags;
-       char *mntdata;
-       int ret;
-       const char *xinopath = "/dev/shm/aufs.xino";
-
-       if (strcmp(bdev->type, "aufs"))
-               return -22;
-       if (!bdev->src || !bdev->dest)
-               return -22;
-
-       //  separately mount it first
-       //  mount -t aufs -obr=${upper}=rw:${lower}=ro lower dest
-       dup = alloca(strlen(bdev->src)+1);
-       strcpy(dup, bdev->src);
-       if (!(lower = strchr(dup, ':')))
-               return -22;
-       if (!(upper = strchr(++lower, ':')))
-               return -22;
-       *upper = '\0';
-       upper++;
-
-       if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
-               free(mntdata);
-               return -22;
-       }
-
-       // TODO We should check whether bdev->src is a blockdev, and if so
-       // but for now, only support aufs of a basic directory
-
-       // AUFS does not work on top of certain filesystems like (XFS or Btrfs)
-       // so add xino=/dev/shm/aufs.xino parameter to mount options.
-       // The same xino option can be specified to multiple aufs mounts, and
-       // a xino file is not shared among multiple aufs mounts.
-       //
-       // see http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg02587.html
-       //     http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg05126.html
-       if (mntdata) {
-               len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,,xino=") + strlen(mntdata) + 1;
-               options = alloca(len);
-               ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s", upper, lower, mntdata, xinopath);
-       }
-       else {
-               len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,xino=") + 1;
-               options = alloca(len);
-               ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s", upper, lower, xinopath);
-       }
-
-       if (ret < 0 || ret >= len) {
-               free(mntdata);
-               return -1;
-       }
-
-       ret = mount(lower, bdev->dest, "aufs", MS_MGC_VAL | mntflags, options);
-       if (ret < 0)
-               SYSERROR("aufs: error mounting %s onto %s options %s",
-                       lower, bdev->dest, options);
-       else
-               INFO("aufs: mounted %s onto %s options %s",
-                       lower, bdev->dest, options);
-       return ret;
-}
-
-static int aufs_umount(struct bdev *bdev)
-{
-       if (strcmp(bdev->type, "aufs"))
-               return -22;
-       if (!bdev->src || !bdev->dest)
-               return -22;
-       return umount(bdev->dest);
-}
-
-static int aufs_clonepaths(struct bdev *orig, struct bdev *new,
-               const char *oldname, const char *cname,
-               const char *oldpath, const char *lxcpath, int snap,
-               uint64_t newsize, struct lxc_conf *conf)
-{
-       if (!snap) {
-               ERROR("aufs 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);
-       if (!new->dest)
-               return -1;
-       if (mkdir_p(new->dest, 0755) < 0)
-               return -1;
-
-       if (am_unpriv() && chown_mapped_root(new->dest, conf) < 0)
-               WARN("Failed to update ownership of %s", new->dest);
-
-       if (strcmp(orig->type, "dir") == 0) {
-               char *delta, *lastslash;
-               int ret, len, lastslashidx;
-
-               // if we have /var/lib/lxc/c2/rootfs, then delta will be
-               //            /var/lib/lxc/c2/delta0
-               lastslash = strrchr(new->dest, '/');
-               if (!lastslash)
-                       return -22;
-               if (strlen(lastslash) < 7)
-                       return -22;
-               lastslash++;
-               lastslashidx = lastslash - new->dest;
-
-               delta = malloc(lastslashidx + 7);
-               if (!delta)
-                       return -1;
-               strncpy(delta, new->dest, lastslashidx+1);
-               strcpy(delta+lastslashidx, "delta0");
-               if ((ret = mkdir(delta, 0755)) < 0) {
-                       SYSERROR("error: mkdir %s", delta);
-                       free(delta);
-                       return -1;
-               }
-               if (am_unpriv() && chown_mapped_root(delta, conf) < 0)
-                       WARN("Failed to update ownership of %s", delta);
-
-               // the src will be 'aufs:lowerdir:upperdir'
-               len = strlen(delta) + strlen(orig->src) + 12;
-               new->src = malloc(len);
-               if (!new->src) {
-                       free(delta);
-                       return -ENOMEM;
-               }
-               ret = snprintf(new->src, len, "aufs:%s:%s", orig->src, delta);
-               free(delta);
-               if (ret < 0 || ret >= len)
-                       return -ENOMEM;
-       } else if (strcmp(orig->type, "aufs") == 0) {
-               // What exactly do we want to do here?
-               // I think we want to use the original lowerdir, with a
-               // private delta which is originally rsynced from the
-               // original delta
-               char *osrc, *odelta, *nsrc, *ndelta;
-               int len, ret;
-               if (!(osrc = strdup(orig->src)))
-                       return -22;
-               nsrc = strchr(osrc, ':') + 1;
-               if (nsrc != osrc + 5 || (odelta = strchr(nsrc, ':')) == NULL) {
-                       free(osrc);
-                       return -22;
-               }
-               *odelta = '\0';
-               odelta++;
-               ndelta = dir_new_path(odelta, oldname, cname, oldpath, lxcpath);
-               if (!ndelta) {
-                       free(osrc);
-                       return -ENOMEM;
-               }
-               if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
-                       SYSERROR("error: mkdir %s", ndelta);
-                       free(osrc);
-                       free(ndelta);
-                       return -1;
-               }
-               if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
-                       WARN("Failed to update ownership of %s", ndelta);
-
-               struct rsync_data_char rdata;
-               rdata.src = odelta;
-               rdata.dest = ndelta;
-               if (am_unpriv())
-                       ret = userns_exec_1(conf, rsync_delta_wrapper, &rdata);
-               else
-                       ret = rsync_delta(&rdata);
-               if (ret) {
-                       free(osrc);
-                       free(ndelta);
-                       ERROR("copying aufs delta");
-                       return -1;
-               }
-               len = strlen(nsrc) + strlen(ndelta) + 12;
-               new->src = malloc(len);
-               if (!new->src) {
-                       free(osrc);
-                       free(ndelta);
-                       return -ENOMEM;
-               }
-               ret = snprintf(new->src, len, "aufs:%s:%s", nsrc, ndelta);
-               free(osrc);
-               free(ndelta);
-               if (ret < 0 || ret >= len)
-                       return -ENOMEM;
-       } else {
-               ERROR("aufs clone of %s container is not yet supported",
-                       orig->type);
-               // Note, supporting this will require aufs_mount supporting
-               // mounting of the underlay.  No big deal, just needs to be done.
-               return -1;
-       }
-
-       return 0;
-}
-
-static int aufs_destroy(struct bdev *orig)
-{
-       char *upper;
-
-       if (strncmp(orig->src, "aufs:", 5) != 0)
-               return -22;
-       upper = strchr(orig->src + 5, ':');
-       if (!upper)
-               return -22;
-       upper++;
-       return lxc_rmdir_onedev(upper, NULL);
-}
-
-/*
- * to say 'lxc-create -t ubuntu -n o1 -B aufs' means you want
- * $lxcpath/$lxcname/rootfs to have the created container, while all
- * changes after starting the container are written to
- * $lxcpath/$lxcname/delta0
- */
-static int aufs_create(struct bdev *bdev, const char *dest, const char *n,
-               struct bdev_specs *specs)
-{
-       char *delta;
-       int ret, len = strlen(dest), newlen;
-
-       if (len < 8 || strcmp(dest+len-7, "/rootfs") != 0)
-               return -1;
-
-       if (!(bdev->dest = strdup(dest))) {
-               ERROR("Out of memory");
-               return -1;
-       }
-
-       delta = alloca(strlen(dest)+1);
-       strcpy(delta, dest);
-       strcpy(delta+len-6, "delta0");
-
-       if (mkdir_p(delta, 0755) < 0) {
-               ERROR("Error creating %s", delta);
-               return -1;
-       }
-
-       /* aufs:lower:upper */
-       newlen = (2 * len) + strlen("aufs:") + 2;
-       bdev->src = malloc(newlen);
-       if (!bdev->src) {
-               ERROR("Out of memory");
-               return -1;
-       }
-       ret = snprintf(bdev->src, newlen, "aufs:%s:%s", dest, delta);
-       if (ret < 0 || ret >= newlen)
-               return -1;
-
-       if (mkdir_p(bdev->dest, 0755) < 0) {
-               ERROR("Error creating %s", bdev->dest);
-               return -1;
-       }
-
-       return 0;
-}
-
-static const struct bdev_ops aufs_ops = {
-       .detect = &aufs_detect,
-       .mount = &aufs_mount,
-       .umount = &aufs_umount,
-       .clone_paths = &aufs_clonepaths,
-       .destroy = &aufs_destroy,
-       .create = &aufs_create,
-       .can_snapshot = true,
-       .can_backup = true,
-};
-
 //
 // nbd dev ops
 //
diff --git a/src/lxc/bdev/lxcaufs.c b/src/lxc/bdev/lxcaufs.c
new file mode 100644 (file)
index 0000000..a5c34aa
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "bdev.h"
+#include "log.h"
+#include "lxcrsync.h"
+#include "utils.h"
+
+lxc_log_define(lxcaufs, lxc);
+
+/* the bulk of this needs to become a common helper */
+extern char *dir_new_path(char *src, const char *oldname, const char *name,
+               const char *oldpath, const char *lxcpath);
+
+int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
+               const char *cname, const char *oldpath, const char *lxcpath,
+               int snap, uint64_t newsize, struct lxc_conf *conf)
+{
+       if (!snap) {
+               ERROR("aufs 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);
+       if (!new->dest)
+               return -1;
+       if (mkdir_p(new->dest, 0755) < 0)
+               return -1;
+
+       if (am_unpriv() && chown_mapped_root(new->dest, conf) < 0)
+               WARN("Failed to update ownership of %s", new->dest);
+
+       if (strcmp(orig->type, "dir") == 0) {
+               char *delta, *lastslash;
+               int ret, len, lastslashidx;
+
+               // if we have /var/lib/lxc/c2/rootfs, then delta will be
+               //            /var/lib/lxc/c2/delta0
+               lastslash = strrchr(new->dest, '/');
+               if (!lastslash)
+                       return -22;
+               if (strlen(lastslash) < 7)
+                       return -22;
+               lastslash++;
+               lastslashidx = lastslash - new->dest;
+
+               delta = malloc(lastslashidx + 7);
+               if (!delta)
+                       return -1;
+               strncpy(delta, new->dest, lastslashidx+1);
+               strcpy(delta+lastslashidx, "delta0");
+               if ((ret = mkdir(delta, 0755)) < 0) {
+                       SYSERROR("error: mkdir %s", delta);
+                       free(delta);
+                       return -1;
+               }
+               if (am_unpriv() && chown_mapped_root(delta, conf) < 0)
+                       WARN("Failed to update ownership of %s", delta);
+
+               // the src will be 'aufs:lowerdir:upperdir'
+               len = strlen(delta) + strlen(orig->src) + 12;
+               new->src = malloc(len);
+               if (!new->src) {
+                       free(delta);
+                       return -ENOMEM;
+               }
+               ret = snprintf(new->src, len, "aufs:%s:%s", orig->src, delta);
+               free(delta);
+               if (ret < 0 || ret >= len)
+                       return -ENOMEM;
+       } else if (strcmp(orig->type, "aufs") == 0) {
+               // What exactly do we want to do here?
+               // I think we want to use the original lowerdir, with a
+               // private delta which is originally rsynced from the
+               // original delta
+               char *osrc, *odelta, *nsrc, *ndelta;
+               int len, ret;
+               if (!(osrc = strdup(orig->src)))
+                       return -22;
+               nsrc = strchr(osrc, ':') + 1;
+               if (nsrc != osrc + 5 || (odelta = strchr(nsrc, ':')) == NULL) {
+                       free(osrc);
+                       return -22;
+               }
+               *odelta = '\0';
+               odelta++;
+               ndelta = dir_new_path(odelta, oldname, cname, oldpath, lxcpath);
+               if (!ndelta) {
+                       free(osrc);
+                       return -ENOMEM;
+               }
+               if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
+                       SYSERROR("error: mkdir %s", ndelta);
+                       free(osrc);
+                       free(ndelta);
+                       return -1;
+               }
+               if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
+                       WARN("Failed to update ownership of %s", ndelta);
+
+               struct rsync_data_char rdata;
+               rdata.src = odelta;
+               rdata.dest = ndelta;
+               if (am_unpriv())
+                       ret = userns_exec_1(conf, rsync_delta_wrapper, &rdata);
+               else
+                       ret = rsync_delta(&rdata);
+               if (ret) {
+                       free(osrc);
+                       free(ndelta);
+                       ERROR("copying aufs delta");
+                       return -1;
+               }
+               len = strlen(nsrc) + strlen(ndelta) + 12;
+               new->src = malloc(len);
+               if (!new->src) {
+                       free(osrc);
+                       free(ndelta);
+                       return -ENOMEM;
+               }
+               ret = snprintf(new->src, len, "aufs:%s:%s", nsrc, ndelta);
+               free(osrc);
+               free(ndelta);
+               if (ret < 0 || ret >= len)
+                       return -ENOMEM;
+       } else {
+               ERROR("aufs clone of %s container is not yet supported",
+                       orig->type);
+               // Note, supporting this will require aufs_mount supporting
+               // mounting of the underlay.  No big deal, just needs to be done.
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * to say 'lxc-create -t ubuntu -n o1 -B aufs' means you want
+ * $lxcpath/$lxcname/rootfs to have the created container, while all
+ * changes after starting the container are written to
+ * $lxcpath/$lxcname/delta0
+ */
+int aufs_create(struct bdev *bdev, const char *dest, const char *n,
+               struct bdev_specs *specs)
+{
+       char *delta;
+       int ret, len = strlen(dest), newlen;
+
+       if (len < 8 || strcmp(dest+len-7, "/rootfs") != 0)
+               return -1;
+
+       if (!(bdev->dest = strdup(dest))) {
+               ERROR("Out of memory");
+               return -1;
+       }
+
+       delta = alloca(strlen(dest)+1);
+       strcpy(delta, dest);
+       strcpy(delta+len-6, "delta0");
+
+       if (mkdir_p(delta, 0755) < 0) {
+               ERROR("Error creating %s", delta);
+               return -1;
+       }
+
+       /* aufs:lower:upper */
+       newlen = (2 * len) + strlen("aufs:") + 2;
+       bdev->src = malloc(newlen);
+       if (!bdev->src) {
+               ERROR("Out of memory");
+               return -1;
+       }
+       ret = snprintf(bdev->src, newlen, "aufs:%s:%s", dest, delta);
+       if (ret < 0 || ret >= newlen)
+               return -1;
+
+       if (mkdir_p(bdev->dest, 0755) < 0) {
+               ERROR("Error creating %s", bdev->dest);
+               return -1;
+       }
+
+       return 0;
+}
+
+int aufs_destroy(struct bdev *orig)
+{
+       char *upper;
+
+       if (strncmp(orig->src, "aufs:", 5) != 0)
+               return -22;
+       upper = strchr(orig->src + 5, ':');
+       if (!upper)
+               return -22;
+       upper++;
+       return lxc_rmdir_onedev(upper, NULL);
+}
+
+int aufs_detect(const char *path)
+{
+       if (strncmp(path, "aufs:", 5) == 0)
+               return 1; // take their word for it
+       return 0;
+}
+
+int aufs_mount(struct bdev *bdev)
+{
+       char *options, *dup, *lower, *upper;
+       int len;
+       unsigned long mntflags;
+       char *mntdata;
+       int ret;
+       const char *xinopath = "/dev/shm/aufs.xino";
+
+       if (strcmp(bdev->type, "aufs"))
+               return -22;
+       if (!bdev->src || !bdev->dest)
+               return -22;
+
+       //  separately mount it first
+       //  mount -t aufs -obr=${upper}=rw:${lower}=ro lower dest
+       dup = alloca(strlen(bdev->src)+1);
+       strcpy(dup, bdev->src);
+       if (!(lower = strchr(dup, ':')))
+               return -22;
+       if (!(upper = strchr(++lower, ':')))
+               return -22;
+       *upper = '\0';
+       upper++;
+
+       if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+               free(mntdata);
+               return -22;
+       }
+
+       // TODO We should check whether bdev->src is a blockdev, and if so
+       // but for now, only support aufs of a basic directory
+
+       // AUFS does not work on top of certain filesystems like (XFS or Btrfs)
+       // so add xino=/dev/shm/aufs.xino parameter to mount options.
+       // The same xino option can be specified to multiple aufs mounts, and
+       // a xino file is not shared among multiple aufs mounts.
+       //
+       // see http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg02587.html
+       //     http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg05126.html
+       if (mntdata) {
+               len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,,xino=") + strlen(mntdata) + 1;
+               options = alloca(len);
+               ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s", upper, lower, mntdata, xinopath);
+       }
+       else {
+               len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,xino=") + 1;
+               options = alloca(len);
+               ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s", upper, lower, xinopath);
+       }
+
+       if (ret < 0 || ret >= len) {
+               free(mntdata);
+               return -1;
+       }
+
+       ret = mount(lower, bdev->dest, "aufs", MS_MGC_VAL | mntflags, options);
+       if (ret < 0)
+               SYSERROR("aufs: error mounting %s onto %s options %s",
+                       lower, bdev->dest, options);
+       else
+               INFO("aufs: mounted %s onto %s options %s",
+                       lower, bdev->dest, options);
+       return ret;
+}
+
+int aufs_umount(struct bdev *bdev)
+{
+       if (strcmp(bdev->type, "aufs"))
+               return -22;
+       if (!bdev->src || !bdev->dest)
+               return -22;
+       return umount(bdev->dest);
+}
diff --git a/src/lxc/bdev/lxcaufs.h b/src/lxc/bdev/lxcaufs.h
new file mode 100644 (file)
index 0000000..e259ee2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LXC_AUFS_H
+#define __LXC_AUFS_H
+
+#define _GNU_SOURCE
+#include <stdint.h>
+
+/* defined in bdev.h */
+struct bdev;
+
+/* defined in lxccontainer.h */
+struct bdev_specs;
+
+/* defined conf.h */
+struct lxc_conf;
+
+/*
+ * Functions associated with an aufs bdev struct.
+ */
+int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
+               const char *cname, const char *oldpath, const char *lxcpath,
+               int snap, uint64_t newsize, struct lxc_conf *conf);
+int aufs_create(struct bdev *bdev, const char *dest, const char *n,
+               struct bdev_specs *specs);
+int aufs_destroy(struct bdev *orig);
+int aufs_detect(const char *path);
+int aufs_mount(struct bdev *bdev);
+int aufs_umount(struct bdev *bdev);
+
+#endif /* __LXC_AUFS_H */