From 9572c2fae80bca094050f7ad4f0d8f8187bed233 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Sun, 30 Dec 2012 12:46:27 +0100 Subject: [PATCH] btrfs-progs: minor patches to get "btrfs receive" working --- ...s-progs-Fix-the-receive-code-pathing.patch | 146 ++++++++++++++++++ .../btrfsprogs/btrfs-receive-help-text.patch | 13 ++ .../btrfsprogs/btrfs-receive-lchown.patch | 12 ++ pkgs/tools/filesystems/btrfsprogs/default.nix | 7 +- 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 pkgs/tools/filesystems/btrfsprogs/btrfs-progs-Fix-the-receive-code-pathing.patch create mode 100644 pkgs/tools/filesystems/btrfsprogs/btrfs-receive-help-text.patch create mode 100644 pkgs/tools/filesystems/btrfsprogs/btrfs-receive-lchown.patch diff --git a/pkgs/tools/filesystems/btrfsprogs/btrfs-progs-Fix-the-receive-code-pathing.patch b/pkgs/tools/filesystems/btrfsprogs/btrfs-progs-Fix-the-receive-code-pathing.patch new file mode 100644 index 000000000000..6dd0639c607e --- /dev/null +++ b/pkgs/tools/filesystems/btrfsprogs/btrfs-progs-Fix-the-receive-code-pathing.patch @@ -0,0 +1,146 @@ +diff --git a/cmds-receive.c b/cmds-receive.c +index a8be6fa..6b7cf12 100644 +--- a/cmds-receive.c ++++ b/cmds-receive.c +@@ -52,11 +52,13 @@ static int g_verbose = 0; + struct btrfs_receive + { + int mnt_fd; ++ int dest_dir_fd; + + int write_fd; + char *write_path; + + char *root_path; ++ char *dest_dir_path; /* relative to root_path */ + char *full_subvol_path; + + struct subvol_info *cur_subvol; +@@ -150,8 +152,11 @@ static int process_subvol(const char *path, const u8 *uuid, u64 ctransid, + r->cur_subvol = calloc(1, sizeof(*r->cur_subvol)); + r->parent_subvol = NULL; + +- r->cur_subvol->path = strdup(path); +- r->full_subvol_path = path_cat(r->root_path, path); ++ if (strlen(r->dest_dir_path) == 0) ++ r->cur_subvol->path = strdup(path); ++ else ++ r->cur_subvol->path = path_cat(r->dest_dir_path, path); ++ r->full_subvol_path = path_cat3(r->root_path, r->dest_dir_path, path); + + fprintf(stderr, "At subvol %s\n", path); + +@@ -167,7 +172,7 @@ static int process_subvol(const char *path, const u8 *uuid, u64 ctransid, + + memset(&args_v1, 0, sizeof(args_v1)); + strcpy(args_v1.name, path); +- ret = ioctl(r->mnt_fd, BTRFS_IOC_SUBVOL_CREATE, &args_v1); ++ ret = ioctl(r->dest_dir_fd, BTRFS_IOC_SUBVOL_CREATE, &args_v1); + if (ret < 0) { + ret = -errno; + fprintf(stderr, "ERROR: creating subvolume %s failed. " +@@ -195,8 +200,11 @@ static int process_snapshot(const char *path, const u8 *uuid, u64 ctransid, + r->cur_subvol = calloc(1, sizeof(*r->cur_subvol)); + r->parent_subvol = NULL; + +- r->cur_subvol->path = strdup(path); +- r->full_subvol_path = path_cat(r->root_path, path); ++ if (strlen(r->dest_dir_path) == 0) ++ r->cur_subvol->path = strdup(path); ++ else ++ r->cur_subvol->path = path_cat(r->dest_dir_path, path); ++ r->full_subvol_path = path_cat3(r->root_path, r->dest_dir_path, path); + + fprintf(stderr, "At snapshot %s\n", path); + +@@ -243,7 +251,7 @@ static int process_snapshot(const char *path, const u8 *uuid, u64 ctransid, + goto out; + } + +- ret = ioctl(r->mnt_fd, BTRFS_IOC_SNAP_CREATE_V2, &args_v2); ++ ret = ioctl(r->dest_dir_fd, BTRFS_IOC_SNAP_CREATE_V2, &args_v2); + close(args_v2.fd); + if (ret < 0) { + ret = -errno; +@@ -790,17 +798,48 @@ struct btrfs_send_ops send_ops = { + int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd) + { + int ret; ++ char *dest_dir_full_path; + int end = 0; + +- r->root_path = strdup(tomnt); +- r->mnt_fd = open(tomnt, O_RDONLY | O_NOATIME); ++ dest_dir_full_path = realpath(tomnt, NULL); ++ if (!dest_dir_full_path) { ++ ret = -errno; ++ fprintf(stderr, "ERROR: realpath(%s) failed. %s\n", tomnt, ++ strerror(-ret)); ++ goto out; ++ } ++ r->dest_dir_fd = open(dest_dir_full_path, O_RDONLY | O_NOATIME); ++ if (r->dest_dir_fd < 0) { ++ ret = -errno; ++ fprintf(stderr, "ERROR: failed to open destination directory %s. %s\n", ++ dest_dir_full_path, strerror(-ret)); ++ goto out; ++ } ++ ++ ret = find_mount_root(dest_dir_full_path, &r->root_path); ++ if (ret < 0) { ++ ret = -EINVAL; ++ fprintf(stderr, "ERROR: failed to determine mount point " ++ "for %s\n", dest_dir_full_path); ++ goto out; ++ } ++ r->mnt_fd = open(r->root_path, O_RDONLY | O_NOATIME); + if (r->mnt_fd < 0) { + ret = -errno; +- fprintf(stderr, "ERROR: failed to open %s. %s\n", tomnt, ++ fprintf(stderr, "ERROR: failed to open %s. %s\n", r->root_path, + strerror(-ret)); + goto out; + } + ++ /* ++ * find_mount_root returns a root_path that is a subpath of ++ * dest_dir_full_path. Now get the other part of root_path, ++ * which is the destination dir relative to root_path. ++ */ ++ r->dest_dir_path = dest_dir_full_path + strlen(r->root_path); ++ if (r->dest_dir_path[0] == '/') ++ r->dest_dir_path++; ++ + ret = subvol_uuid_search_init(r->mnt_fd, &r->sus); + if (ret < 0) + return ret; +diff --git a/cmds-send.c b/cmds-send.c +index 9b47e70..c408bc7 100644 +--- a/cmds-send.c ++++ b/cmds-send.c +@@ -81,6 +81,14 @@ int find_mount_root(const char *path, char **mount_root) + } + } + ++ if (!longest_match) { ++ fprintf(stderr, "ERROR: Failed to find mount root for path %s.\n", ++ path); ++ fprintf(stderr, "Please make sure that you have a valid \ ++ /etc/mtab file.\n"); ++ return -ENOENT; ++ } ++ + *mount_root = realpath(longest_match, NULL); + free(longest_match); + +diff --git a/send-utils.h b/send-utils.h +index da407eb..a3e038b 100644 +--- a/send-utils.h ++++ b/send-utils.h +@@ -65,5 +65,6 @@ void subvol_uuid_search_add(struct subvol_uuid_search *s, + char *path_cat(const char *p1, const char *p2); + char *path_cat3(const char *p1, const char *p2, const char *p3); + ++int find_mount_root(const char *path, char **mount_root); + + #endif /* SEND_UTILS_H_ */ diff --git a/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-help-text.patch b/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-help-text.patch new file mode 100644 index 000000000000..a9892cc780ed --- /dev/null +++ b/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-help-text.patch @@ -0,0 +1,13 @@ +diff --git a/cmds-receive.c b/cmds-receive.c +index a8be6fa..c182175 100644 +--- a/cmds-receive.c ++++ b/cmds-receive.c +@@ -880,7 +880,7 @@ static const char * const receive_cmd_group_usage[] = { + }; + + static const char * const cmd_receive_usage[] = { +- "btrfs receive [-v] [-i ] ", ++ "btrfs receive [-v] [-f ] ", + "Receive subvolumes from stdin.", + "Receives one or more subvolumes that were previously ", + "sent with btrfs send. The received subvolumes are stored", diff --git a/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-lchown.patch b/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-lchown.patch new file mode 100644 index 000000000000..3abb1ba25d32 --- /dev/null +++ b/pkgs/tools/filesystems/btrfsprogs/btrfs-receive-lchown.patch @@ -0,0 +1,12 @@ +diff --git a/cmds-receive.c b/cmds-receive.c +index 6b7cf12..a6a6a5b 100644 +--- a/cmds-receive.c ++++ b/cmds-receive.c +@@ -731,7 +731,7 @@ static int process_chown(const char *path, u64 uid, u64 gid, void *user) + fprintf(stderr, "chown %s - uid=%llu, gid=%llu\n", path, + uid, gid); + +- ret = chown(full_path, uid, gid); ++ ret = lchown(full_path, uid, gid); + if (ret < 0) { + ret = -errno; diff --git a/pkgs/tools/filesystems/btrfsprogs/default.nix b/pkgs/tools/filesystems/btrfsprogs/default.nix index c8a39a1672a0..37b83c2c9a21 100644 --- a/pkgs/tools/filesystems/btrfsprogs/default.nix +++ b/pkgs/tools/filesystems/btrfsprogs/default.nix @@ -11,7 +11,12 @@ stdenv.mkDerivation { sha256 = "72d4cd4fb23d876a17146d6231ad40a2151fa47c648485c54cf7478239b43764"; }; - patches = [ ./subvol-listing.patch ]; + patches = [ + ./subvol-listing.patch + ./btrfs-receive-help-text.patch + ./btrfs-progs-Fix-the-receive-code-pathing.patch + ./btrfs-receive-lchown.patch + ]; buildInputs = [ zlib libuuid acl attr e2fsprogs ];