[lxc-devel] [PATCH] use btrfs snapshot feature to restore snapshots (v2)

S.Çağlar Onur caglar at 10ur.org
Sat Mar 1 01:55:05 UTC 2014


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?

>> +             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>


More information about the lxc-devel mailing list