bdev: non-functional changes

parent b9986e43
...@@ -187,21 +187,22 @@ struct bdev_type { ...@@ -187,21 +187,22 @@ struct bdev_type {
}; };
static const struct bdev_type bdevs[] = { static const struct bdev_type bdevs[] = {
{.name = "zfs", .ops = &zfs_ops,}, { .name = "zfs", .ops = &zfs_ops, },
{.name = "lvm", .ops = &lvm_ops,}, { .name = "lvm", .ops = &lvm_ops, },
{.name = "rbd", .ops = &rbd_ops,}, { .name = "rbd", .ops = &rbd_ops, },
{.name = "btrfs", .ops = &btrfs_ops,}, { .name = "btrfs", .ops = &btrfs_ops, },
{.name = "dir", .ops = &dir_ops,}, { .name = "dir", .ops = &dir_ops, },
{.name = "aufs", .ops = &aufs_ops,}, { .name = "aufs", .ops = &aufs_ops, },
{.name = "overlayfs", .ops = &ovl_ops,}, { .name = "overlayfs", .ops = &ovl_ops, },
{.name = "loop", .ops = &loop_ops,}, { .name = "loop", .ops = &loop_ops, },
{.name = "nbd", .ops = &nbd_ops,}, { .name = "nbd", .ops = &nbd_ops, },
}; };
static const size_t numbdevs = sizeof(bdevs) / sizeof(struct bdev_type); static const size_t numbdevs = sizeof(bdevs) / sizeof(struct bdev_type);
/* helpers */ /* helpers */
static const struct bdev_type *bdev_query(struct lxc_conf *conf, const char *src); static const struct bdev_type *bdev_query(struct lxc_conf *conf,
const char *src);
static struct bdev *bdev_get(const char *type); static struct bdev *bdev_get(const char *type);
static struct bdev *do_bdev_create(const char *dest, const char *type, static struct bdev *do_bdev_create(const char *dest, const char *type,
const char *cname, struct bdev_specs *specs); const char *cname, struct bdev_specs *specs);
...@@ -245,7 +246,8 @@ char *dir_new_path(char *src, const char *oldname, const char *name, ...@@ -245,7 +246,8 @@ char *dir_new_path(char *src, const char *oldname, const char *name,
while ((p2 = strstr(src, oldname)) != NULL) { while ((p2 = strstr(src, oldname)) != NULL) {
strncpy(p, src, p2 - src); // copy text up to oldname strncpy(p, src, p2 - src); // copy text up to oldname
p += p2 - src; // move target pointer (p) p += p2 - src; // move target pointer (p)
p += sprintf(p, "%s", name); // print new name in place of oldname p += sprintf(p, "%s",
name); // print new name in place of oldname
src = p2 + l2; // move src to end of oldname src = p2 + l2; // move src to end of oldname
} }
sprintf(p, "%s", src); // copy the rest of src sprintf(p, "%s", src); // copy the rest of src
...@@ -264,15 +266,19 @@ bool attach_block_device(struct lxc_conf *conf) ...@@ -264,15 +266,19 @@ bool attach_block_device(struct lxc_conf *conf)
if (!conf->rootfs.path) if (!conf->rootfs.path)
return true; return true;
path = conf->rootfs.path; path = conf->rootfs.path;
if (!requires_nbd(path)) if (!requires_nbd(path))
return true; return true;
path = strchr(path, ':'); path = strchr(path, ':');
if (!path) if (!path)
return false; return false;
path++; path++;
if (!attach_nbd(path, conf)) if (!attach_nbd(path, conf))
return false; return false;
return true; return true;
} }
...@@ -283,6 +289,7 @@ bool bdev_can_backup(struct lxc_conf *conf) ...@@ -283,6 +289,7 @@ bool bdev_can_backup(struct lxc_conf *conf)
if (!bdev) if (!bdev)
return false; return false;
ret = bdev->ops->can_backup; ret = bdev->ops->can_backup;
bdev_put(bdev); bdev_put(bdev);
return ret; return ret;
...@@ -311,7 +318,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -311,7 +318,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
* we don't know how to come up with a new name * we don't know how to come up with a new name
*/ */
if (strstr(src, oldname) == NULL) { if (strstr(src, oldname) == NULL) {
ERROR("original rootfs path %s doesn't include container name %s", ERROR(
"original rootfs path %s doesn't include container name %s",
src, oldname); src, oldname);
return NULL; return NULL;
} }
...@@ -334,6 +342,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -334,6 +342,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
bdev_put(orig); bdev_put(orig);
return NULL; return NULL;
} }
ret = snprintf(orig->dest, len, "%s/%s/rootfs", oldpath, oldname); ret = snprintf(orig->dest, len, "%s/%s/rootfs", oldpath, oldname);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0 || (size_t)ret >= len) {
ERROR("rootfs path too long"); ERROR("rootfs path too long");
...@@ -341,9 +350,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -341,9 +350,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
return NULL; return NULL;
} }
ret = stat(orig->dest, &sb); ret = stat(orig->dest, &sb);
if (ret < 0 && errno == ENOENT) if (ret < 0 && errno == ENOENT)
if (mkdir_p(orig->dest, 0755) < 0) if (mkdir_p(orig->dest, 0755) < 0)
WARN("Error creating '%s', continuing.", orig->dest); WARN("Error creating '%s', continuing.",
orig->dest);
} }
/* /*
...@@ -357,7 +368,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -357,7 +368,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
/* /*
* If newtype is NULL and snapshot is set, then use overlayfs * If newtype is NULL and snapshot is set, then use overlayfs
*/ */
if (!bdevtype && !keepbdevtype && snap && strcmp(orig->type , "dir") == 0) if (!bdevtype && !keepbdevtype && snap &&
strcmp(orig->type, "dir") == 0)
bdevtype = "overlayfs"; bdevtype = "overlayfs";
if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) { if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
...@@ -378,7 +390,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -378,7 +390,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
new = bdev_get(bdevtype ? bdevtype : orig->type); new = bdev_get(bdevtype ? bdevtype : orig->type);
if (!new) { if (!new) {
ERROR("no such block device type: %s", bdevtype ? bdevtype : orig->type); ERROR("no such block device type: %s",
bdevtype ? bdevtype : orig->type);
bdev_put(orig); bdev_put(orig);
return NULL; return NULL;
} }
...@@ -397,10 +410,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -397,10 +410,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
/* /*
* https://github.com/lxc/lxc/issues/131 * https://github.com/lxc/lxc/issues/131
* Use btrfs snapshot feature instead of rsync to restore if both orig and new are btrfs * Use btrfs snapshot feature instead of rsync to restore if both orig
* and new are btrfs
*/ */
if (bdevtype && if (bdevtype && strcmp(orig->type, "btrfs") == 0 &&
strcmp(orig->type, "btrfs") == 0 && strcmp(new->type, "btrfs") == 0 && strcmp(new->type, "btrfs") == 0 &&
btrfs_same_fs(orig->dest, new->dest) == 0) { btrfs_same_fs(orig->dest, new->dest) == 0) {
if (btrfs_destroy(new) < 0) { if (btrfs_destroy(new) < 0) {
ERROR("Error destroying %s subvolume", new->dest); ERROR("Error destroying %s subvolume", new->dest);
...@@ -411,7 +425,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -411,7 +425,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
goto err; goto err;
} }
if (btrfs_snapshot(orig->dest, new->dest) < 0) { if (btrfs_snapshot(orig->dest, new->dest) < 0) {
ERROR("Error restoring %s to %s", orig->dest, new->dest); ERROR("Error restoring %s to %s", orig->dest,
new->dest);
goto err; goto err;
} }
bdev_put(orig); bdev_put(orig);
...@@ -437,7 +452,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -437,7 +452,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
data.orig = orig; data.orig = orig;
data.new = new; data.new = new;
if (am_unpriv()) if (am_unpriv())
ret = userns_exec_1(c0->lxc_conf, rsync_rootfs_wrapper, &data, "rsync_rootfs_wrapper"); ret = userns_exec_1(c0->lxc_conf, rsync_rootfs_wrapper, &data,
"rsync_rootfs_wrapper");
else else
ret = rsync_rootfs(&data); ret = rsync_rootfs(&data);
...@@ -474,10 +490,13 @@ struct bdev *bdev_create(const char *dest, const char *type, const char *cname, ...@@ -474,10 +490,13 @@ struct bdev *bdev_create(const char *dest, const char *type, const char *cname,
// try for the best backing store type, according to our // try for the best backing store type, according to our
// opinionated preferences // opinionated preferences
for (i = 0; best_options[i]; i++) { for (i = 0; best_options[i]; i++) {
if ((bdev = do_bdev_create(dest, best_options[i], cname, specs))) if ((bdev = do_bdev_create(dest, best_options[i], cname,
specs)))
return bdev; return bdev;
} }
return NULL; // 'dir' should never fail, so this shouldn't happen
return NULL; // 'dir' should never fail, so this shouldn't
// happen
} }
// -B lvm,dir // -B lvm,dir
...@@ -518,15 +537,18 @@ int bdev_destroy_wrapper(void *data) ...@@ -518,15 +537,18 @@ int bdev_destroy_wrapper(void *data)
ERROR("Failed to setgid to 0"); ERROR("Failed to setgid to 0");
return -1; return -1;
} }
if (setgroups(0, NULL) < 0) if (setgroups(0, NULL) < 0)
WARN("Failed to clear groups"); WARN("Failed to clear groups");
if (setuid(0) < 0) { if (setuid(0) < 0) {
ERROR("Failed to setuid to 0"); ERROR("Failed to setuid to 0");
return -1; return -1;
} }
if (!bdev_destroy(conf)) if (!bdev_destroy(conf))
return -1; return -1;
else
return 0; return 0;
} }
...@@ -549,6 +571,7 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst, ...@@ -549,6 +571,7 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
bdev = malloc(sizeof(struct bdev)); bdev = malloc(sizeof(struct bdev));
if (!bdev) if (!bdev)
return NULL; return NULL;
memset(bdev, 0, sizeof(struct bdev)); memset(bdev, 0, sizeof(struct bdev));
bdev->ops = q->ops; bdev->ops = q->ops;
bdev->type = q->name; bdev->type = q->name;
...@@ -637,8 +660,10 @@ int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -637,8 +660,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
ret = pipe(p); ret = pipe(p);
if (ret < 0) if (ret < 0)
return -1; return -1;
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
if (pid > 0) { if (pid > 0) {
int status; int status;
close(p[1]); close(p[1]);
...@@ -664,7 +689,7 @@ int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -664,7 +689,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
exit(1); exit(1);
if (detect_shared_rootfs()) { if (detect_shared_rootfs()) {
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL)) {
SYSERROR("Failed to make / rslave"); SYSERROR("Failed to make / rslave");
ERROR("Continuing..."); ERROR("Continuing...");
} }
...@@ -672,9 +697,11 @@ int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -672,9 +697,11 @@ int detect_fs(struct bdev *bdev, char *type, int len)
ret = mount_unknown_fs(srcdev, bdev->dest, bdev->mntopts); ret = mount_unknown_fs(srcdev, bdev->dest, bdev->mntopts);
if (ret < 0) { if (ret < 0) {
ERROR("failed mounting %s onto %s to detect fstype", srcdev, bdev->dest); ERROR("failed mounting %s onto %s to detect fstype", srcdev,
bdev->dest);
exit(1); exit(1);
} }
// if symlink, get the real dev name // if symlink, get the real dev name
char devpath[MAXPATHLEN]; char devpath[MAXPATHLEN];
char *l = linkderef(srcdev, devpath); char *l = linkderef(srcdev, devpath);
...@@ -683,6 +710,7 @@ int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -683,6 +710,7 @@ int detect_fs(struct bdev *bdev, char *type, int len)
f = fopen("/proc/self/mounts", "r"); f = fopen("/proc/self/mounts", "r");
if (!f) if (!f)
exit(1); exit(1);
while (getline(&line, &linelen, f) != -1) { while (getline(&line, &linelen, f) != -1) {
sp1 = strchr(line, ' '); sp1 = strchr(line, ' ');
if (!sp1) if (!sp1)
...@@ -701,8 +729,10 @@ int detect_fs(struct bdev *bdev, char *type, int len) ...@@ -701,8 +729,10 @@ int detect_fs(struct bdev *bdev, char *type, int len)
sp2++; sp2++;
if (write(p[1], sp2, strlen(sp2)) != strlen(sp2)) if (write(p[1], sp2, strlen(sp2)) != strlen(sp2))
exit(1); exit(1);
exit(0); exit(0);
} }
exit(1); exit(1);
} }
...@@ -720,9 +750,10 @@ int do_mkfs(const char *path, const char *fstype) ...@@ -720,9 +750,10 @@ int do_mkfs(const char *path, const char *fstype)
// If the file is not a block device, we don't want mkfs to ask // If the file is not a block device, we don't want mkfs to ask
// us about whether to proceed. // us about whether to proceed.
if (null_stdfds() < 0) if (null_stdfds() < 0)
exit(1); exit(EXIT_FAILURE);
execlp("mkfs", "mkfs", "-t", fstype, path, (char *)NULL); execlp("mkfs", "mkfs", "-t", fstype, path, (char *)NULL);
exit(1); exit(EXIT_FAILURE);
} }
/* /*
...@@ -733,12 +764,15 @@ int is_blktype(struct bdev *b) ...@@ -733,12 +764,15 @@ int is_blktype(struct bdev *b)
{ {
if (strcmp(b->type, "lvm") == 0) if (strcmp(b->type, "lvm") == 0)
return 1; return 1;
return 0; return 0;
} }
int mount_unknown_fs(const char *rootfs, const char *target, int mount_unknown_fs(const char *rootfs, const char *target,
const char *options) const char *options)
{ {
size_t i;
int ret;
struct cbarg { struct cbarg {
const char *rootfs; const char *rootfs;
const char *target; const char *target;
...@@ -759,11 +793,7 @@ int mount_unknown_fs(const char *rootfs, const char *target, ...@@ -759,11 +793,7 @@ int mount_unknown_fs(const char *rootfs, const char *target,
"/proc/filesystems", "/proc/filesystems",
}; };
size_t i;
for (i = 0; i < sizeof(fsfile) / sizeof(fsfile[0]); i++) { for (i = 0; i < sizeof(fsfile) / sizeof(fsfile[0]); i++) {
int ret;
if (access(fsfile[i], F_OK)) if (access(fsfile[i], F_OK))
continue; continue;
...@@ -794,13 +824,16 @@ bool rootfs_is_blockdev(struct lxc_conf *conf) ...@@ -794,13 +824,16 @@ bool rootfs_is_blockdev(struct lxc_conf *conf)
ret = stat(conf->rootfs.path, &st); ret = stat(conf->rootfs.path, &st);
if (ret == 0 && S_ISBLK(st.st_mode)) if (ret == 0 && S_ISBLK(st.st_mode))
return true; return true;
q = bdev_query(conf, conf->rootfs.path); q = bdev_query(conf, conf->rootfs.path);
if (!q) if (!q)
return false; return false;
if (strcmp(q->name, "lvm") == 0 || if (strcmp(q->name, "lvm") == 0 ||
strcmp(q->name, "loop") == 0 || strcmp(q->name, "loop") == 0 ||
strcmp(q->name, "nbd") == 0) strcmp(q->name, "nbd") == 0)
return true; return true;
return false; return false;
} }
...@@ -808,10 +841,11 @@ static struct bdev *do_bdev_create(const char *dest, const char *type, ...@@ -808,10 +841,11 @@ static struct bdev *do_bdev_create(const char *dest, const char *type,
const char *cname, struct bdev_specs *specs) const char *cname, struct bdev_specs *specs)
{ {
struct bdev *bdev = bdev_get(type); struct bdev *bdev;
if (!bdev) {
bdev = bdev_get(type);
if (!bdev)
return NULL; return NULL;
}
if (bdev->ops->create(bdev, dest, cname, specs) < 0) { if (bdev->ops->create(bdev, dest, cname, specs) < 0) {
bdev_put(bdev); bdev_put(bdev);
...@@ -830,14 +864,18 @@ static struct bdev *bdev_get(const char *type) ...@@ -830,14 +864,18 @@ static struct bdev *bdev_get(const char *type)
if (strcmp(bdevs[i].name, type) == 0) if (strcmp(bdevs[i].name, type) == 0)
break; break;
} }
if (i == numbdevs) if (i == numbdevs)
return NULL; return NULL;
bdev = malloc(sizeof(struct bdev)); bdev = malloc(sizeof(struct bdev));
if (!bdev) if (!bdev)
return NULL; return NULL;
memset(bdev, 0, sizeof(struct bdev)); memset(bdev, 0, sizeof(struct bdev));
bdev->ops = bdevs[i].ops; bdev->ops = bdevs[i].ops;
bdev->type = bdevs[i].name; bdev->type = bdevs[i].name;
return bdev; return bdev;
} }
...@@ -885,7 +923,7 @@ static const struct bdev_type *bdev_query(struct lxc_conf *conf, ...@@ -885,7 +923,7 @@ static const struct bdev_type *bdev_query(struct lxc_conf *conf,
* the callback system, they can be pulled from there eventually, so we * the callback system, they can be pulled from there eventually, so we
* don't need to pollute utils.c with these low level functions * don't need to pollute utils.c with these low level functions
*/ */
static int find_fstype_cb(char* buffer, void *data) static int find_fstype_cb(char *buffer, void *data)
{ {
struct cbarg { struct cbarg {
const char *rootfs; const char *rootfs;
...@@ -905,8 +943,8 @@ static int find_fstype_cb(char* buffer, void *data) ...@@ -905,8 +943,8 @@ static int find_fstype_cb(char* buffer, void *data)
fstype += lxc_char_left_gc(fstype, strlen(fstype)); fstype += lxc_char_left_gc(fstype, strlen(fstype));
fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0'; fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0';
DEBUG("trying to mount '%s'->'%s' with fstype '%s'", DEBUG("trying to mount '%s'->'%s' with fstype '%s'", cbarg->rootfs,
cbarg->rootfs, cbarg->target, fstype); cbarg->target, fstype);
if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) { if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) {
free(mntdata); free(mntdata);
...@@ -921,8 +959,8 @@ static int find_fstype_cb(char* buffer, void *data) ...@@ -921,8 +959,8 @@ static int find_fstype_cb(char* buffer, void *data)
free(mntdata); free(mntdata);
INFO("mounted '%s' on '%s', with fstype '%s'", INFO("mounted '%s' on '%s', with fstype '%s'", cbarg->rootfs,
cbarg->rootfs, cbarg->target, fstype); cbarg->target, fstype);
return 1; return 1;
} }
...@@ -935,8 +973,10 @@ static char *linkderef(char *path, char *dest) ...@@ -935,8 +973,10 @@ static char *linkderef(char *path, char *dest)
ret = stat(path, &sbuf); ret = stat(path, &sbuf);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
if (!S_ISLNK(sbuf.st_mode)) if (!S_ISLNK(sbuf.st_mode))
return path; return path;
ret = readlink(path, dest, MAXPATHLEN); ret = readlink(path, dest, MAXPATHLEN);
if (ret < 0) { if (ret < 0) {
SYSERROR("error reading link %s", path); SYSERROR("error reading link %s", path);
...@@ -946,6 +986,7 @@ static char *linkderef(char *path, char *dest) ...@@ -946,6 +986,7 @@ static char *linkderef(char *path, char *dest)
return NULL; return NULL;
} }
dest[ret] = '\0'; dest[ret] = '\0';
return dest; return dest;
} }
...@@ -965,6 +1006,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, ...@@ -965,6 +1006,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
strcmp(b->type, "btrfs") == 0 || strcmp(b->type, "btrfs") == 0 ||
strcmp(b->type, "loop") == 0) strcmp(b->type, "loop") == 0)
return true; return true;
return false; return false;
} }
...@@ -976,6 +1018,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, ...@@ -976,6 +1018,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
strcmp(t, "btrfs") == 0 || strcmp(t, "btrfs") == 0 ||
strcmp(t, "loop") == 0) strcmp(t, "loop") == 0)
return true; return true;
return false; return false;
} }
...@@ -991,5 +1034,6 @@ bool is_valid_bdev_type(const char *type) ...@@ -991,5 +1034,6 @@ bool is_valid_bdev_type(const char *type)
strcmp(type, "rbd") == 0 || strcmp(type, "rbd") == 0 ||
strcmp(type, "zfs") == 0) strcmp(type, "zfs") == 0)
return true; return true;
return false; return false;
} }
...@@ -23,17 +23,13 @@ ...@@ -23,17 +23,13 @@
#ifndef __LXC_BDEV_H #ifndef __LXC_BDEV_H
#define __LXC_BDEV_H #define __LXC_BDEV_H
/* blockdev operations for:
* aufs, dir, raw, btrfs, overlayfs, aufs, lvm, loop, zfs, nbd (qcow2, raw, vdi, qed)
*/
#include <lxc/lxccontainer.h> #include "config.h"
#include <stdint.h> #include <stdint.h>
#include <sys/mount.h> #include <sys/mount.h>
#include "config.h" #include <lxc/lxccontainer.h>
/* define constants if the kernel/glibc headers don't define them */
#ifndef MS_DIRSYNC #ifndef MS_DIRSYNC
#define MS_DIRSYNC 128 #define MS_DIRSYNC 128
#endif #endif
...@@ -73,18 +69,19 @@ struct bdev_ops { ...@@ -73,18 +69,19 @@ struct bdev_ops {
int (*create)(struct bdev *bdev, const char *dest, const char *n, int (*create)(struct bdev *bdev, const char *dest, const char *n,
struct bdev_specs *specs); struct bdev_specs *specs);
/* given original mount, rename the paths for cloned container */ /* given original mount, rename the paths for cloned container */
int (*clone_paths)(struct bdev *orig, struct bdev *new, const char *oldname, int (*clone_paths)(struct bdev *orig, struct bdev *new,
const char *cname, const char *oldpath, const char *lxcpath, const char *oldname, const char *cname,
int snap, uint64_t newsize, struct lxc_conf *conf); const char *oldpath, const char *lxcpath, int snap,
uint64_t newsize, struct lxc_conf *conf);
bool can_snapshot; bool can_snapshot;
bool can_backup; bool can_backup;
}; };
/* /*
* When lxc-start (conf.c) is mounting a rootfs, then src will be the * When lxc-start is mounting a rootfs, then src will be the "lxc.rootfs" value,
* 'lxc.rootfs' value, dest will be mount dir (i.e. $libdir/lxc) When clone * dest will be mount dir (i.e. $libdir/lxc) When clone or create is doing so,
* or create is doing so, then dest will be $lxcpath/$lxcname/rootfs, since * then dest will be $lxcpath/$lxcname/rootfs, since we may need to rsync from
* we may need to rsync from one to the other. * one to the other.
* data is so far unused. * data is so far unused.
*/ */
struct bdev { struct bdev {
...@@ -93,10 +90,10 @@ struct bdev { ...@@ -93,10 +90,10 @@ struct bdev {
char *src; char *src;
char *dest; char *dest;
char *mntopts; char *mntopts;
// turn the following into a union if need be /* Turn the following into a union if need be. */
// lofd is the open fd for the mounted loopback file /* lofd is the open fd for the mounted loopback file. */
int lofd; int lofd;
// index for the connected nbd device /* index for the connected nbd device. */
int nbd_idx; int nbd_idx;
}; };
...@@ -104,9 +101,9 @@ bool bdev_is_dir(struct lxc_conf *conf, const char *path); ...@@ -104,9 +101,9 @@ bool bdev_is_dir(struct lxc_conf *conf, const char *path);
bool bdev_can_backup(struct lxc_conf *conf); bool bdev_can_backup(struct lxc_conf *conf);
/* /*
* Instantiate a bdev object. The src is used to determine which blockdev * Instantiate a bdev object. The src is used to determine which blockdev type
* type this should be. The dst and data are optional, and will be used * this should be. The dst and data are optional, and will be used in case of
* in case of mount/umount. * mount/umount.
* *
* Optionally, src can be 'dir:/var/lib/lxc/c1' or 'lvm:/dev/lxc/c1'. For * Optionally, src can be 'dir:/var/lib/lxc/c1' or 'lvm:/dev/lxc/c1'. For
* other backing stores, this will allow additional options. In particular, * other backing stores, this will allow additional options. In particular,
...@@ -118,13 +115,13 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst, ...@@ -118,13 +115,13 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst,
const char *data); const char *data);
struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
const char *lxcpath, const char *bdevtype, const char *lxcpath, const char *bdevtype, int flags,
int flags, const char *bdevdata, uint64_t newsize, const char *bdevdata, uint64_t newsize, int *needs_rdep);
int *needs_rdep); struct bdev *bdev_create(const char *dest, const char *type, const char *cname,
struct bdev *bdev_create(const char *dest, const char *type, struct bdev_specs *specs);
const char *cname, struct bdev_specs *specs);
void bdev_put(struct bdev *bdev); void bdev_put(struct bdev *bdev);
bool bdev_destroy(struct lxc_conf *conf); bool bdev_destroy(struct lxc_conf *conf);
/* callback function to be used with userns_exec_1() */ /* callback function to be used with userns_exec_1() */
int bdev_destroy_wrapper(void *data); int bdev_destroy_wrapper(void *data);
...@@ -139,6 +136,7 @@ int is_blktype(struct bdev *b); ...@@ -139,6 +136,7 @@ int is_blktype(struct bdev *b);
int mount_unknown_fs(const char *rootfs, const char *target, int mount_unknown_fs(const char *rootfs, const char *target,
const char *options); const char *options);
bool rootfs_is_blockdev(struct lxc_conf *conf); bool rootfs_is_blockdev(struct lxc_conf *conf);
/* /*
* these are really for qemu-nbd support, as container shutdown * these are really for qemu-nbd support, as container shutdown
* must explicitly request device detach. * must explicitly request device detach.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment