[RFC PATCH 5/5] btrfs-progs: let this feature works at subvolume command group.
From: Jeff Liu <hidden>
Date: 2012-08-07 08:58:46
Subsystem:
the rest · Maintainer:
Linus Torvalds
make this feature works as `btrfs subvolume diff-snapshot [options] <src> <dest>`. Signed-off-by: Jie Liu <redacted> --- cmds-subvolume.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 3508ce6..e7cc3cc 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c@@ -28,6 +28,7 @@ #include "ioctl.h" #include "commands.h" +#include "diff-snapshot.h" /* btrfs-list.c */ int list_subvols(int fd, int print_parent, int get_default);
@@ -515,6 +516,94 @@ static int cmd_find_new(int argc, char **argv) return 0; } +static const char * const cmd_snapshot_diff_usage[] = { + "btrfs subvolume diff-snapshot [options] <source> <dest>", + "List the differences between two snapshots", + "By default, list all changes in destination snapshot towards source", + "", + "-n list the new items in destination snapshot\n", + "-r list the removed items in destination snapshot\n", + "-u list the updated items in destination snapshot\n", + NULL +}; + +static int cmd_snapshot_diff(int argc, char **argv) +{ + int ret; + int src_fd; + int dst_fd; + char *src_snapshot; + char *dest_snapshot; + unsigned int flags = 0; + + while (1) { + int c = getopt(argc, argv, "rnu"); + if (c < 0) + break; + switch (c) { + case 'r': + flags |= SNAPSHOT_DIFF_LIST_REMOVED_ITEM; + break; + case 'n': + flags |= SNAPSHOT_DIFF_LIST_NEW_ITEM; + break; + case 'u': + flags |= SNAPSHOT_DIFF_LIST_UPDATED_ITEM; + break; + default: + fprintf(stderr, "ERROR: snapshot diff args invalid.\n" + " -r list removed items\n" + " -n list new items\n" + " -u list updated items\n"); + return 1; + } + } + + src_snapshot = argv[argc - 2]; + dest_snapshot = argv[argc - 1]; + + ret = test_issubvolume(src_snapshot); + if (ret < 0) { + fprintf(stderr, "ERROR: error accessing '%s'\n", + src_snapshot); + return 12; + } + if (!ret) { + fprintf(stderr, "ERROR: '%s' is not a subvolume\n", + src_snapshot); + return 13; + } + + ret = test_issubvolume(dest_snapshot); + if (ret < 0) { + fprintf(stderr, "ERROR: error accessing '%s'\n", + dest_snapshot); + return 12; + } + if (!ret) { + fprintf(stderr, "ERROR: '%s' is not a subvolume\n", + dest_snapshot); + return 13; + } + + src_fd = open_file_or_dir(src_snapshot); + if (src_fd < 0) { + fprintf(stderr, "ERROR: can't access '%s'\n", src_snapshot); + return 12; + } + + dst_fd = open_file_or_dir(dest_snapshot); + if (dst_fd < 0) { + fprintf(stderr, "ERROR: can't access '%s'\n", dest_snapshot); + return 12; + } + + ret = snapshot_diff(src_fd, dst_fd, src_snapshot, dest_snapshot, flags); + if (ret) + return 19; + return 0; +} + const struct cmd_group subvolume_cmd_group = { subvolume_cmd_group_usage, NULL, { { "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -526,6 +615,7 @@ const struct cmd_group subvolume_cmd_group = { { "set-default", cmd_subvol_set_default, cmd_subvol_set_default_usage, NULL, 0 }, { "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 }, + { "diff-snapshot", cmd_snapshot_diff, cmd_snapshot_diff_usage, NULL, 0 }, { 0, 0, 0, 0, 0 } } };
--
1.7.4.1