@@ -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 }
}
};
make this feature works as `btrfs subvolume diff-snapshot [options] <src> <dest>`. Signed-off-by: Jie Liu <jeff.liu@oracle.com> --- cmds-subvolume.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 90 insertions(+), 0 deletions(-)