linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 11/11] Btrfs-progs: add show to display all known parameters of the given subvol
Date: Thu, 10 Jan 2013 19:41:23 +0800	[thread overview]
Message-ID: <1357818083-15531-12-git-send-email-anand.jain@oracle.com> (raw)
In-Reply-To: <1357818083-15531-1-git-send-email-anand.jain@oracle.com>

This adds show sub-command to the btrfs subvol, which is to display
all known parameters of the given subvol or snapshot. This command
will also list out snapshots of the given subvol if there is any.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 btrfs-list.c     |   25 ++++++++-
 btrfs-list.h     |    3 +-
 cmds-subvolume.c |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 man/btrfs.8.in   |    6 ++
 4 files changed, 175 insertions(+), 7 deletions(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 844788b..309f99a 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1348,6 +1348,22 @@ static void print_subvolume_column(struct root_info *subv,
 	}
 }
 
+static void print_single_volume_info_raw(struct root_info *subv, char *raw_prefix)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_LIST_ALL; i++) {
+		if (!btrfs_list_columns[i].need_print)
+			continue;
+
+		if(raw_prefix);
+			printf("%s",raw_prefix);
+
+		print_subvolume_column(subv, i);
+	}
+	printf("\n");
+}
+
 static void print_single_volume_info_table(struct root_info *subv)
 {
 	int i;
@@ -1414,7 +1430,7 @@ static void print_all_volume_info_tab_head()
 }
 
 static void print_all_volume_info(struct root_lookup *sorted_tree,
-				  int layout)
+				  int layout, char *raw_prefix)
 {
 	struct rb_node *n;
 	struct root_info *entry;
@@ -1432,6 +1448,9 @@ static void print_all_volume_info(struct root_lookup *sorted_tree,
 		case BTRFS_LIST_LAYOUT_TABLE:
 			print_single_volume_info_table(entry);
 			break;
+		case BTRFS_LIST_LAYOUT_RAW:
+			print_single_volume_info_raw(entry, raw_prefix);
+			break;
 		}
 		n = rb_next(n);
 	}
@@ -1458,7 +1477,7 @@ int btrfs_list_subvols(int fd, struct root_lookup *root_lookup)
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-		       int layout)
+		       int layout, char *raw_prefix)
 {
 	struct root_lookup root_lookup;
 	struct root_lookup root_sort;
@@ -1470,7 +1489,7 @@ int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 	__filter_and_sort_subvol(&root_lookup, &root_sort, filter_set,
 				 comp_set, fd);
 
-	print_all_volume_info(&root_sort, layout);
+	print_all_volume_info(&root_sort, layout, raw_prefix);
 	__free_all_subvolumn(&root_lookup);
 
 	return 0;
diff --git a/btrfs-list.h b/btrfs-list.h
index 5f3febd..fee7c5b 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -20,6 +20,7 @@
 
 #define BTRFS_LIST_LAYOUT_DEFAULT	0
 #define BTRFS_LIST_LAYOUT_TABLE		1
+#define BTRFS_LIST_LAYOUT_RAW		2
 
 /*
  * one of these for each root we find.
@@ -150,7 +151,7 @@ int btrfs_list_setup_comparer(struct btrfs_list_comparer_set **comp_set,
 
 int btrfs_list_subvols_print(int fd, struct btrfs_list_filter_set *filter_set,
 		       struct btrfs_list_comparer_set *comp_set,
-			int is_tab_result);
+			int layout, char *raw_prefix);
 int btrfs_list_find_updated_files(int fd, u64 root_id, u64 oldest_gen);
 int btrfs_list_get_default_subvolume(int fd, u64 *default_id);
 char *btrfs_list_path_for_root(int fd, u64 root);
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index dd677f7..808a7da 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -24,6 +24,7 @@
 #include <libgen.h>
 #include <limits.h>
 #include <getopt.h>
+#include <uuid/uuid.h>
 
 #include "kerncompat.h"
 #include "ioctl.h"
@@ -418,10 +419,10 @@ static int cmd_subvol_list(int argc, char **argv)
 
 	if (is_tab_result)
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_TABLE);
+				BTRFS_LIST_LAYOUT_TABLE, NULL);
 	else
 		ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
-				BTRFS_LIST_LAYOUT_DEFAULT);
+				BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -634,7 +635,7 @@ static int cmd_subvol_get_default(int argc, char **argv)
 	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
 
 	ret = btrfs_list_subvols_print(fd, filter_set, NULL,
-		BTRFS_LIST_LAYOUT_DEFAULT);
+		BTRFS_LIST_LAYOUT_DEFAULT, NULL);
 	if (ret)
 		return 19;
 	return 0;
@@ -721,6 +722,146 @@ static int cmd_find_new(int argc, char **argv)
 	return 0;
 }
 
+static const char * const cmd_subvol_show_usage[] = {
+	"btrfs subvolume show <subvol-path>",
+	"Show more information of the subvolume",
+	NULL
+};
+
+static int cmd_subvol_show(int argc, char **argv)
+{
+	int ret, fd;
+	char *subvol, *mnt = NULL;
+	struct root_info get_ri;
+	char tstr[256];
+	char uuidparse[37];
+	struct btrfs_list_filter_set *filter_set;
+	char raw_prefix[] = "\t\t\t\t";
+
+	if (check_argc_exact(argc, 2))
+		usage(cmd_subvol_show_usage);
+
+	subvol = realpath(argv[1],0);
+	if(!subvol) {
+		fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
+			argv[1], strerror(errno));
+		return 12;
+	}
+
+	ret = test_issubvolume(subvol);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: error accessing '%s'\n", subvol);
+		free(subvol);
+		return 12;
+	}
+	if (!ret) {
+		fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol);
+		free(subvol);
+		return 13;
+	}
+
+	ret = find_mount_root(subvol, &mnt);
+	if (ret < 0) {
+		fprintf(stderr, "ERROR: find_mount_root failed on %s: "
+				"%s\n", subvol, strerror(-ret));
+		free(subvol);
+		return 12;
+	}
+	if (!strcmp(subvol, mnt))
+		return 0;
+
+	/* this will point to after the mnt/" */
+	get_ri.full_path = subvol+strlen(mnt)+1;
+
+	if (!strcmp(get_ri.full_path, ""))
+		return 0;
+
+	fd = open_file_or_dir(mnt);
+	if (fd < 0) {
+		fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
+		return 12;
+	}
+
+	if (btrfs_get_subvol(fd, &get_ri)) {
+		fprintf(stderr, "ERROR: can't find '%s'\n",
+			get_ri.full_path);
+		close(fd);
+		return 13;
+	}
+
+	/* print the info */
+	printf("%s/%s", mnt, get_ri.full_path);
+	printf("\n");
+
+	if (uuid_is_null(get_ri.uuid))
+		strcpy(uuidparse, "-");
+	else
+		uuid_unparse(get_ri.uuid, uuidparse);
+	printf("\t");
+	printf("uuid: \t\t\t%s", uuidparse);
+	printf("\n");
+
+        if (uuid_is_null(get_ri.puuid))
+                strcpy(uuidparse, "-");
+        else
+                uuid_unparse(get_ri.puuid, uuidparse);
+	printf("\t");
+	printf("Parent uuid: \t\t%s", uuidparse);
+	printf("\n");
+
+	if (get_ri.otime)
+		strftime(tstr, 256, "%Y-%m-%d %X",
+			 localtime(&get_ri.otime));
+	else
+		strcpy(tstr, "-");
+	printf("\t");
+	printf("Creation time: \t\t%s", tstr);
+	printf("\n");
+
+	printf("\t");
+	printf("Object ID: \t\t%llu", get_ri.root_id);
+	printf("\n");
+
+	printf("\t");
+	printf("Generation (Gen): \t%llu", get_ri.gen);
+	printf("\n");
+
+	printf("\t");
+	printf("Gen at creation: \t%llu", get_ri.ogen);
+	printf("\n");
+
+	printf("\t");
+	printf("Parent: \t\t%llu", get_ri.ref_tree);
+	printf("\n");
+
+	printf("\t");
+	printf("Top Level: \t\t%llu", get_ri.top_id);
+	printf("\n");
+
+	/* print the snapshots of the given subvol if any*/
+	printf("\t");
+	printf("Snapshot(s):\n");
+	filter_set = btrfs_list_alloc_filter_set();
+	btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
+				get_ri.uuid);
+	btrfs_list_setup_print_column(BTRFS_LIST_PATH);
+	btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
+			raw_prefix);
+
+	/* clean up */
+	if (get_ri.path)
+		free(get_ri.path);
+	if (get_ri.name)
+		free(get_ri.name);
+	if (get_ri.full_path)
+		free(get_ri.full_path);
+
+	close(fd);
+	free(mnt);
+	free(subvol);
+	return 0;
+}
+
 const struct cmd_group subvolume_cmd_group = {
 	subvolume_cmd_group_usage, NULL, {
 		{ "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
@@ -732,6 +873,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 },
+		{ "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
 		{ 0, 0, 0, 0, 0 }
 	}
 };
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 9222580..57c25b0 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -17,6 +17,8 @@ btrfs \- control a btrfs filesystem
 .PP
 \fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
 .PP
+\fBbtrfs\fP \fBsubvolume show\fP\fI <path>\fP
+.PP
 \fBbtrfs\fP \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] \
 [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> \
 [<\fIfile\fR>|<\fIdir\fR>...]
@@ -160,6 +162,10 @@ Get the default subvolume of the filesystem \fI<path>\fR. The output format
 is similar to \fBsubvolume list\fR command.
 .TP
 
+\fBsubvolume show\fR\fI <path>\fR
+Show information of a given subvolume in the \fI<path>\fR.
+.TP
+
 \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \
 [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
 
-- 
1.7.1


  parent reply	other threads:[~2013-01-10 11:35 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-28  3:12 [PATCH 0/8 v2] add show command to the subvol sub command Anand jain
2012-12-28  3:12 ` [PATCH 1/8] Btrfs-progs: move open_file_or_dir() to utils.c Anand jain
2012-12-28  3:12 ` [PATCH 2/8] Btrfs-progs: Move printing outside of btrfs_list_subvols Anand jain
2012-12-28  3:12 ` [PATCH 3/8] Btrfs-progs: add parent uuid for snapshots Anand jain
2012-12-28  3:12 ` [PATCH 4/8] Btrfs-progs: move struct root_info to btrfs-list.h Anand jain
2012-12-28  3:12 ` [PATCH 5/8] Btrfs-progs: function to get root_info of a subvol Anand jain
2012-12-28  3:13 ` [PATCH 6/8] Btrfs-progs: provide method to check if filter is set Anand jain
2012-12-28  3:13 ` [PATCH 7/8] Btrfs-progs: add method to filter snapshots by parent uuid Anand jain
2012-12-28  3:13 ` [PATCH 8/8] Btrfs-progs: add show command to display detailed information about the subvol Anand jain
2013-01-10 11:41 ` [PATCH 00/11 V3] add show command to the subvol sub command Anand Jain
2013-01-10 11:41   ` [PATCH 01/11] Btrfs-progs: move open_file_or_dir() to utils.c Anand Jain
2013-01-10 11:41   ` [PATCH 02/11] Btrfs-progs: Move printing outside of btrfs_list_subvols Anand Jain
2013-01-10 11:41   ` [PATCH 03/11] Btrfs-progs: add parent uuid for snapshots Anand Jain
2013-01-10 11:41   ` [PATCH 04/11] Btrfs-progs: move struct root_info to btrfs-list.h Anand Jain
2013-01-10 11:41   ` [PATCH 05/11] Btrfs-progs: function to get root_info of a subvol Anand Jain
2013-01-10 11:41   ` [PATCH 06/11] Btrfs-progs: provide method to check if filter is set Anand Jain
2013-01-10 11:41   ` [PATCH 07/11] Btrfs-progs: add method to filter snapshots by parent uuid Anand Jain
2013-01-10 11:41   ` [PATCH 08/11] Btrfs-progs: put find_mount_root() in commands.h Anand Jain
2013-01-10 11:41   ` [PATCH 09/11] Btrfs-progs: maintain similar case in heading prefix Anand Jain
2013-01-10 11:41   ` [PATCH 10/11] Btrfs-progs: accommodate different layout for printing subvol list Anand Jain
2013-01-10 11:41   ` Anand Jain [this message]
2013-01-14  4:04   ` [PATCH 00/11 V3] add show command to the subvol sub command Anand Jain
2013-01-14 18:25     ` Goffredo Baroncelli
2013-01-15  8:05       ` Anand Jain
2013-01-15 18:37         ` Goffredo Baroncelli
2013-01-21  0:19   ` Gene Czarcinski
2013-01-21 10:35     ` Anand Jain
2013-01-23  8:30   ` Anand Jain

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=1357818083-15531-12-git-send-email-anand.jain@oracle.com \
    --to=anand.jain@oracle.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).