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

Serge Hallyn serge.hallyn at ubuntu.com
Sat Mar 1 00:14:57 UTC 2014


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.

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


More information about the lxc-devel mailing list