bectl(8): Implement bectl list -s
be_get_dataset_snapshots has been added to libbe(3), effectively returning the same information as be_get_bootenv_props but for snapshots of the given dataset. The assumption is that one will have the BE dataset name before wanting to grab snapshots.
This commit is contained in:
parent
411563c444
commit
5ef81a6b77
@ -68,6 +68,7 @@ const char *be_root_path(libbe_handle_t *);
|
||||
|
||||
int be_get_bootenv_props(libbe_handle_t *, nvlist_t *);
|
||||
int be_get_dataset_props(libbe_handle_t *, const char *, nvlist_t *);
|
||||
int be_get_dataset_snapshots(libbe_handle_t *, const char *, nvlist_t *);
|
||||
int be_prop_list_alloc(nvlist_t **be_list);
|
||||
void be_prop_list_free(nvlist_t *be_list);
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "be.h"
|
||||
#include "be_impl.h"
|
||||
|
||||
static int snapshot_prop_list_builder(zfs_handle_t *hdl, prop_data_t *data);
|
||||
|
||||
/*
|
||||
* Returns the name of the active boot environment
|
||||
*/
|
||||
@ -117,6 +119,25 @@ be_get_dataset_props(libbe_handle_t *lbh, const char *name, nvlist_t *props)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
be_get_dataset_snapshots(libbe_handle_t *lbh, const char *name, nvlist_t *props)
|
||||
{
|
||||
zfs_handle_t *ds_hdl;
|
||||
prop_data_t data;
|
||||
int ret;
|
||||
|
||||
data.lbh = lbh;
|
||||
data.list = props;
|
||||
data.single_object = false;
|
||||
if ((ds_hdl = zfs_open(lbh->lzh, name,
|
||||
ZFS_TYPE_FILESYSTEM)) == NULL)
|
||||
return (BE_ERR_ZFSOPEN);
|
||||
|
||||
ret = snapshot_prop_list_builder(ds_hdl, &data);
|
||||
zfs_close(ds_hdl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal callback function used by zfs_iter_filesystems. For each dataset in
|
||||
* the bootenv root, populate an nvlist_t of its relevant properties.
|
||||
@ -221,6 +242,13 @@ prop_list_builder(prop_data_t *data)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
snapshot_prop_list_builder(zfs_handle_t *hdl, prop_data_t *data)
|
||||
{
|
||||
|
||||
return (zfs_iter_snapshots_sorted(hdl, prop_list_builder_cb, data));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
be_prop_list_alloc(nvlist_t **be_list)
|
||||
|
@ -144,6 +144,9 @@ of state to be retained, such as errors from previous operations.
|
||||
.Ft int
|
||||
.Fn be_get_dataset_props "libbe_handle_t *, const char *, nvlist_t *" ;
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn be_get_dataset_snapshots "libbe_handle_t *, const char *, nvlist_t *" ;
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn be_prop_list_free "nvlist_t *" ;
|
||||
.\" .Ft void
|
||||
|
@ -74,6 +74,7 @@ static int bectl_cmd_add(int argc, char *argv[]);
|
||||
static int bectl_cmd_jail(int argc, char *argv[]);
|
||||
static const char *get_origin_props(nvlist_t *dsprops, nvlist_t **originprops);
|
||||
static void print_padding(const char *fval, int colsz, struct printc *pc);
|
||||
static int print_snapshots(const char *dsname, struct printc *pc);
|
||||
static void print_info(const char *name, nvlist_t *dsprops, struct printc *pc);
|
||||
static void print_headers(nvlist_t *props, struct printc *pc);
|
||||
static int bectl_cmd_list(int argc, char *argv[]);
|
||||
@ -505,6 +506,28 @@ dataset_space(const char *oname)
|
||||
return (space);
|
||||
}
|
||||
|
||||
static int
|
||||
print_snapshots(const char *dsname, struct printc *pc)
|
||||
{
|
||||
nvpair_t *cur;
|
||||
nvlist_t *props, *sprops;
|
||||
|
||||
if (be_prop_list_alloc(&props) != 0) {
|
||||
fprintf(stderr, "bectl list: failed to allocate snapshot nvlist\n");
|
||||
return (1);
|
||||
}
|
||||
if (be_get_dataset_snapshots(be, dsname, props) != 0) {
|
||||
fprintf(stderr, "bectl list: failed to fetch boot ds snapshots\n");
|
||||
return (1);
|
||||
}
|
||||
for (cur = nvlist_next_nvpair(props, NULL); cur != NULL;
|
||||
cur = nvlist_next_nvpair(props, cur)) {
|
||||
nvpair_value_nvlist(cur, &sprops);
|
||||
print_info(nvpair_name(cur), sprops, pc);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
print_info(const char *name, nvlist_t *dsprops, struct printc *pc)
|
||||
{
|
||||
@ -513,27 +536,34 @@ print_info(const char *name, nvlist_t *dsprops, struct printc *pc)
|
||||
unsigned long long ctimenum, space;
|
||||
nvlist_t *originprops;
|
||||
const char *oname;
|
||||
char *propstr;
|
||||
char *dsname, *propstr;
|
||||
int active_colsz;
|
||||
boolean_t active_now, active_reboot;
|
||||
|
||||
dsname = NULL;
|
||||
originprops = NULL;
|
||||
printf("%*s%s", pc->current_indent, "", name);
|
||||
nvlist_lookup_string(dsprops, "dataset", &dsname);
|
||||
|
||||
/* Recurse at the base level if we're breaking info down */
|
||||
if (pc->current_indent == 0 && (pc->show_all_datasets ||
|
||||
pc->show_snaps)) {
|
||||
printf("\n");
|
||||
if (nvlist_lookup_string(dsprops, "dataset", &propstr) != 0)
|
||||
if (dsname == NULL)
|
||||
/* XXX TODO: Error? */
|
||||
return;
|
||||
pc->current_indent += INDENT_INCREMENT;
|
||||
print_info(propstr, dsprops, pc);
|
||||
print_info(dsname, dsprops, pc);
|
||||
pc->current_indent += INDENT_INCREMENT;
|
||||
if ((oname = get_origin_props(dsprops, &originprops)) != NULL) {
|
||||
print_info(oname, originprops, pc);
|
||||
nvlist_free(originprops);
|
||||
}
|
||||
|
||||
/* Back up a level; snapshots at the same level as dataset */
|
||||
pc->current_indent -= INDENT_INCREMENT;
|
||||
if (pc->show_snaps)
|
||||
print_snapshots(dsname, pc);
|
||||
pc->current_indent = 0;
|
||||
return;
|
||||
} else
|
||||
@ -593,11 +623,8 @@ print_info(const char *name, nvlist_t *dsprops, struct printc *pc)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
if (originprops != NULL) {
|
||||
/*if (pc->show_all_datasets) {
|
||||
}*/
|
||||
if (originprops != NULL)
|
||||
be_prop_list_free(originprops);
|
||||
}
|
||||
#undef BUFSZ
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user