[lxc-devel] [PATCH] use btrfs snapshot feature to restore snapshots (v2)
Stéphane Graber
stgraber at ubuntu.com
Sat Mar 1 02:09:08 UTC 2014
On Fri, Feb 28, 2014 at 08:55:05PM -0500, S.Çağlar Onur wrote:
> On Fri, Feb 28, 2014 at 7:14 PM, Serge Hallyn <serge.hallyn at ubuntu.com> wrote:
> > Quoting S.Çağlar Onur (caglar at 10ur.org):
> >> fixes #131
> >>
> >> changes since v1;
> >> * uses btrfs snapshot feature only if src and dest are on same fs
> >>
> >> Signed-off-by: S.Çağlar Onur <caglar at 10ur.org>
> >
> > Thanks! Looks good except for one little thing
> >
> > Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> >
> >> ---
> >> src/lxc/bdev.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
> >> 1 file changed, 80 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> >> index 627c09a..233c97d 100644
> >> --- a/src/lxc/bdev.c
> >> +++ b/src/lxc/bdev.c
> >> @@ -1336,6 +1336,56 @@ static int btrfs_subvolume_create(const char *path)
> >> return ret;
> >> }
> >>
> >> +#define BTRFS_FSID_SIZE 16
> >> +struct btrfs_ioctl_fs_info_args {
> >> + unsigned long long max_id;
> >> + unsigned long long num_devices;
> >> + char fsid[BTRFS_FSID_SIZE];
> >> + unsigned long long reserved[124];
> >> +};
> >> +
> >> +#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
> >> + struct btrfs_ioctl_fs_info_args)
> >> +
> >> +static int btrfs_same_fs(const char *orig, const char *new) {
> >> + int fd_orig = -1, fd_new = -1, ret = -1;
> >> + struct btrfs_ioctl_fs_info_args orig_args, new_args;
> >> +
> >> + fd_orig = open(orig, O_RDONLY);
> >> + if (fd_orig < 0) {
> >> + SYSERROR("Error opening original rootfs %s", orig);
> >> + goto out;
> >> + }
> >> + ret = ioctl(fd_orig, BTRFS_IOC_FS_INFO, &orig_args);
> >> + if (ret < 0) {
> >> + SYSERROR("BTRFS_IOC_FS_INFO %s", orig);
> >> + goto out;
> >> + }
> >> +
> >> + fd_new = open(new, O_RDONLY);
> >> + if (fd_new < 0) {
> >> + SYSERROR("Error opening new container dir %s", new);
> >
> > If this fails here, ret will still still be 0.
>
> Ahh, do you want me to send a new one or are you going to take care of
> it while pushing?
I'll push with ret = -1;
>
> >> + goto out;
> >> + }
> >> + ret = ioctl(fd_new, BTRFS_IOC_FS_INFO, &new_args);
> >> + if (ret < 0) {
> >> + SYSERROR("BTRFS_IOC_FS_INFO %s", new);
> >> + goto out;
> >> + }
> >> +
> >> + if (strncmp(orig_args.fsid, new_args.fsid, BTRFS_FSID_SIZE) != 0) {
> >> + ret = -1;
> >> + goto out;
> >> + }
> >> + ret = 0;
> >> +out:
> >> + if (fd_new != -1)
> >> + close(fd_new);
> >> + if (fd_orig != -1)
> >> + close(fd_orig);
> >> + return ret;
> >> +}
> >> +
> >> static int btrfs_snapshot(const char *orig, const char *new)
> >> {
> >> int fd = -1, fddst = -1, ret = -1;
> >> @@ -2587,9 +2637,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> >> if (new->ops->clone_paths(orig, new, oldname, cname, oldpath, lxcpath,
> >> snap, newsize, c0->lxc_conf) < 0) {
> >> ERROR("failed getting pathnames for cloned storage: %s", src);
> >> - bdev_put(orig);
> >> - bdev_put(new);
> >> - return NULL;
> >> + goto err;
> >> }
> >>
> >> if (am_unpriv() && chown_mapped_root(new->src, c0->lxc_conf) < 0)
> >> @@ -2598,12 +2646,33 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> >> if (snap)
> >> return new;
> >>
> >> + /*
> >> + * https://github.com/lxc/lxc/issues/131
> >> + * Use btrfs snapshot feature instead of rsync to restore if both orig and new are btrfs
> >> + */
> >> + if (bdevtype &&
> >> + strcmp(orig->type, "btrfs") == 0 && strcmp(new->type, "btrfs") == 0 &&
> >> + btrfs_same_fs(orig->dest, new->dest) == 0) {
> >> + if (btrfs_destroy(new) < 0) {
> >> + ERROR("Error destroying %s subvolume", new->dest);
> >> + goto err;
> >> + }
> >> + if (mkdir_p(new->dest, 0755) < 0) {
> >> + ERROR("Error creating %s directory", new->dest);
> >> + goto err;
> >> + }
> >> + if (btrfs_snapshot(orig->dest, new->dest) < 0) {
> >> + ERROR("Error restoring %s to %s", orig->dest, new->dest);
> >> + goto err;
> >> + }
> >> + bdev_put(orig);
> >> + return new;
> >> + }
> >> +
> >> pid = fork();
> >> if (pid < 0) {
> >> SYSERROR("fork");
> >> - bdev_put(orig);
> >> - bdev_put(new);
> >> - return NULL;
> >> + goto err;
> >> }
> >>
> >> if (pid > 0) {
> >> @@ -2624,6 +2693,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> >> ret = rsync_rootfs(&data);
> >>
> >> exit(ret == 0 ? 0 : 1);
> >> +
> >> +err:
> >> + bdev_put(orig);
> >> + bdev_put(new);
> >> + return NULL;
> >> }
> >>
> >> static struct bdev * do_bdev_create(const char *dest, const char *type,
> >> --
> >> 1.8.3.2
> >>
> >> _______________________________________________
> >> lxc-devel mailing list
> >> lxc-devel at lists.linuxcontainers.org
> >> http://lists.linuxcontainers.org/listinfo/lxc-devel
> > _______________________________________________
> > lxc-devel mailing list
> > lxc-devel at lists.linuxcontainers.org
> > http://lists.linuxcontainers.org/listinfo/lxc-devel
>
>
>
> --
> S.Çağlar Onur <caglar at 10ur.org>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140228/c4dd9de8/attachment.pgp>
More information about the lxc-devel
mailing list