Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149577977
D20818.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D20818.diff
View Options
Index: head/sbin/bectl/bectl.8
===================================================================
--- head/sbin/bectl/bectl.8
+++ head/sbin/bectl/bectl.8
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 12, 2019
+.Dd September 4, 2019
.Dt BECTL 8
.Os
.Sh NAME
@@ -57,6 +57,9 @@
.Nm
.Cm list
.Op Fl aDHs
+.Op Fl c Ar property
+.Op Fl C Ar property
+.Oo Bro Fl c Ar property | Fl C Ar property Brc Oc
.Nm
.Cm mount
.Ar beName
@@ -234,7 +237,12 @@
.El
.Pp
All default parameters may be overwritten.
-.It Cm list Op Fl aDHs
+.It Xo
+.Cm list
+.Op Fl DHas
+.Oo Bro Fl c Ar property | Fl C Ar property Brc Oc
+.Xc
+.Pp
Display all boot environments.
The
.Em Active
@@ -245,21 +253,44 @@
or both
.Pq Em \&NR .
.Pp
-If
-.Fl a
-is used, display all datasets.
-If
-.Fl D
-is used, display the full space usage for each boot environment, assuming all
+.Bl -tag -width indent
+.It Fl a
+Display all datasets.
+.It Fl D
+Display the full space usage for each boot environment, assuming all
other boot environments were destroyed.
-The
-.Fl H
-option is used for scripting.
-It does not print headers and separate fields by a single tab instead of
+.It Fl H
+Used for scripting.
+Do not print headers and separate fields by a single tab instead of
arbitrary white space.
-If
+.It Fl s
+Display all snapshots as well.
+.It Fl c Ar property
+Sort boot environments by given property name.
+The following properties are supported:
+.Pp
+.Bl -tag -width 4n -offset indent -compact
+.It name (default output)
+.It creation
+.It origin
+.It used
+.It usedds
+.It usedsnap
+.It usedrefreserv
+.El
+.It Fl C Ar property
+Same as the
+.Fl c
+option, but displays in descending order.
+.El
+.Pp
+The
+.Fl D
+option is ignored when either the
.Fl s
-is used, display all snapshots as well.
+or
+.Fl a
+option is used.
.It Cm mount Ar beName Op Ar mountpoint
Temporarily mount the boot environment.
Mount at the specified
Index: head/sbin/bectl/bectl.c
===================================================================
--- head/sbin/bectl/bectl.c
+++ head/sbin/bectl/bectl.c
@@ -80,7 +80,7 @@
"\tbectl jail {-b | -U} [{-o key=value | -u key}]... "
"{jailID | jailName}\n"
"\t bootenv [utility [argument ...]]\n"
- "\tbectl list [-DHas]\n"
+ "\tbectl list [-DHas] [{-c property | -C property}]\n"
"\tbectl mount beName [mountpoint]\n"
"\tbectl rename origBeName newBeName\n"
"\tbectl {ujail | unjail} {jailID | jailName} bootenv\n"
Index: head/sbin/bectl/bectl_list.c
===================================================================
--- head/sbin/bectl/bectl_list.c
+++ head/sbin/bectl/bectl_list.c
@@ -38,6 +38,12 @@
#include "bectl.h"
+struct sort_column {
+ char *name;
+ char *val;
+ nvlist_t *nvl;
+};
+
struct printc {
int active_colsz_def;
int be_colsz;
@@ -324,6 +330,74 @@
printf("\n");
}
+/*
+ * Sort the given nvlist of boot environments by property.
+ */
+static int
+prop_list_sort(nvlist_t *props, char *property, bool reverse)
+{
+ nvpair_t *nvp;
+ nvlist_t *nvl;
+ int i, nvp_count;
+ uint64_t lval, rval;
+ struct sort_column sc_prev, sc_next;
+
+ /* a temporary list to work with */
+ nvlist_dup(props, &nvl, 0);
+
+ nvp_count = fnvlist_num_pairs(nvl);
+ for (i = 0; i < nvp_count; i++) {
+
+ nvp = nvlist_next_nvpair(nvl, NULL);
+ nvpair_value_nvlist(nvp, &sc_prev.nvl);
+ nvlist_lookup_string(sc_prev.nvl, "name", &sc_prev.name);
+ nvlist_lookup_string(sc_prev.nvl, property, &sc_prev.val);
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+
+ nvpair_value_nvlist(nvp, &sc_next.nvl);
+ nvlist_lookup_string(sc_next.nvl, "name", &sc_next.name);
+ nvlist_lookup_string(sc_next.nvl, property, &sc_next.val);
+
+ /* properties that use numerical comparison */
+ if (strcmp(property, "creation") == 0 ||
+ strcmp(property, "used") == 0 ||
+ strcmp(property, "usedds") == 0 ||
+ strcmp(property, "usedsnap") == 0 ||
+ strcmp(property, "usedrefreserv") == 0) {
+
+ lval = strtoull(sc_prev.val, NULL, 10);
+ rval = strtoull(sc_next.val, NULL, 10);
+
+ if ((lval < rval && reverse) ||
+ (lval > rval && !reverse))
+ sc_prev = sc_next;
+ }
+
+ /* properties that use string comparison */
+ else if (strcmp(property, "name") == 0 ||
+ strcmp(property, "origin") == 0) {
+ if ((strcmp(sc_prev.val, sc_next.val) < 0 && reverse) ||
+ (strcmp(sc_prev.val, sc_next.val) > 0 && !reverse))
+ sc_prev = sc_next;
+ }
+ }
+
+ /*
+ * The 'props' nvlist has been created to only have unique names.
+ * When a name is added, any existing nvlist's with the same name
+ * will be removed. Eventually, all existing nvlist's are replaced
+ * in sorted order.
+ */
+ nvlist_add_nvlist(props, sc_prev.name, sc_prev.nvl);
+ nvlist_remove_all(nvl, sc_prev.name);
+ }
+
+ be_prop_list_free(nvl);
+
+ return 0;
+}
+
int
bectl_cmd_list(int argc, char *argv[])
{
@@ -331,12 +405,14 @@
nvpair_t *cur;
nvlist_t *dsprops, *props;
int opt, printed;
- boolean_t active_now, active_reboot;
+ char *column;
+ bool reverse;
+ column = NULL;
props = NULL;
printed = 0;
bzero(&pc, sizeof(pc));
- while ((opt = getopt(argc, argv, "aDHs")) != -1) {
+ while ((opt = getopt(argc, argv, "aDHsc:C:")) != -1) {
switch (opt) {
case 'a':
pc.show_all_datasets = true;
@@ -350,6 +426,18 @@
case 's':
pc.show_snaps = true;
break;
+ case 'c':
+ if (column != NULL)
+ free(column);
+ column = strdup(optarg);
+ reverse = false;
+ break;
+ case 'C':
+ if (column != NULL)
+ free(column);
+ column = strdup(optarg);
+ reverse = true;
+ break;
default:
fprintf(stderr, "bectl list: unknown option '-%c'\n",
optopt);
@@ -374,44 +462,33 @@
return (1);
}
+ /* List boot environments in alphabetical order by default */
+ if (column == NULL) {
+ column = strdup("name");
+ reverse = false;
+ }
+
+ prop_list_sort(props, column, reverse);
+
/* Force -D off if either -a or -s are specified */
if (pc.show_all_datasets || pc.show_snaps)
pc.show_space = false;
if (!pc.script_fmt)
print_headers(props, &pc);
- /* Do a first pass to print active and next active first */
- for (cur = nvlist_next_nvpair(props, NULL); cur != NULL;
- cur = nvlist_next_nvpair(props, cur)) {
- nvpair_value_nvlist(cur, &dsprops);
- active_now = active_reboot = false;
- nvlist_lookup_boolean_value(dsprops, "active", &active_now);
- nvlist_lookup_boolean_value(dsprops, "nextboot",
- &active_reboot);
- if (!active_now && !active_reboot)
- continue;
- if (printed > 0 && (pc.show_all_datasets || pc.show_snaps))
- printf("\n");
- print_info(nvpair_name(cur), dsprops, &pc);
- printed++;
- }
-
- /* Now pull everything else */
+ /* Print boot environments */
for (cur = nvlist_next_nvpair(props, NULL); cur != NULL;
cur = nvlist_next_nvpair(props, cur)) {
nvpair_value_nvlist(cur, &dsprops);
- active_now = active_reboot = false;
- nvlist_lookup_boolean_value(dsprops, "active", &active_now);
- nvlist_lookup_boolean_value(dsprops, "nextboot",
- &active_reboot);
- if (active_now || active_reboot)
- continue;
if (printed > 0 && (pc.show_all_datasets || pc.show_snaps))
printf("\n");
+
print_info(nvpair_name(cur), dsprops, &pc);
printed++;
}
+
+ free(column);
be_prop_list_free(props);
return (0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 26, 9:03 AM (15 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30375693
Default Alt Text
D20818.diff (7 KB)
Attached To
Mode
D20818: implement sorting for 'bectl list' output
Attached
Detach File
Event Timeline
Log In to Comment