btrfs-progs: receive: introduce option to dump send stream
authorQu Wenruo <quwenruo@cn.fujitsu.com>
Wed, 7 Sep 2016 00:29:34 +0000 (08:29 +0800)
committerDavid Sterba <dsterba@suse.com>
Wed, 14 Dec 2016 14:06:34 +0000 (15:06 +0100)
Introduce new option, '--dump' for receive subcommand.

With this command, user can dump the metadata of a send stream.
Which is quite useful for education purpose or bug reporting.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Documentation/btrfs-receive.asciidoc
cmds-receive.c

index e246603..f12e949 100644 (file)
@@ -9,12 +9,19 @@ SYNOPSIS
 --------
 *btrfs receive* [options] <path>
 
+or
+
+*btrfs receive* --dump [options]
+
 DESCRIPTION
 -----------
 
 Receive a stream of changes and replicate one or more subvolumes that were
 previously used with *btrfs send* The received subvolumes are stored to
-'path'.
+'path', if '--dump' option is not given.
+
+If '--dump' option is given, *btrfs receive* will only do the validation of
+the stream, and print the stream metadata.
 
 *btrfs receive* will fail int the following cases:
 
@@ -56,6 +63,12 @@ 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.
 
+--dump::
+print the stream metadata
++
+Does not accept the 'path' parameter. So with this option, *btrfs receive* won't
+modify your filesystem, and can be run by non-privileged users.
+
 EXIT STATUS
 -----------
 *btrfs receive* returns a zero exit status if it succeeds. Non zero is
index 85a6eea..68950b4 100644 (file)
@@ -49,6 +49,7 @@
 #include "send.h"
 #include "send-stream.h"
 #include "send-utils.h"
+#include "send-dump.h"
 
 static int g_verbose = 0;
 
@@ -1226,6 +1227,7 @@ int cmd_receive(int argc, char **argv)
        struct btrfs_receive rctx;
        int receive_fd = fileno(stdin);
        u64 max_errors = 1;
+       int dump = 0;
        int ret = 0;
 
        memset(&rctx, 0, sizeof(rctx));
@@ -1238,9 +1240,11 @@ int cmd_receive(int argc, char **argv)
 
        while (1) {
                int c;
+               enum { GETOPT_VAL_DUMP = 257 };
                static const struct option long_opts[] = {
                        { "max-errors", required_argument, NULL, 'E' },
                        { "chroot", no_argument, NULL, 'C' },
+                       { "dump", no_argument, NULL, GETOPT_VAL_DUMP },
                        { NULL, 0, NULL, 0 }
                };
 
@@ -1277,6 +1281,9 @@ int cmd_receive(int argc, char **argv)
                                goto out;
                        }
                        break;
+               case GETOPT_VAL_DUMP:
+                       dump = 1;
+                       break;
                case '?':
                default:
                        error("receive args invalid");
@@ -1284,7 +1291,9 @@ int cmd_receive(int argc, char **argv)
                }
        }
 
-       if (check_argc_exact(argc - optind, 1))
+       if (dump && check_argc_exact(argc - optind, 0))
+               usage(cmd_receive_usage);
+       if (!dump && check_argc_exact(argc - optind, 1))
                usage(cmd_receive_usage);
 
        tomnt = argv[optind];
@@ -1297,17 +1306,33 @@ int cmd_receive(int argc, char **argv)
                }
        }
 
-       ret = do_receive(&rctx, tomnt, realmnt, receive_fd, max_errors);
+       if (dump) {
+               struct btrfs_dump_send_args dump_args;
+
+               dump_args.root_path[0] = '.';
+               dump_args.root_path[1] = '\0';
+               dump_args.full_subvol_path[0] = '.';
+               dump_args.full_subvol_path[1] = '\0';
+               ret = btrfs_read_and_process_send_stream(receive_fd,
+                               &btrfs_print_send_ops, &dump_args, 0, 0);
+               if (ret < 0)
+                       error("failed to dump the send stream: %s",
+                             strerror(-ret));
+       } else {
+               ret = do_receive(&rctx, tomnt, realmnt, receive_fd, max_errors);
+       }
+
        if (receive_fd != fileno(stdin))
                close(receive_fd);
-
 out:
 
        return !!ret;
 }
 
 const char * const cmd_receive_usage[] = {
-       "btrfs receive [-ve] [-f <infile>] [--max-errors <N>] <mount>",
+       "btrfs receive [options] <mount>",
+       "or",
+       "btrfs receive --dump [options]",
        "Receive subvolumes from stdin.",
        "Receives one or more subvolumes that were previously",
        "sent with btrfs send. The received subvolumes are stored",
@@ -1334,5 +1359,7 @@ const char * const cmd_receive_usage[] = {
        "-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.",
+       "--dump           Exam and output metadata info of send stream.",
+       "                 Don't need <mount> parameter.",
        NULL
 };