diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index df5a51e17..d74385127 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -9,6 +9,7 @@ noinst_HEADERS = \ bdev/bdev.h \ bdev/lxcaufs.h \ bdev/lxcbtrfs.h \ + bdev/lxcdir.h \ bdev/lxclvm.h \ bdev/lxcoverlay.h \ bdev/lxcrsync.h \ @@ -68,6 +69,7 @@ liblxc_so_SOURCES = \ bdev/bdev.c bdev/bdev.h \ bdev/lxcaufs.c bdev/lxcaufs.h \ bdev/lxcbtrfs.c bdev/lxcbtrfs.h \ + bdev/lxcdir.c bdev/lxcdir.h \ bdev/lxclvm.c bdev/lxclvm.h \ bdev/lxcoverlay.c bdev/lxcoverlay.h \ bdev/lxcrsync.c bdev/lxcrsync.h \ diff --git a/src/lxc/bdev/bdev.c b/src/lxc/bdev/bdev.c index af5b972a4..323241a50 100644 --- a/src/lxc/bdev/bdev.c +++ b/src/lxc/bdev/bdev.c @@ -55,6 +55,7 @@ #include "lxc.h" #include "lxcaufs.h" #include "lxcbtrfs.h" +#include "lxcdir.h" #include "lxclock.h" #include "lxclvm.h" #include "lxcoverlay.h" @@ -102,6 +103,17 @@ static const struct bdev_ops btrfs_ops = { .can_backup = true, }; +static const struct bdev_ops dir_ops = { + .detect = &dir_detect, + .mount = &dir_mount, + .umount = &dir_umount, + .clone_paths = &dir_clonepaths, + .destroy = &dir_destroy, + .create = &dir_create, + .can_snapshot = false, + .can_backup = true, +}; + /* lvm */ static const struct bdev_ops lvm_ops = { .detect = &lvm_detect, @@ -138,18 +150,6 @@ static const struct bdev_ops zfs_ops = { .can_backup = true, }; -/* functions associated with a dir bdev struct */ -static int dir_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 dir_create(struct bdev *bdev, const char *dest, const char *n, - struct bdev_specs *specs); -static int dir_destroy(struct bdev *orig); -static int dir_detect(const char *path); -static int dir_mount(struct bdev *bdev); -static int dir_umount(struct bdev *bdev); - /* functions associated with a loop bdev struct */ static int do_loop_create(const char *path, uint64_t size, const char *fstype); static int loop_create(struct bdev *bdev, const char *dest, const char *n, @@ -504,123 +504,6 @@ struct bdev_type { const struct bdev_ops *ops; }; -static int dir_detect(const char *path) -{ - if (strncmp(path, "dir:", 4) == 0) - return 1; // take their word for it - if (is_dir(path)) - return 1; - return 0; -} - -// -// XXXXXXX plain directory bind mount ops -// -static int dir_mount(struct bdev *bdev) -{ - unsigned long mntflags; - char *mntdata; - int ret; - - if (strcmp(bdev->type, "dir")) - return -22; - if (!bdev->src || !bdev->dest) - return -22; - - if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) { - free(mntdata); - return -22; - } - - ret = mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags, mntdata); - free(mntdata); - return ret; -} - -static int dir_umount(struct bdev *bdev) -{ - if (strcmp(bdev->type, "dir")) - return -22; - if (!bdev->src || !bdev->dest) - return -22; - return umount(bdev->dest); -} - -/* - * for a simple directory bind mount, we substitute the old container - * name and paths for the new - */ -static int dir_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 len, ret; - - if (snap) { - ERROR("directories cannot be snapshotted. Try aufs or overlayfs."); - return -1; - } - - if (!orig->dest || !orig->src) - return -1; - - len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; - new->src = malloc(len); - if (!new->src) - return -1; - ret = snprintf(new->src, len, "%s/%s/rootfs", lxcpath, cname); - if (ret < 0 || ret >= len) - return -1; - if ((new->dest = strdup(new->src)) == NULL) - return -1; - - return 0; -} - -static int dir_destroy(struct bdev *orig) -{ - if (lxc_rmdir_onedev(orig->src, NULL) < 0) - return -1; - return 0; -} - -static int dir_create(struct bdev *bdev, const char *dest, const char *n, - struct bdev_specs *specs) -{ - if (specs && specs->dir) - bdev->src = strdup(specs->dir); - else - bdev->src = strdup(dest); - bdev->dest = strdup(dest); - if (!bdev->src || !bdev->dest) { - ERROR("Out of memory"); - return -1; - } - - if (mkdir_p(bdev->src, 0755) < 0) { - ERROR("Error creating %s", bdev->src); - return -1; - } - if (mkdir_p(bdev->dest, 0755) < 0) { - ERROR("Error creating %s", bdev->dest); - return -1; - } - - return 0; -} - -static const struct bdev_ops dir_ops = { - .detect = &dir_detect, - .mount = &dir_mount, - .umount = &dir_umount, - .clone_paths = &dir_clonepaths, - .destroy = &dir_destroy, - .create = &dir_create, - .can_snapshot = false, - .can_backup = true, -}; - // this will return 1 for physical disks, qemu-nbd, loop, etc // right now only lvm is a block device int is_blktype(struct bdev *b) diff --git a/src/lxc/bdev/lxcdir.c b/src/lxc/bdev/lxcdir.c new file mode 100644 index 000000000..fb258405e --- /dev/null +++ b/src/lxc/bdev/lxcdir.c @@ -0,0 +1,134 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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 +#include + +#include "bdev.h" +#include "log.h" +#include "utils.h" + +lxc_log_define(lxcdir, lxc); + +/* + * for a simple directory bind mount, we substitute the old container + * name and paths for the new + */ +int dir_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 len, ret; + + if (snap) { + ERROR("directories cannot be snapshotted. Try aufs or overlayfs."); + return -1; + } + + if (!orig->dest || !orig->src) + return -1; + + len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; + new->src = malloc(len); + if (!new->src) + return -1; + ret = snprintf(new->src, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + if ((new->dest = strdup(new->src)) == NULL) + return -1; + + return 0; +} + +int dir_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + if (specs && specs->dir) + bdev->src = strdup(specs->dir); + else + bdev->src = strdup(dest); + bdev->dest = strdup(dest); + if (!bdev->src || !bdev->dest) { + ERROR("Out of memory"); + return -1; + } + + if (mkdir_p(bdev->src, 0755) < 0) { + ERROR("Error creating %s", bdev->src); + return -1; + } + if (mkdir_p(bdev->dest, 0755) < 0) { + ERROR("Error creating %s", bdev->dest); + return -1; + } + + return 0; +} + +int dir_destroy(struct bdev *orig) +{ + if (lxc_rmdir_onedev(orig->src, NULL) < 0) + return -1; + return 0; +} + +int dir_detect(const char *path) +{ + if (strncmp(path, "dir:", 4) == 0) + return 1; // take their word for it + if (is_dir(path)) + return 1; + return 0; +} + +int dir_mount(struct bdev *bdev) +{ + unsigned long mntflags; + char *mntdata; + int ret; + + if (strcmp(bdev->type, "dir")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + + if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) { + free(mntdata); + return -22; + } + + ret = mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags, mntdata); + free(mntdata); + return ret; +} + +int dir_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "dir")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} diff --git a/src/lxc/bdev/lxcdir.h b/src/lxc/bdev/lxcdir.h new file mode 100644 index 000000000..f5cca9ada --- /dev/null +++ b/src/lxc/bdev/lxcdir.h @@ -0,0 +1,52 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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_DIR_H +#define __LXC_DIR_H + +#define _GNU_SOURCE +#include + +/* defined in bdev.h */ +struct bdev; + +/* defined in lxccontainer.h */ +struct bdev_specs; + +/* defined conf.h */ +struct lxc_conf; + +/* + * Functions associated with a dir bdev struct. + */ +int dir_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 dir_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs); +int dir_destroy(struct bdev *orig); +int dir_detect(const char *path); +int dir_mount(struct bdev *bdev); +int dir_umount(struct bdev *bdev); + +#endif /* __LXC_DIR_H */