From d44e88c26690a56f9efac58f602dba06c9ec0c90 Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Thu, 15 Aug 2013 12:55:50 -0500 Subject: [PATCH] bdev: support -B best and -B lvm,dir -B dev will check whether btrfs, zfs, or lvm can be used, in that order, and fall back to dir. -B lvm,btrfs will try lvm first, then btrfs, then fail. Signed-off-by: Serge Hallyn --- src/lxc/bdev.c | 46 +++++++++++++++++++++++++++++++++--------- src/lxc/lxccontainer.c | 5 ++++- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index 07a794b3e..d6f117631 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -1977,6 +1977,22 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname, exit(0); } +static struct bdev * do_bdev_create(const char *dest, const char *type, + const char *cname, struct bdev_specs *specs) +{ + struct bdev *bdev = bdev_get(type); + if (!bdev) { + return NULL; + } + + if (bdev->ops->create(bdev, dest, cname, specs) < 0) { + bdev_put(bdev); + return NULL; + } + + return bdev; +} + /* * bdev_create: * Create a backing store for a container. @@ -1992,22 +2008,34 @@ struct bdev *bdev_create(const char *dest, const char *type, const char *cname, struct bdev_specs *specs) { struct bdev *bdev; + char *best_options[] = {"btrfs", "zfs", "lvm", "dir", NULL}; if (!type) - type = "dir"; + return do_bdev_create(dest, "dir", cname, specs); - bdev = bdev_get(type); - if (!bdev) { - ERROR("Unknown fs type: %s\n", type); - return NULL; + if (strcmp(type, "best") == 0) { + int i; + // try for the best backing store type, according to our + // opinionated preferences + for (i=0; best_options[i]; i++) { + if ((bdev = do_bdev_create(dest, best_options[i], cname, specs))) + return bdev; + } + return NULL; // 'dir' should never fail, so this shouldn't happen } - if (bdev->ops->create(bdev, dest, cname, specs) < 0) { - bdev_put(bdev); - return NULL; + // -B lvm,dir + if (index(type, ',') != NULL) { + char *dup = alloca(strlen(type)+1), *saveptr, *token; + strcpy(dup, type); + for (token = strtok_r(dup, ",", &saveptr); token; + token = strtok_r(NULL, ",", &saveptr)) { + if ((bdev = do_bdev_create(dest, token, cname, specs))) + return bdev; + } } - return bdev; + return do_bdev_create(dest, type, cname, specs); } char *overlayfs_getlower(char *p) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 1c77b632f..02e37660c 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -679,8 +679,11 @@ static struct bdev *do_bdev_create(struct lxc_container *c, const char *type, return NULL; bdev = bdev_create(dest, type, c->name, specs); - if (!bdev) + if (!bdev) { + ERROR("Failed to create backing store type %s\n", type); return NULL; + } + lxcapi_set_config_item(c, "lxc.rootfs", bdev->src); return bdev; }