All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 1/3] btrfs-progs: Introduce new send-dump object
Date: Mon,  1 Aug 2016 14:29:42 +0800	[thread overview]
Message-ID: <20160801062944.25355-1-quwenruo@cn.fujitsu.com> (raw)

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




             reply	other threads:[~2016-08-01  6:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-01  6:29 Qu Wenruo [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160801062944.25355-1-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.