summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-05-27 13:51:29 -0400
committerDavid Sterba <dsterba@suse.cz>2015-06-02 17:35:43 +0200
commit420afa3edc3325912ee72d951af7228f66ed1831 (patch)
tree333ad8cb7116a85e8ad1c5e710dfa69b16ea3e3f
parentfa7749fdf4968707e05c367238f63aa0253b3758 (diff)
btrfs-progs: specify mountpoint for recieve
In a chroot environment we may not have /proc mounted, which makes btrfs receive freak out since it wants to know the base directory where are are mounted for things like clone and such. Give an option to specify where the mountpoint is in these cases so you can still do a btrfs receive in a chroot. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> [added manpage documentation] Signed-off-by: David Sterba <dsterba@suse.cz>
-rw-r--r--Documentation/btrfs-receive.asciidoc6
-rw-r--r--cmds-receive.c47
2 files changed, 37 insertions, 16 deletions
diff --git a/Documentation/btrfs-receive.asciidoc b/Documentation/btrfs-receive.asciidoc
index bdbabdff..84b85c1c 100644
--- a/Documentation/btrfs-receive.asciidoc
+++ b/Documentation/btrfs-receive.asciidoc
@@ -43,6 +43,12 @@ or on EOF.
--max-errors <N>::
Terminate as soon as N errors happened while processing commands from the send
stream. Default value is 1. A value of 0 means no limit.
+-m::
+The root mount point of the destination fs.
++
+By default the mountpoint is searched in /proc/self/mounts.
+If you do not have /proc, eg. in a chroot environment, use this option to tell
+us where this filesystem is mounted.
EXIT STATUS
-----------
diff --git a/cmds-receive.c b/cmds-receive.c
index 05af6f7e..114b718c 100644
--- a/cmds-receive.c
+++ b/cmds-receive.c
@@ -856,8 +856,8 @@ static struct btrfs_send_ops send_ops = {
.utimes = process_utimes,
};
-static int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd,
- u64 max_errors)
+static int do_receive(struct btrfs_receive *r, const char *tomnt,
+ char *realmnt, int r_fd, u64 max_errors)
{
int ret;
char *dest_dir_full_path;
@@ -879,20 +879,24 @@ static int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd,
goto out;
}
- ret = find_mount_root(dest_dir_full_path, &r->root_path);
- if (ret < 0) {
- fprintf(stderr,
- "ERROR: failed to determine mount point for %s: %s\n",
- dest_dir_full_path, strerror(-ret));
- ret = -EINVAL;
- goto out;
- }
- if (ret > 0) {
- fprintf(stderr,
+ if (realmnt) {
+ r->root_path = realmnt;
+ } else {
+ ret = find_mount_root(dest_dir_full_path, &r->root_path);
+ if (ret < 0) {
+ fprintf(stderr,
+ "ERROR: failed to determine mount point for %s: %s\n",
+ dest_dir_full_path, strerror(-ret));
+ ret = -EINVAL;
+ goto out;
+ }
+ if (ret > 0) {
+ fprintf(stderr,
"ERROR: %s doesn't belong to btrfs mount point\n",
dest_dir_full_path);
- ret = -EINVAL;
- goto out;
+ ret = -EINVAL;
+ goto out;
+ }
}
r->mnt_fd = open(r->root_path, O_RDONLY | O_NOATIME);
if (r->mnt_fd < 0) {
@@ -994,6 +998,7 @@ int cmd_receive(int argc, char **argv)
{
char *tomnt = NULL;
char *fromfile = NULL;
+ char *realmnt = NULL;
struct btrfs_receive r;
int receive_fd = fileno(stdin);
u64 max_errors = 1;
@@ -1013,7 +1018,7 @@ int cmd_receive(int argc, char **argv)
{ NULL, 0, NULL, 0 }
};
- c = getopt_long(argc, argv, "Cevf:", long_opts, NULL);
+ c = getopt_long(argc, argv, "Cevf:m:", long_opts, NULL);
if (c < 0)
break;
@@ -1033,6 +1038,13 @@ int cmd_receive(int argc, char **argv)
case 'E':
max_errors = arg_strtou64(optarg);
break;
+ case 'm':
+ realmnt = strdup(optarg);
+ if (!realmnt) {
+ fprintf(stderr, "ERROR: couldn't allocate realmnt.\n");
+ return 1;
+ }
+ break;
case '?':
default:
fprintf(stderr, "ERROR: receive args invalid.\n");
@@ -1053,7 +1065,7 @@ int cmd_receive(int argc, char **argv)
}
}
- ret = do_receive(&r, tomnt, receive_fd, max_errors);
+ ret = do_receive(&r, tomnt, realmnt, receive_fd, max_errors);
return !!ret;
}
@@ -1083,5 +1095,8 @@ const char * const cmd_receive_usage[] = {
"--max-errors <N> Terminate as soon as N errors happened while",
" processing commands from the send stream.",
" Default value is 1. A value of 0 means no limit.",
+ "-m <mountpoint> The root mount point of the destination fs.",
+ " If you do not have /proc use this to tell us where ",
+ " this file system is mounted.",
NULL
};