All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] btrfs-progs: Introduce new send-dump object
@ 2016-08-01  6:29 Qu Wenruo
  2016-08-01  6:29 ` [PATCH 2/3] btrfs-progs: inspect: Introduce dump-send-stream subcommand Qu Wenruo
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-08-01  6:29 UTC (permalink / raw)
  To: linux-btrfs

Introduce send-dump.[ch] which implements a new btrfs_send_ops to
exam and output all operations inside a send stream.

It has a better output format than the old and no longer compilable
send-test tool, but still tries to be script friendly.

Provides the basis for later "inspect-internal dump-send" command.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 Makefile.in |   2 +-
 send-dump.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 send-dump.h |  24 ++++
 3 files changed, 392 insertions(+), 1 deletion(-)
 create mode 100644 send-dump.c
 create mode 100644 send-dump.h

diff --git a/Makefile.in b/Makefile.in
index ac6b353..97caf95 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
 	  extent-cache.o extent_io.o volumes.o utils.o repair.o \
 	  qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
 	  ulist.o qgroup-verify.o backref.o string-table.o task-utils.o \
-	  inode.o file.o find-root.o free-space-tree.o help.o
+	  inode.o file.o find-root.o free-space-tree.o help.o send-dump.o
 cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
 	       cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
 	       cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
diff --git a/send-dump.c b/send-dump.c
new file mode 100644
index 0000000..bf451c7
--- /dev/null
+++ b/send-dump.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#include <unistd.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <libgen.h>
+#include <mntent.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <asm/types.h>
+#include <uuid/uuid.h>
+#include "utils.h"
+#include "commands.h"
+#include "send-utils.h"
+#include "send-stream.h"
+#include "send-dump.h"
+
+#define path_cat_out_with_error(function_name, out_path, path1, path2, ret) \
+ret = path_cat_out(out_path, path1, path2);			\
+if (ret < 0) {							\
+	error("%s: path invalid: %s\n", function_name, path2);	\
+	return ret;						\
+}
+
+#define TITLE_WIDTH	16
+#define PATH_WIDTH	32
+
+static void print_dump(const char *title, const char *path,
+	  	       const char *fmt, ...)
+{
+	va_list args;
+	char real_title[TITLE_WIDTH + 1];
+
+	real_title[0]='\0';
+	/* Append ':' to title*/
+	strncpy(real_title, title, TITLE_WIDTH - 1);
+	strncat(real_title, ":", TITLE_WIDTH);
+
+	/* Unified output */
+	printf("%-*s%-*s", TITLE_WIDTH, real_title, PATH_WIDTH, path);
+	va_start(args, fmt);
+	/* Command specified output */
+	vprintf(fmt, args);
+	va_end(args);
+	printf("\n");
+}
+
+static int print_subvol(const char *path, const u8 *uuid, u64 ctransid,
+			void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	int ret;
+
+	path_cat_out_with_error("subvol", r->full_subvol_path, r->root_path,
+				path, ret);
+	uuid_unparse(uuid, uuid_str);
+
+	print_dump("subvol", r->full_subvol_path, "uuid: %s, transid: %llu",
+		   uuid_str, ctransid);
+	return 0;
+}
+
+static int print_snapshot(const char *path, const u8 *uuid, u64 ctransid,
+			  const u8 *parent_uuid, u64 parent_ctransid,
+			  void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	char parent_uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	int ret;
+
+	path_cat_out_with_error("snapshot", r->full_subvol_path, r->root_path,
+				path, ret);
+	uuid_unparse(uuid, uuid_str);
+	uuid_unparse(parent_uuid, parent_uuid_str);
+
+	print_dump("snapshot", r->full_subvol_path,
+		   "uuid: %s, transid: %llu, parent_uuid: %s, parent_transid: %llu",
+		   uuid_str, ctransid, parent_uuid_str, parent_ctransid);
+	return 0;
+}
+
+static int print_mkfile(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkfile", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkfile", full_path, "");
+	return 0;
+}
+
+static int print_mkdir(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkdir", full_path, "");
+	return 0;
+}
+
+static int print_mknod(const char *path, u64 mode, u64 dev, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mknod", full_path, "mode: %llo, dev: 0x%llx", mode, dev);
+	return 0;
+}
+
+static int print_mkfifo(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkfifo", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkfifo", full_path, "");
+	return 0;
+}
+
+static int print_mksock(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mksock", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mksock", full_path, "");
+	return 0;
+}
+
+static int print_symlink(const char *path, const char *lnk, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("symlink", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("symlink", full_path, "lnk: %s", lnk);
+	return 0;
+}
+
+static int print_rename(const char *from, const char *to, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_from[PATH_MAX];
+	char full_to[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("rename", full_from, r->full_subvol_path, from,
+				ret);
+	path_cat_out_with_error("rename", full_to, r->full_subvol_path, to,
+				ret);
+	print_dump("rename", full_from, "to %s", full_to);
+	return 0;
+}
+
+static int print_link(const char *path, const char *lnk, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("link", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("link", full_path, "lnk: %s", lnk);
+	return 0;
+}
+
+static int print_unlink(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("unlink", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("unlink", full_path, "");
+	return 0;
+}
+
+static int print_rmdir(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("rmdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("rmdir", full_path, "");
+	return 0;
+}
+
+static int print_write(const char *path, const void *data, u64 offset,
+		       u64 len, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("write", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("write", full_path, "offset: %llu, len: %llu", offset, len);
+	return 0;
+}
+
+static int print_clone(const char *path, u64 offset, u64 len,
+		       const u8 *clone_uuid, u64 clone_ctransid,
+		       const char *clone_path, u64 clone_offset,
+		       void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("clone", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("clone", full_path, "offset: %llu, len: %llu from: %s, offset: %llu",
+		   offset, len, clone_path, clone_offset);
+	return 0;
+}
+
+static int print_set_xattr(const char *path, const char *name,
+			   const void *data, int len, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("set_xattr", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("set_xattr", full_path, "name: %s, len: %s", name, len);
+	return 0;
+}
+
+static int print_remove_xattr(const char *path, const char *name, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("remove_xattr", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("remove_xattr", full_path, name);
+	return 0;
+}
+
+static int print_truncate(const char *path, u64 size, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("truncate", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("truncate", full_path, "size: %llu", size);
+	return 0;
+}
+
+static int print_chmod(const char *path, u64 mode, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("chmod", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("chmod", full_path, "mode: %llo", mode);
+	return 0;
+}
+
+static int print_chown(const char *path, u64 uid, u64 gid, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("chown", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("chown", full_path, "gid: %llu, uid: %llu", gid, uid);
+	return 0;
+}
+
+static int print_utimes(const char *path, struct timespec *at,
+			struct timespec *mt, struct timespec *ct,
+			void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("utimes", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("utimes", full_path, "");
+	return 0;
+}
+
+static int print_update_extent(const char *path, u64 offset, u64 len,
+			       void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("update_extent", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("update_extent", full_path, "offset: %llu, len: %llu",
+		   offset, len);
+	return 0;
+}
+
+struct btrfs_send_ops btrfs_print_send_ops = {
+	.subvol = print_subvol,
+	.snapshot = print_snapshot,
+	.mkfile = print_mkfile,
+	.mkdir = print_mkdir,
+	.mknod = print_mknod,
+	.mkfifo = print_mkfifo,
+	.mksock = print_mksock,
+	.symlink = print_symlink,
+	.rename = print_rename,
+	.link = print_link,
+	.unlink = print_unlink,
+	.rmdir = print_rmdir,
+	.write = print_write,
+	.clone = print_clone,
+	.set_xattr = print_set_xattr,
+	.remove_xattr = print_remove_xattr,
+	.truncate = print_truncate,
+	.chmod = print_chmod,
+	.chown = print_chown,
+	.utimes = print_utimes,
+	.update_extent = print_update_extent
+};
diff --git a/send-dump.h b/send-dump.h
new file mode 100644
index 0000000..48d821f
--- /dev/null
+++ b/send-dump.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#ifndef __BTRFS_SEND_DUMP_H__
+#define __BTRFS_SEND_DUMP_H__
+struct btrfs_dump_send_args {
+	char *full_subvol_path;
+	char *root_path;
+};
+extern struct btrfs_send_ops btrfs_print_send_ops;
+#endif
-- 
2.9.0




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] btrfs-progs: inspect: Introduce dump-send-stream subcommand
  2016-08-01  6:29 [PATCH 1/3] btrfs-progs: Introduce new send-dump object Qu Wenruo
@ 2016-08-01  6:29 ` Qu Wenruo
  2016-08-01  6:29 ` [PATCH 3/3] btrfs-progs: Remove send-test tool Qu Wenruo
  2016-08-16 14:31 ` [PATCH 1/3] btrfs-progs: Introduce new send-dump object David Sterba
  2 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-08-01  6:29 UTC (permalink / raw)
  To: linux-btrfs

Introduce a new subcommand "dump-send-stream" for "inspect-internal"
command group.

It will exam and output all operations inside a send stream.
It's quite a useful tool to learn and dig kernel send stream.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 Documentation/btrfs-inspect-internal.asciidoc |  8 +++
 Makefile.in                                   |  3 +-
 cmds-inspect-dump-send.c                      | 84 +++++++++++++++++++++++++++
 cmds-inspect-dump-send.h                      | 24 ++++++++
 cmds-inspect.c                                |  3 +
 5 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 cmds-inspect-dump-send.c
 create mode 100644 cmds-inspect-dump-send.h

diff --git a/Documentation/btrfs-inspect-internal.asciidoc b/Documentation/btrfs-inspect-internal.asciidoc
index 74f6dea..8ba768d 100644
--- a/Documentation/btrfs-inspect-internal.asciidoc
+++ b/Documentation/btrfs-inspect-internal.asciidoc
@@ -146,6 +146,14 @@ Print sizes and statistics of trees.
 -b::::
 Print raw numbers in bytes.
 
+*dump-send-stream [options]*::
+exam and output all operations inside a send stream. Read from 'stdin' by default.
++
+`Options`
++
+-f|--file <file>::::
+Read from file instead of 'stdin'.
+
 EXIT STATUS
 -----------
 *btrfs inspect-internal* returns a zero exit status if it succeeds. Non zero is
diff --git a/Makefile.in b/Makefile.in
index 97caf95..00bf639 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -86,7 +86,8 @@ cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
 	       cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
 	       cmds-restore.o cmds-rescue.o chunk-recover.o super-recover.o \
 	       cmds-property.o cmds-fi-usage.o cmds-inspect-dump-tree.o \
-	       cmds-inspect-dump-super.o cmds-inspect-tree-stats.o cmds-fi-du.o
+	       cmds-inspect-dump-super.o cmds-inspect-tree-stats.o \
+	       cmds-fi-du.o cmds-inspect-dump-send.o
 libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \
 		   uuid-tree.o utils-lib.o rbtree-utils.o
 libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \
diff --git a/cmds-inspect-dump-send.c b/cmds-inspect-dump-send.c
new file mode 100644
index 0000000..46a3cd6
--- /dev/null
+++ b/cmds-inspect-dump-send.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "kerncompat.h"
+#include "ctree.h"
+#include "send-dump.h"
+#include "send-stream.h"
+#include "utils.h"
+#include "commands.h"
+
+const char * const cmd_inspect_dump_send_usage[] = {
+	"btrfs inspect-internal dump-send-stream [options]",
+	"Dump the operations of a send stream from stdin",
+	"-f|--file <file>    read send stream from file",
+	"-h|--help           print this message",
+	NULL
+};
+
+int cmd_inspect_dump_send(int argc, char **argv)
+{
+	struct btrfs_dump_send_args dump_args;
+	int fd = 0;
+	int ret;
+
+	while (1) {
+		int c;
+		static const struct option long_options[] = {
+			{ "file", required_argument, NULL, 'f' },
+			{ "help", no_argument, NULL, 'h' },
+			{ NULL, 0, NULL, 0 }
+		};
+
+		c = getopt_long(argc, argv, "f:h", long_options, NULL);
+		if (c < 0)
+			break;
+		switch(c) {
+		case 'f':
+			fd = open(optarg, O_RDONLY, 0666);
+			if (fd < 0) {
+				error("cannot open %s: %s", optarg,
+				      strerror(errno));
+				exit(1);
+			}
+			break;
+		case 'h':
+		default:
+			usage(cmd_inspect_dump_send_usage);
+			break;
+		}
+	}
+	dump_args.root_path = malloc(PATH_MAX);
+	dump_args.root_path[0] = '.';
+	dump_args.root_path[1] = '\0';
+	dump_args.full_subvol_path = malloc(PATH_MAX);
+	dump_args.full_subvol_path[0] = '.';
+	dump_args.full_subvol_path[1] = '\0';
+
+	ret = btrfs_read_and_process_send_stream(fd, &btrfs_print_send_ops,
+			&dump_args, 0, 0);
+	if (ret < 0)
+		error("failed to read the send stream: %s\n", strerror(-ret));
+	close(fd);
+	return ret;
+}
diff --git a/cmds-inspect-dump-send.h b/cmds-inspect-dump-send.h
new file mode 100644
index 0000000..49c8034
--- /dev/null
+++ b/cmds-inspect-dump-send.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#ifndef __CMDS_INSPECT_DUMP_SEND_H__
+#define __CMDS_INSPECT_DUMP_SEND_H__
+
+int cmd_inspect_dump_send(int argc, char **argv);
+
+extern const char * const cmd_inspect_dump_send_usage[];
+
+#endif
diff --git a/cmds-inspect.c b/cmds-inspect.c
index 4b7cea0..98653d5 100644
--- a/cmds-inspect.c
+++ b/cmds-inspect.c
@@ -34,6 +34,7 @@
 #include "cmds-inspect-dump-tree.h"
 #include "cmds-inspect-dump-super.h"
 #include "cmds-inspect-tree-stats.h"
+#include "cmds-inspect-dump-send.h"
 
 static const char * const inspect_cmd_group_usage[] = {
 	"btrfs inspect-internal <command> <args>",
@@ -642,6 +643,8 @@ const struct cmd_group inspect_cmd_group = {
 				cmd_inspect_dump_super_usage, NULL, 0 },
 		{ "tree-stats", cmd_inspect_tree_stats,
 				cmd_inspect_tree_stats_usage, NULL, 0 },
+		{ "dump-send-stream", cmd_inspect_dump_send,
+				cmd_inspect_dump_send_usage, NULL, 0 },
 		NULL_CMD_STRUCT
 	}
 };
-- 
2.9.0




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] btrfs-progs: Remove send-test tool
  2016-08-01  6:29 [PATCH 1/3] btrfs-progs: Introduce new send-dump object Qu Wenruo
  2016-08-01  6:29 ` [PATCH 2/3] btrfs-progs: inspect: Introduce dump-send-stream subcommand Qu Wenruo
@ 2016-08-01  6:29 ` Qu Wenruo
  2016-08-16 14:31 ` [PATCH 1/3] btrfs-progs: Introduce new send-dump object David Sterba
  2 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-08-01  6:29 UTC (permalink / raw)
  To: linux-btrfs

Since new "inspect dump-send" has better output and structure, it's time
to remove old and function-weak send-test tool.

New "inspect dump-send" can handle them all better.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 Makefile.in |   6 +-
 send-test.c | 447 ------------------------------------------------------------
 2 files changed, 1 insertion(+), 452 deletions(-)
 delete mode 100644 send-test.c

diff --git a/Makefile.in b/Makefile.in
index 00bf639..5e4dd57 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -347,10 +347,6 @@ ioctl-test: $(objects) $(libs) ioctl-test.o
 	@echo "    [LD]     $@"
 	$(Q)$(CC) $(CFLAGS) -o ioctl-test $(objects) $(libs) ioctl-test.o $(LDFLAGS) $(LIBS)
 
-send-test: $(objects) $(libs) send-test.o
-	@echo "    [LD]     $@"
-	$(Q)$(CC) $(CFLAGS) -o send-test $(objects) $(libs) send-test.o $(LDFLAGS) $(LIBS)
-
 library-test: $(libs_shared) library-test.o
 	@echo "    [LD]     $@"
 	$(Q)$(CC) $(CFLAGS) -o library-test library-test.o $(LDFLAGS) -lbtrfs
@@ -382,7 +378,7 @@ clean-all: clean clean-doc clean-gen
 clean: $(CLEANDIRS)
 	@echo "Cleaning"
 	$(Q)$(RM) -f $(progs) cscope.out *.o *.o.d \
-	      dir-test ioctl-test quick-test send-test library-test library-test-static \
+	      dir-test ioctl-test quick-test library-test library-test-static \
 	      btrfs.static mkfs.btrfs.static \
 	      $(check_defs) \
 	      $(libs) $(lib_links) \
diff --git a/send-test.c b/send-test.c
deleted file mode 100644
index 4645b89..0000000
--- a/send-test.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2013 SUSE.  All rights reserved.
- *
- * This code is adapted from cmds-send.c and cmds-receive.c,
- * Both of which are:
- *
- * Copyright (C) 2012 Alexander Block.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#include <unistd.h>
-#include <stdint.h>
-#include <dirent.h>
-#include <pthread.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <libgen.h>
-#include <mntent.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <asm/types.h>
-#include <uuid/uuid.h>
-
-/*
- * This should be compilable without the rest of the btrfs-progs
- * source distribution.
- */
-#if BTRFS_FLAT_INCLUDES
-#include "send-utils.h"
-#include "send-stream.h"
-#else
-#include <btrfs/send-utils.h>
-#include <btrfs/send-stream.h>
-#endif /* BTRFS_FLAT_INCLUDES */
-
-static int pipefd[2];
-struct btrfs_ioctl_send_args io_send = {0, };
-static char *subvol_path;
-static char *root_path;
-
-struct recv_args {
-	char *full_subvol_path;
-	char *root_path;
-};
-
-void usage(int error)
-{
-	printf("send-test <btrfs root> <subvol>\n");
-	if (error)
-		exit(error);
-}
-
-static int print_subvol(const char *path, const u8 *uuid, u64 ctransid,
-			void *user)
-{
-	struct recv_args *r = user;
-	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
-
-	r->full_subvol_path = path_cat(r->root_path, path);
-	uuid_unparse(uuid, uuid_str);
-
-	printf("subvol\t%s\t%llu\t%s\n", uuid_str,
-	       (unsigned long long)ctransid, r->full_subvol_path);
-
-	return 0;
-}
-
-static int print_snapshot(const char *path, const u8 *uuid, u64 ctransid,
-			  const u8 *parent_uuid, u64 parent_ctransid,
-			  void *user)
-{
-	struct recv_args *r = user;
-	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
-	char parent_uuid_str[BTRFS_UUID_UNPARSED_SIZE];
-
-	r->full_subvol_path = path_cat(r->root_path, path);
-	uuid_unparse(uuid, uuid_str);
-	uuid_unparse(parent_uuid, parent_uuid_str);
-
-	printf("snapshot\t%s\t%llu\t%s\t%llu\t%s\n", uuid_str,
-	       (unsigned long long)ctransid, parent_uuid_str,
-	       (unsigned long long)parent_ctransid, r->full_subvol_path);
-
-	return 0;
-}
-
-static int print_mkfile(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("mkfile\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_mkdir(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("mkdir\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_mknod(const char *path, u64 mode, u64 dev, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("mknod\t%llo\t0x%llx\t%s\n", (unsigned long long)mode,
-	       (unsigned long long)dev, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_mkfifo(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("mkfifo\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_mksock(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("mksock\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_symlink(const char *path, const char *lnk, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("symlink\t%s\t%s\n", lnk, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_rename(const char *from, const char *to, void *user)
-{
-	struct recv_args *r = user;
-	char *full_from = path_cat(r->full_subvol_path, from);
-	char *full_to = path_cat(r->full_subvol_path, to);
-
-	printf("rename\t%s\t%s\n", from, to);
-
-	free(full_from);
-	free(full_to);
-	return 0;
-}
-
-static int print_link(const char *path, const char *lnk, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("link\t%s\t%s\n", lnk, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_unlink(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("unlink\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_rmdir(const char *path, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("rmdir\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_write(const char *path, const void *data, u64 offset,
-		       u64 len, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("write\t%llu\t%llu\t%s\n", (unsigned long long)offset,
-	       (unsigned long long)len, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_clone(const char *path, u64 offset, u64 len,
-		       const u8 *clone_uuid, u64 clone_ctransid,
-		       const char *clone_path, u64 clone_offset,
-		       void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("clone\t%s\t%s\n", full_path, clone_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_set_xattr(const char *path, const char *name,
-			   const void *data, int len, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("set_xattr\t%s\t%s\t%d\n", full_path,
-	       name, len);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_remove_xattr(const char *path, const char *name, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("remove_xattr\t%s\t%s\n", full_path, name);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_truncate(const char *path, u64 size, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("truncate\t%llu\t%s\n", (unsigned long long)size, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_chmod(const char *path, u64 mode, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("chmod\t%llo\t%s\n", (unsigned long long)mode, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_chown(const char *path, u64 uid, u64 gid, void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("chown\t%llu\t%llu\t%s\n", (unsigned long long)uid,
-	       (unsigned long long)gid, full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_utimes(const char *path, struct timespec *at,
-			struct timespec *mt, struct timespec *ct,
-			void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("utimes\t%s\n", full_path);
-
-	free(full_path);
-	return 0;
-}
-
-static int print_update_extent(const char *path, u64 offset, u64 len,
-			       void *user)
-{
-	struct recv_args *r = user;
-	char *full_path = path_cat(r->full_subvol_path, path);
-
-	printf("update_extent\t%s\t%llu\t%llu\n", full_path, offset, len);
-
-	free(full_path);
-	return 0;
-}
-
-static struct btrfs_send_ops send_ops_print = {
-	.subvol = print_subvol,
-	.snapshot = print_snapshot,
-	.mkfile = print_mkfile,
-	.mkdir = print_mkdir,
-	.mknod = print_mknod,
-	.mkfifo = print_mkfifo,
-	.mksock = print_mksock,
-	.symlink = print_symlink,
-	.rename = print_rename,
-	.link = print_link,
-	.unlink = print_unlink,
-	.rmdir = print_rmdir,
-	.write = print_write,
-	.clone = print_clone,
-	.set_xattr = print_set_xattr,
-	.remove_xattr = print_remove_xattr,
-	.truncate = print_truncate,
-	.chmod = print_chmod,
-	.chown = print_chown,
-	.utimes = print_utimes,
-	.update_extent = print_update_extent,
-};
-
-static void *process_thread(void *arg_)
-{
-	int ret;
-
-	while (1) {
-		ret = btrfs_read_and_process_send_stream(pipefd[0],
-							 &send_ops_print, arg_, 0);
-		if (ret)
-			break;
-	}
-
-	if (ret > 0)
-		ret = 0;
-
-	return ERR_PTR(ret);
-}
-
-int main(int argc, char **argv)
-{
-	int ret = 0;
-	int subvol_fd;
-	pthread_t t_read;
-	void *t_err = NULL;
-	struct recv_args r;
-
-	if (argc != 3)
-		usage(EINVAL);
-
-	root_path = realpath(argv[1], NULL);
-	if (!root_path) {
-		ret = errno;
-		usage(ret);
-	}
-
-	subvol_path = realpath(argv[2], NULL);
-	if (!subvol_path) {
-		ret = errno;
-		usage(ret);
-	}
-
-	r.full_subvol_path = subvol_path;
-	r.root_path = root_path;
-
-	subvol_fd = open(subvol_path, O_RDONLY|O_NOATIME);
-	if (subvol_fd < 0) {
-		ret = errno;
-		fprintf(stderr, "ERROR: Subvolume open failed. %s\n",
-			strerror(ret));
-		goto out;
-	}
-
-	ret = pipe(pipefd);
-	if (ret < 0) {
-		ret = errno;
-		fprintf(stderr, "ERROR: pipe failed. %s\n", strerror(ret));
-		goto out;
-	}
-
-	ret = pthread_create(&t_read, NULL, process_thread, &r);
-	if (ret < 0) {
-		ret = errno;
-		fprintf(stderr, "ERROR: pthread create failed. %s\n",
-			strerror(ret));
-		goto out;
-	}
-
-	io_send.send_fd = pipefd[1];
-	io_send.clone_sources_count = 0;
-	io_send.clone_sources = NULL;
-	io_send.parent_root = 0;
-	io_send.flags = BTRFS_SEND_FLAG_NO_FILE_DATA;
-
-	ret = ioctl(subvol_fd, BTRFS_IOC_SEND, &io_send);
-	if (ret < 0) {
-		ret = errno;
-		fprintf(stderr, "ERROR: send ioctl failed with %d: %s\n", ret,
-			strerror(ret));
-		goto out;
-	}
-
-	close(pipefd[1]);
-
-	ret = pthread_join(t_read, &t_err);
-	if (ret) {
-		fprintf(stderr, "ERROR: pthread_join failed: %s\n",
-			strerror(ret));
-		goto out;
-	}
-	if (t_err) {
-		ret = (long int)t_err;
-		fprintf(stderr, "ERROR: failed to process send stream, ret=%ld "
-			"(%s)\n", (long int)t_err, strerror(ret));
-		goto out;
-	}
-
-out:
-	return !!ret;
-}
-- 
2.9.0




^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-08-01  6:29 [PATCH 1/3] btrfs-progs: Introduce new send-dump object Qu Wenruo
  2016-08-01  6:29 ` [PATCH 2/3] btrfs-progs: inspect: Introduce dump-send-stream subcommand Qu Wenruo
  2016-08-01  6:29 ` [PATCH 3/3] btrfs-progs: Remove send-test tool Qu Wenruo
@ 2016-08-16 14:31 ` David Sterba
  2016-08-17  0:42   ` Qu Wenruo
  2 siblings, 1 reply; 9+ messages in thread
From: David Sterba @ 2016-08-16 14:31 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Mon, Aug 01, 2016 at 02:29:42PM +0800, Qu Wenruo wrote:
> Introduce send-dump.[ch] which implements a new btrfs_send_ops to
> exam and output all operations inside a send stream.
> 
> It has a better output format than the old and no longer compilable
> send-test tool, but still tries to be script friendly.
> 
> Provides the basis for later "inspect-internal dump-send" command.

I'd rather put that into the receive subcommand, as it takes the stream
as argument and it's closer to the send/receive commands, but that's
a minor thing.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-08-16 14:31 ` [PATCH 1/3] btrfs-progs: Introduce new send-dump object David Sterba
@ 2016-08-17  0:42   ` Qu Wenruo
  2016-08-17 11:38     ` David Sterba
  2016-08-24 12:49     ` David Sterba
  0 siblings, 2 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-08-17  0:42 UTC (permalink / raw)
  To: dsterba, linux-btrfs



At 08/16/2016 10:31 PM, David Sterba wrote:
> On Mon, Aug 01, 2016 at 02:29:42PM +0800, Qu Wenruo wrote:
>> Introduce send-dump.[ch] which implements a new btrfs_send_ops to
>> exam and output all operations inside a send stream.
>>
>> It has a better output format than the old and no longer compilable
>> send-test tool, but still tries to be script friendly.
>>
>> Provides the basis for later "inspect-internal dump-send" command.
>
> I'd rather put that into the receive subcommand, as it takes the stream
> as argument and it's closer to the send/receive commands, but that's
> a minor thing.
>
>
I'm OK to put it into receive command.

Although unlike normal receive usage, it doesn't need the <path> 
parameter, and make <path> to be optional.

If it's fine to you, then I can update the patchset to merge it into 
receive subcommand.

Thanks,
Qu



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-08-17  0:42   ` Qu Wenruo
@ 2016-08-17 11:38     ` David Sterba
  2016-08-24 12:49     ` David Sterba
  1 sibling, 0 replies; 9+ messages in thread
From: David Sterba @ 2016-08-17 11:38 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs

On Wed, Aug 17, 2016 at 08:42:48AM +0800, Qu Wenruo wrote:
> 
> 
> At 08/16/2016 10:31 PM, David Sterba wrote:
> > On Mon, Aug 01, 2016 at 02:29:42PM +0800, Qu Wenruo wrote:
> >> Introduce send-dump.[ch] which implements a new btrfs_send_ops to
> >> exam and output all operations inside a send stream.
> >>
> >> It has a better output format than the old and no longer compilable
> >> send-test tool, but still tries to be script friendly.
> >>
> >> Provides the basis for later "inspect-internal dump-send" command.
> >
> > I'd rather put that into the receive subcommand, as it takes the stream
> > as argument and it's closer to the send/receive commands, but that's
> > a minor thing.
> >
> >
> I'm OK to put it into receive command.
> 
> Although unlike normal receive usage, it doesn't need the <path> 
> parameter, and make <path> to be optional.
> 
> If it's fine to you, then I can update the patchset to merge it into 
> receive subcommand.

Hold on, I want to go through the whole patchset still.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-08-17  0:42   ` Qu Wenruo
  2016-08-17 11:38     ` David Sterba
@ 2016-08-24 12:49     ` David Sterba
  2016-09-06  2:08       ` Qu Wenruo
  1 sibling, 1 reply; 9+ messages in thread
From: David Sterba @ 2016-08-24 12:49 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: dsterba, linux-btrfs

On Wed, Aug 17, 2016 at 08:42:48AM +0800, Qu Wenruo wrote:
> 
> 
> At 08/16/2016 10:31 PM, David Sterba wrote:
> > On Mon, Aug 01, 2016 at 02:29:42PM +0800, Qu Wenruo wrote:
> >> Introduce send-dump.[ch] which implements a new btrfs_send_ops to
> >> exam and output all operations inside a send stream.
> >>
> >> It has a better output format than the old and no longer compilable
> >> send-test tool, but still tries to be script friendly.
> >>
> >> Provides the basis for later "inspect-internal dump-send" command.
> >
> > I'd rather put that into the receive subcommand, as it takes the stream
> > as argument and it's closer to the send/receive commands, but that's
> > a minor thing.
> >
> >
> I'm OK to put it into receive command.
> 
> Although unlike normal receive usage, it doesn't need the <path> 
> parameter, and make <path> to be optional.

That's a good point and would make the syntax work in two modes, but we
do that in ohter commands and I hope it will not be confusing. Exmaples:

Normal receive:

 btrfs receive -f file /mount

Dump the stream:

 btrs receive --dump -f file

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-08-24 12:49     ` David Sterba
@ 2016-09-06  2:08       ` Qu Wenruo
  0 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-09-06  2:08 UTC (permalink / raw)
  To: dsterba, linux-btrfs



At 08/24/2016 08:49 PM, David Sterba wrote:
> On Wed, Aug 17, 2016 at 08:42:48AM +0800, Qu Wenruo wrote:
>>
>>
>> At 08/16/2016 10:31 PM, David Sterba wrote:
>>> On Mon, Aug 01, 2016 at 02:29:42PM +0800, Qu Wenruo wrote:
>>>> Introduce send-dump.[ch] which implements a new btrfs_send_ops to
>>>> exam and output all operations inside a send stream.
>>>>
>>>> It has a better output format than the old and no longer compilable
>>>> send-test tool, but still tries to be script friendly.
>>>>
>>>> Provides the basis for later "inspect-internal dump-send" command.
>>>
>>> I'd rather put that into the receive subcommand, as it takes the stream
>>> as argument and it's closer to the send/receive commands, but that's
>>> a minor thing.
>>>
>>>
>> I'm OK to put it into receive command.
>>
>> Although unlike normal receive usage, it doesn't need the <path>
>> parameter, and make <path> to be optional.
>
> That's a good point and would make the syntax work in two modes, but we
> do that in ohter commands and I hope it will not be confusing. Exmaples:
>
> Normal receive:
>
>  btrfs receive -f file /mount
>
> Dump the stream:
>
>  btrs receive --dump -f file

Sorry for the late reply.

I'm OK for the new syntax.

If no other problem I'll begin to change the syntax and rebase it to devel.

Thanks,
Qu



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] btrfs-progs: Introduce new send-dump object
  2016-09-07  0:29 [PATCH 0/3] Introduce dump option for btrfs-receive Qu Wenruo
@ 2016-09-07  0:29 ` Qu Wenruo
  0 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2016-09-07  0:29 UTC (permalink / raw)
  To: linux-btrfs

Introduce send-dump.[ch] which implements a new btrfs_send_ops to
exam and output all operations inside a send stream.

It has a better output format than the old and no longer compilable
send-test tool, but still tries to be script friendly.

Provides the basis for later "inspect-internal dump-send" command.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 Makefile.in |   2 +-
 send-dump.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 send-dump.h |  24 ++++
 3 files changed, 392 insertions(+), 1 deletion(-)
 create mode 100644 send-dump.c
 create mode 100644 send-dump.h

diff --git a/Makefile.in b/Makefile.in
index ac6b353..97caf95 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
 	  extent-cache.o extent_io.o volumes.o utils.o repair.o \
 	  qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
 	  ulist.o qgroup-verify.o backref.o string-table.o task-utils.o \
-	  inode.o file.o find-root.o free-space-tree.o help.o
+	  inode.o file.o find-root.o free-space-tree.o help.o send-dump.o
 cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
 	       cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
 	       cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
diff --git a/send-dump.c b/send-dump.c
new file mode 100644
index 0000000..bf451c7
--- /dev/null
+++ b/send-dump.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#include <unistd.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <libgen.h>
+#include <mntent.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <asm/types.h>
+#include <uuid/uuid.h>
+#include "utils.h"
+#include "commands.h"
+#include "send-utils.h"
+#include "send-stream.h"
+#include "send-dump.h"
+
+#define path_cat_out_with_error(function_name, out_path, path1, path2, ret) \
+ret = path_cat_out(out_path, path1, path2);			\
+if (ret < 0) {							\
+	error("%s: path invalid: %s\n", function_name, path2);	\
+	return ret;						\
+}
+
+#define TITLE_WIDTH	16
+#define PATH_WIDTH	32
+
+static void print_dump(const char *title, const char *path,
+	  	       const char *fmt, ...)
+{
+	va_list args;
+	char real_title[TITLE_WIDTH + 1];
+
+	real_title[0]='\0';
+	/* Append ':' to title*/
+	strncpy(real_title, title, TITLE_WIDTH - 1);
+	strncat(real_title, ":", TITLE_WIDTH);
+
+	/* Unified output */
+	printf("%-*s%-*s", TITLE_WIDTH, real_title, PATH_WIDTH, path);
+	va_start(args, fmt);
+	/* Command specified output */
+	vprintf(fmt, args);
+	va_end(args);
+	printf("\n");
+}
+
+static int print_subvol(const char *path, const u8 *uuid, u64 ctransid,
+			void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	int ret;
+
+	path_cat_out_with_error("subvol", r->full_subvol_path, r->root_path,
+				path, ret);
+	uuid_unparse(uuid, uuid_str);
+
+	print_dump("subvol", r->full_subvol_path, "uuid: %s, transid: %llu",
+		   uuid_str, ctransid);
+	return 0;
+}
+
+static int print_snapshot(const char *path, const u8 *uuid, u64 ctransid,
+			  const u8 *parent_uuid, u64 parent_ctransid,
+			  void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	char parent_uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+	int ret;
+
+	path_cat_out_with_error("snapshot", r->full_subvol_path, r->root_path,
+				path, ret);
+	uuid_unparse(uuid, uuid_str);
+	uuid_unparse(parent_uuid, parent_uuid_str);
+
+	print_dump("snapshot", r->full_subvol_path,
+		   "uuid: %s, transid: %llu, parent_uuid: %s, parent_transid: %llu",
+		   uuid_str, ctransid, parent_uuid_str, parent_ctransid);
+	return 0;
+}
+
+static int print_mkfile(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkfile", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkfile", full_path, "");
+	return 0;
+}
+
+static int print_mkdir(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkdir", full_path, "");
+	return 0;
+}
+
+static int print_mknod(const char *path, u64 mode, u64 dev, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mknod", full_path, "mode: %llo, dev: 0x%llx", mode, dev);
+	return 0;
+}
+
+static int print_mkfifo(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mkfifo", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mkfifo", full_path, "");
+	return 0;
+}
+
+static int print_mksock(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("mksock", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("mksock", full_path, "");
+	return 0;
+}
+
+static int print_symlink(const char *path, const char *lnk, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("symlink", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("symlink", full_path, "lnk: %s", lnk);
+	return 0;
+}
+
+static int print_rename(const char *from, const char *to, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_from[PATH_MAX];
+	char full_to[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("rename", full_from, r->full_subvol_path, from,
+				ret);
+	path_cat_out_with_error("rename", full_to, r->full_subvol_path, to,
+				ret);
+	print_dump("rename", full_from, "to %s", full_to);
+	return 0;
+}
+
+static int print_link(const char *path, const char *lnk, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("link", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("link", full_path, "lnk: %s", lnk);
+	return 0;
+}
+
+static int print_unlink(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("unlink", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("unlink", full_path, "");
+	return 0;
+}
+
+static int print_rmdir(const char *path, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("rmdir", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("rmdir", full_path, "");
+	return 0;
+}
+
+static int print_write(const char *path, const void *data, u64 offset,
+		       u64 len, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("write", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("write", full_path, "offset: %llu, len: %llu", offset, len);
+	return 0;
+}
+
+static int print_clone(const char *path, u64 offset, u64 len,
+		       const u8 *clone_uuid, u64 clone_ctransid,
+		       const char *clone_path, u64 clone_offset,
+		       void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("clone", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("clone", full_path, "offset: %llu, len: %llu from: %s, offset: %llu",
+		   offset, len, clone_path, clone_offset);
+	return 0;
+}
+
+static int print_set_xattr(const char *path, const char *name,
+			   const void *data, int len, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("set_xattr", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("set_xattr", full_path, "name: %s, len: %s", name, len);
+	return 0;
+}
+
+static int print_remove_xattr(const char *path, const char *name, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("remove_xattr", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("remove_xattr", full_path, name);
+	return 0;
+}
+
+static int print_truncate(const char *path, u64 size, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("truncate", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("truncate", full_path, "size: %llu", size);
+	return 0;
+}
+
+static int print_chmod(const char *path, u64 mode, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("chmod", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("chmod", full_path, "mode: %llo", mode);
+	return 0;
+}
+
+static int print_chown(const char *path, u64 uid, u64 gid, void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("chown", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("chown", full_path, "gid: %llu, uid: %llu", gid, uid);
+	return 0;
+}
+
+static int print_utimes(const char *path, struct timespec *at,
+			struct timespec *mt, struct timespec *ct,
+			void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("utimes", full_path, r->full_subvol_path, path,
+				ret);
+	print_dump("utimes", full_path, "");
+	return 0;
+}
+
+static int print_update_extent(const char *path, u64 offset, u64 len,
+			       void *user)
+{
+	struct btrfs_dump_send_args *r = user;
+	char full_path[PATH_MAX];
+	int ret;
+
+	path_cat_out_with_error("update_extent", full_path, r->full_subvol_path,
+				path, ret);
+	print_dump("update_extent", full_path, "offset: %llu, len: %llu",
+		   offset, len);
+	return 0;
+}
+
+struct btrfs_send_ops btrfs_print_send_ops = {
+	.subvol = print_subvol,
+	.snapshot = print_snapshot,
+	.mkfile = print_mkfile,
+	.mkdir = print_mkdir,
+	.mknod = print_mknod,
+	.mkfifo = print_mkfifo,
+	.mksock = print_mksock,
+	.symlink = print_symlink,
+	.rename = print_rename,
+	.link = print_link,
+	.unlink = print_unlink,
+	.rmdir = print_rmdir,
+	.write = print_write,
+	.clone = print_clone,
+	.set_xattr = print_set_xattr,
+	.remove_xattr = print_remove_xattr,
+	.truncate = print_truncate,
+	.chmod = print_chmod,
+	.chown = print_chown,
+	.utimes = print_utimes,
+	.update_extent = print_update_extent
+};
diff --git a/send-dump.h b/send-dump.h
new file mode 100644
index 0000000..48d821f
--- /dev/null
+++ b/send-dump.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Fujitsu.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ */
+
+#ifndef __BTRFS_SEND_DUMP_H__
+#define __BTRFS_SEND_DUMP_H__
+struct btrfs_dump_send_args {
+	char *full_subvol_path;
+	char *root_path;
+};
+extern struct btrfs_send_ops btrfs_print_send_ops;
+#endif
-- 
2.9.3




^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-09-07  0:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-01  6:29 [PATCH 1/3] btrfs-progs: Introduce new send-dump object Qu Wenruo
2016-08-01  6:29 ` [PATCH 2/3] btrfs-progs: inspect: Introduce dump-send-stream subcommand Qu Wenruo
2016-08-01  6:29 ` [PATCH 3/3] btrfs-progs: Remove send-test tool Qu Wenruo
2016-08-16 14:31 ` [PATCH 1/3] btrfs-progs: Introduce new send-dump object David Sterba
2016-08-17  0:42   ` Qu Wenruo
2016-08-17 11:38     ` David Sterba
2016-08-24 12:49     ` David Sterba
2016-09-06  2:08       ` Qu Wenruo
2016-09-07  0:29 [PATCH 0/3] Introduce dump option for btrfs-receive Qu Wenruo
2016-09-07  0:29 ` [PATCH 1/3] btrfs-progs: Introduce new send-dump object Qu Wenruo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.