summaryrefslogtreecommitdiff
path: root/cmds-receive.c
diff options
context:
space:
mode:
authorFilipe David Borba Manana <fdmanana@gmail.com>2014-05-23 20:14:56 +0100
committerDavid Sterba <dsterba@suse.cz>2014-08-22 14:39:32 +0200
commit909131939f750faffb9fab5542c94f14475379f6 (patch)
tree62b2553a2961e7c376337ab1bbba87945fd520dc /cmds-receive.c
parentc2429c8a0d34ab47e69c8e66803ad4112ff31985 (diff)
Btrfs-progs: receive, allow to continue after errors happen
Due to either bugs in send (kernel) that generate a command against a wrong path for example, or transient errors on the receiving side, we stopped processing the send stream immediately and exited with an error. It's often desirable to continue processing the send stream even if an error happens while processing a single command from the send stream. This change just adds a --max-errors <N> parameter, whose default value is 1 (preserving current behaviour), that allows to tolerate N errors before stopping. A value of 0 means to never stop no matter how many errors we get into while processing the send stream. Regardless of its value, errors are always printed to stderr when they happen, just like before this change. Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com> Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'cmds-receive.c')
-rw-r--r--cmds-receive.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/cmds-receive.c b/cmds-receive.c
index 8d85ca92..87dc1b4e 100644
--- a/cmds-receive.c
+++ b/cmds-receive.c
@@ -32,6 +32,7 @@
#include <ftw.h>
#include <wait.h>
#include <assert.h>
+#include <getopt.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -816,7 +817,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)
+static int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd,
+ u64 max_errors)
{
int ret;
char *dest_dir_full_path;
@@ -868,7 +870,8 @@ static int do_receive(struct btrfs_receive *r, const char *tomnt, int r_fd)
while (!end) {
ret = btrfs_read_and_process_send_stream(r_fd, &send_ops, r,
- r->honor_end_cmd);
+ r->honor_end_cmd,
+ max_errors);
if (ret < 0)
goto out;
if (ret)
@@ -911,6 +914,11 @@ out:
return ret;
}
+static const struct option long_opts[] = {
+ { "max-errors", 1, NULL, 'E' },
+ { NULL, 0, NULL, 0 }
+};
+
int cmd_receive(int argc, char **argv)
{
int c;
@@ -918,7 +926,7 @@ int cmd_receive(int argc, char **argv)
char *fromfile = NULL;
struct btrfs_receive r;
int receive_fd = fileno(stdin);
-
+ u64 max_errors = 1;
int ret;
memset(&r, 0, sizeof(r));
@@ -926,7 +934,7 @@ int cmd_receive(int argc, char **argv)
r.write_fd = -1;
r.dest_dir_fd = -1;
- while ((c = getopt(argc, argv, "evf:")) != -1) {
+ while ((c = getopt_long(argc, argv, "evf:", long_opts, NULL)) != -1) {
switch (c) {
case 'v':
g_verbose++;
@@ -937,6 +945,9 @@ int cmd_receive(int argc, char **argv)
case 'e':
r.honor_end_cmd = 1;
break;
+ case 'E':
+ max_errors = arg_strtou64(optarg);
+ break;
case '?':
default:
fprintf(stderr, "ERROR: receive args invalid.\n");
@@ -957,7 +968,7 @@ int cmd_receive(int argc, char **argv)
}
}
- ret = do_receive(&r, tomnt, receive_fd);
+ ret = do_receive(&r, tomnt, receive_fd, max_errors);
return !!ret;
}
@@ -983,5 +994,8 @@ const char * const cmd_receive_usage[] = {
" in the data stream. Without this option,",
" the receiver terminates only if an error",
" is recognized 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.",
NULL
};