From: Anand Jain <anand.jain@oracle.com> This set of patch will add show sub-command to btrfs subvolume, which is to show more information about a given subvol or snapshot. At present it shows 3 info, I hope this will be further useful if enhanced as needed. eg: # btrfs su show /btrfs/sssv3 /btrfs/sssv3 uuid: c5d646b5-a749-c646-b082-6d9a3ca870be Parent uuid: 34bc8edd-113f-5141-a814-f6dfae069b01 Creation time: 2012-10-12 11:37:00 Thanks Anand Jain (4): Btrfs-progs: introduce btrfs_get_subvols function Btrfs-progs: need struct root_info to be accesible Btrfs-progs: method to fetch root info for subvol Btrfs-progs: add btrfs subvol show cli btrfs-list.c | 119 ++++++++++++++++++++++++++--------------------------- btrfs-list.h | 49 ++++++++++++++++++++++- cmds-subvolume.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ man/btrfs.8.in | 6 +++ 4 files changed, 225 insertions(+), 62 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand jain
2012-Oct-12 05:20 UTC
[PATCH 1/4] Btrfs-progs: introduce btrfs_get_subvols function
From: Anand Jain <anand.jain@oracle.com> Having this not part of btrfs_list_subvols will help code reuse. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-list.c | 35 +++++++++++++++++++++-------------- 1 files changed, 21 insertions(+), 14 deletions(-) diff --git a/btrfs-list.c b/btrfs-list.c index 20da828..657e4db 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -1323,6 +1323,26 @@ static int __list_subvol_fill_paths(int fd, struct root_lookup *root_lookup) return 0; } +static int btrfs_get_subvols(int fd, struct root_lookup *root_lookup) +{ + int ret; + + ret = __list_subvol_search(fd, root_lookup); + if (ret) { + fprintf(stderr, "ERROR: can''t perform the search - %s\n", + strerror(errno)); + return ret; + } + + /* + * now we have an rbtree full of root_info objects, but we need to fill + * in their path names within the subvol that is referencing each one. + */ + ret = __list_subvol_fill_paths(fd, root_lookup); + + return ret; +} + static void print_subvolume_column(struct root_info *subv, enum btrfs_list_column_enum column) { @@ -1471,20 +1491,7 @@ int btrfs_list_subvols(int fd, struct btrfs_list_filter_set *filter_set, struct root_lookup root_sort; int ret; - ret = __list_subvol_search(fd, &root_lookup); - if (ret) { - fprintf(stderr, "ERROR: can''t perform the search - %s\n", - strerror(errno)); - return ret; - } - - /* - * now we have an rbtree full of root_info objects, but we need to fill - * in their path names within the subvol that is referencing each one. - */ - ret = __list_subvol_fill_paths(fd, &root_lookup); - if (ret < 0) - return ret; + ret = btrfs_get_subvols(fd, &root_lookup); __filter_and_sort_subvol(&root_lookup, &root_sort, filter_set, comp_set, fd); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand jain
2012-Oct-12 05:20 UTC
[PATCH 2/4] Btrfs-progs: need struct root_info to be accesible
From: Anand Jain <anand.jain@oracle.com> Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-list.c | 47 ----------------------------------------------- btrfs-list.h | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/btrfs-list.c b/btrfs-list.c index 657e4db..c0407c9 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -46,53 +46,6 @@ struct root_lookup { struct rb_root root; }; -/* - * one of these for each root we find. - */ -struct root_info { - struct rb_node rb_node; - struct rb_node sort_node; - - /* this root''s id */ - u64 root_id; - - /* equal the offset of the root''s key */ - u64 root_offset; - - /* flags of the root */ - u64 flags; - - /* the id of the root that references this one */ - u64 ref_tree; - - /* the dir id we''re in from ref_tree */ - u64 dir_id; - - u64 top_id; - - /* generation when the root is created or last updated */ - u64 gen; - - /* creation generation of this root in sec*/ - u64 ogen; - - /* creation time of this root in sec*/ - time_t otime; - - u8 uuid[BTRFS_UUID_SIZE]; - u8 puuid[BTRFS_UUID_SIZE]; - - /* path from the subvol we live in to this root, including the - * root''s name. This is null until we do the extra lookup ioctl. - */ - char *path; - - /* the name of this root in the directory it lives in */ - char *name; - - char *full_path; -}; - struct { char *name; char *column_name; diff --git a/btrfs-list.h b/btrfs-list.h index a32545f..bd5e23a 100644 --- a/btrfs-list.h +++ b/btrfs-list.h @@ -17,8 +17,54 @@ */ #include "kerncompat.h" +#include "rbtree.h" -struct root_info; +/* + * one of these for each root we find. + */ +struct root_info { + struct rb_node rb_node; + struct rb_node sort_node; + + /* this root''s id */ + u64 root_id; + + /* equal the offset of the root''s key */ + u64 root_offset; + + /* flags of the root */ + u64 flags; + + /* the id of the root that references this one */ + u64 ref_tree; + + /* the dir id we''re in from ref_tree */ + u64 dir_id; + + u64 top_id; + + /* generation when the root is created or last updated */ + u64 gen; + + /* creation generation of this root in sec*/ + u64 ogen; + + /* creation time of this root in sec*/ + time_t otime; + + u8 uuid[BTRFS_UUID_SIZE]; + u8 puuid[BTRFS_UUID_SIZE]; + + /* path from the subvol we live in to this root, including the + * root''s name. This is null until we do the extra lookup ioctl. + */ + char *path; + + /* the name of this root in the directory it lives in */ + char *name; + + char *full_path; +}; typedef int (*btrfs_list_filter_func)(struct root_info *, u64); typedef int (*btrfs_list_comp_func)(struct root_info *, struct root_info *, -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand jain
2012-Oct-12 05:20 UTC
[PATCH 3/4] Btrfs-progs: method to fetch root info for subvol
From: Anand Jain <anand.jain@oracle.com> Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-list.c | 37 +++++++++++++++++++++++++++++++++++++ btrfs-list.h | 1 + 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/btrfs-list.c b/btrfs-list.c index c0407c9..5eada92 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -1296,6 +1296,43 @@ static int btrfs_get_subvols(int fd, struct root_lookup *root_lookup) return ret; } +int btrfs_get_a_subvol(int fd, struct root_info *the_ri) +{ + int ret = -1; + struct root_lookup rl; + struct rb_node *rbn; + struct root_info *ri; + u64 top_id = btrfs_list_get_path_rootid(fd); + + if (btrfs_get_subvols(fd, &rl)) + return 13; + + rbn = rb_first(&rl.root); + while(rbn) { + ri = rb_entry(rbn, struct root_info, rb_node); + resolve_root(&rl, ri, top_id); + if (!comp_entry_with_path(the_ri, ri, 0)) { + memcpy(the_ri, ri, offsetof(struct root_info, path)); + if (ri->path) + the_ri->path = strdup(ri->path); + else + the_ri->path = NULL; + if (ri->name) + the_ri->name = strdup(ri->name); + else + the_ri->name = NULL; + if (ri->full_path) + the_ri->full_path = strdup(ri->full_path); + else + the_ri->name = NULL; + ret = 0; + } + rbn = rb_next(rbn); + } + __free_all_subvolumn(&rl); + return ret; +} + static void print_subvolume_column(struct root_info *subv, enum btrfs_list_column_enum column) { diff --git a/btrfs-list.h b/btrfs-list.h index bd5e23a..fc04f05 100644 --- a/btrfs-list.h +++ b/btrfs-list.h @@ -152,3 +152,4 @@ 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); u64 btrfs_list_get_path_rootid(int fd); +int btrfs_get_a_subvol(int fd, struct root_info *the_ri); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Anand Jain <anand.jain@oracle.com> This will add a sub command to show information about a subvol. eg: btrfs su show /btrfs/sssv3 /btrfs/sssv3 uuid: c5d646b5-a749-c646-b082-6d9a3ca870be Parent uuid: 34bc8edd-113f-5141-a814-f6dfae069b01 Creation time: 2012-10-12 11:37:00 Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-subvolume.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ man/btrfs.8.in | 6 +++ 2 files changed, 119 insertions(+), 0 deletions(-) diff --git a/cmds-subvolume.c b/cmds-subvolume.c index 92b69d1..13defa9 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" @@ -703,6 +704,117 @@ 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 information about the given 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]; + + if (check_argc_exact(argc, 2)) + usage(cmd_subvol_show_usage); + + subvol = argv[1]; + + ret = test_issubvolume(subvol); + if (ret < 0) { + fprintf(stderr, "ERROR: error accessing ''%s''\n", subvol); + return 12; + } + if (!ret) { + fprintf(stderr, "ERROR: ''%s'' is not a subvolume\n", 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)); + return 12; + } + if (!strcmp(subvol, mnt)) + return 0; + + /* +1 will point after the "/" */ + 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_a_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%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%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%s", tstr); + printf("\n"); + +/* if in case we decide to have more available data + to be shown we can use it as below. + + printf("Object ID: %llu", get_ri.root_id); + printf("\n"); + printf("Generation: %llu", get_ri.gen); + printf("\n"); + printf("OGeneration: %llu", get_ri.ogen); + printf("\n"); + printf("Parent: %llu", get_ri.ref_tree); + printf("\n"); + printf("Top Level: %llu", get_ri.top_id); + printf("\n"); +*/ + + /* 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); + return 0; +} + const struct cmd_group subvolume_cmd_group = { subvolume_cmd_group_usage, NULL, { { "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 }, @@ -714,6 +826,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 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Goffredo Baroncelli
2012-Oct-13 20:11 UTC
Re: [PATCH 0/4] Add show sub command to btrfs subvolume
Hi Anad, On 2012-10-12 07:20, Anand jain wrote:> From: Anand Jain<anand.jain@oracle.com> > > This set of patch will add show sub-command to > btrfs subvolume, which is to show more information > about a given subvol or snapshot. At present it shows > 3 info, I hope this will be further useful if enhanced > as needed.Thanks for working on that; do you think that is it feasible to merge the works on "btrfs sub list" and "btrfs sub show" ? To date the output of "btrfs sub list" is quite cryptic: a lot of information on only on row, which is difficult to read. However it has the capability to traverse the filesystem to list the subvolumes, to sort the output, to filter it... Instead your work has not the capability to traverse/filter/sort but has a very nice output. The ideal is to extend the actual command (btrfs sub list) to have your output (as default) and the current one (as option) when used in script... BR G.Baroncelli> > eg: > # btrfs su show /btrfs/sssv3 > /btrfs/sssv3 > uuid: c5d646b5-a749-c646-b082-6d9a3ca870be > Parent uuid: 34bc8edd-113f-5141-a814-f6dfae069b01 > Creation time: 2012-10-12 11:37:00 > > > Thanks > > Anand Jain (4): > Btrfs-progs: introduce btrfs_get_subvols function > Btrfs-progs: need struct root_info to be accesible > Btrfs-progs: method to fetch root info for subvol > Btrfs-progs: add btrfs subvol show cli > > btrfs-list.c | 119 ++++++++++++++++++++++++++--------------------------- > btrfs-list.h | 49 ++++++++++++++++++++++- > cmds-subvolume.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ > man/btrfs.8.in | 6 +++ > 4 files changed, 225 insertions(+), 62 deletions(-) > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Goffredo Baroncelli
2012-Oct-13 20:21 UTC
Re: [PATCH 4/4] Btrfs-progs: add btrfs subvol show cli
On 2012-10-12 07:20, Anand jain wrote:> From: Anand Jain<anand.jain@oracle.com> > > This will add a sub command to show information about a subvol. > eg: > btrfs su show /btrfs/sssv3 > /btrfs/sssv3 > uuid: c5d646b5-a749-c646-b082-6d9a3ca870be > Parent uuid: 34bc8edd-113f-5141-a814-f6dfae069b01 > Creation time: 2012-10-12 11:37:00 >> + > +/* if in case we decide to have more available data > + to be shown we can use it as below. > + > + printf("Object ID: %llu", get_ri.root_id); > + printf("\n"); > + printf("Generation: %llu", get_ri.gen); > + printf("\n"); > + printf("OGeneration: %llu", get_ri.ogen); > + printf("\n"); > + printf("Parent: %llu", get_ri.ref_tree); > + printf("\n"); > + printf("Top Level: %llu", get_ri.top_id); > + printf("\n"); > +*/Please, add a switch to show this further data. Does the flags contains sensible data ?> + > + /* 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); > + return 0; > +} > + > const struct cmd_group subvolume_cmd_group = { > subvolume_cmd_group_usage, NULL, { > { "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 }, > @@ -714,6 +826,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. > +.TPIt is possible to allow "btrfs subvolume show" to process multiple paths ? btrfs sub show <subv1> [<subvol2> ... ]> + > \fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] \ > [-t \fIsize\fR] -[vf]<\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...] >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> Thanks for working on that; do you think that is it feasible to merge > the works on "btrfs sub list" and "btrfs sub show" ? > To date the output of "btrfs sub list" is quite cryptic: a lot of > information on only on row, which is difficult to read. However it has > the capability to traverse the filesystem to list the subvolumes, to > sort the output, to filter it... > Instead your work has not the capability to traverse/filter/sort but has > a very nice output. > > The ideal is to extend the actual command (btrfs sub list) to have your > output (as default) and the current one (as option) when used in script...Thanks for the comments. (just for note: this patch is on top the latest subvol list framework). generally multi-line output isn''t suitable for the list kind of output, right? since it makes scripting difficult. So here the plan is to have both list and show. List is to see all the items and show is know more about an item. Show will be more exciting when we could add size info for each subvol/snapshot. -Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html