bectl: log modifying functions to zpool history

Modeled directly after the method used by the zfs/zpool commands: flag
commands with a "please log me" flag, and when there, reconstruct the
command line. On success, call the library function to add it to the
log.

(Majority of the change by Rob; minor edits by kevans@)

Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Co-authored-by:	Kyle Evans <kevans@FreeBSD.org>
Sponsored by:	Modirum MDPay
Sponsored by:	Klara, Inc.
This commit is contained in:
Rob Norris
2025-12-17 11:00:47 -06:00
committed by Kyle Evans
parent 1fad49baf3
commit 2a87929671
4 changed files with 85 additions and 18 deletions
+12
View File
@@ -1343,3 +1343,15 @@ be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
return (BE_ERR_SUCCESS);
}
int
be_log_history(libbe_handle_t *lbh, const char *message)
{
int err;
err = zpool_log_history(lbh->lzh, message);
if (err)
return (set_error(lbh, BE_ERR_UNKNOWN));
return (BE_ERR_SUCCESS);
}
+2
View File
@@ -107,6 +107,8 @@ int be_exists(libbe_handle_t *, const char *);
int be_export(libbe_handle_t *, const char *, int fd);
int be_import(libbe_handle_t *, const char *, int fd);
int be_log_history(libbe_handle_t *, const char *);
#if SOON
int be_add_child(libbe_handle_t *, const char *, bool);
#endif
+14 -2
View File
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd April 20, 2025
.Dd December 11, 2025
.Dt LIBBE 3
.Os
.Sh NAME
@@ -144,6 +144,9 @@
.Pp
.Ft void
.Fn be_prop_list_free "nvlist_t *prop_list"
.Pp
.Ft int
.Fn be_log_history "libbe_handle_t *hdl" "const char *message"
.Sh DESCRIPTION
.Nm
interfaces with libzfs to provide a set of functions for various operations
@@ -536,6 +539,14 @@ exactly as specified by
The
.Fn be_prop_list_free
function will free the property list.
.Pp
The
.Fn be_log_history
function will log the given
.Fa message
to the zpool history, which can be later retrieved using the
.Xr zpool-history 8
command.
.Sh DIAGNOSTICS
Upon error, one of the following values will be returned:
.Bl -bullet -offset indent -compact
@@ -583,7 +594,8 @@ BE_ERR_UNKNOWN
BE_ERR_INVORIGIN
.El
.Sh SEE ALSO
.Xr bectl 8
.Xr bectl 8 ,
.Xr zpool-history 8
.Sh HISTORY
.Xr bectl 8
and
+57 -16
View File
@@ -6,6 +6,7 @@
#include <sys/param.h>
#include <sys/mount.h>
#include <err.h>
#include <errno.h>
#include <libutil.h>
#include <stdbool.h>
@@ -76,27 +77,28 @@ struct command_map_entry {
int (*fn)(int argc, char *argv[]);
/* True if libbe_print_on_error should be disabled */
bool silent;
bool save_history;
};
static struct command_map_entry command_map[] =
{
{ "activate", bectl_cmd_activate,false },
{ "create", bectl_cmd_create, false },
{ "destroy", bectl_cmd_destroy, false },
{ "export", bectl_cmd_export, false },
{ "import", bectl_cmd_import, false },
{ "activate", bectl_cmd_activate,false, true },
{ "create", bectl_cmd_create, false, true },
{ "destroy", bectl_cmd_destroy, false, true },
{ "export", bectl_cmd_export, false, true },
{ "import", bectl_cmd_import, false, true },
#if SOON
{ "add", bectl_cmd_add, false },
{ "add", bectl_cmd_add, false, true },
#endif
{ "jail", bectl_cmd_jail, false },
{ "list", bectl_cmd_list, false },
{ "mount", bectl_cmd_mount, false },
{ "rename", bectl_cmd_rename, false },
{ "unjail", bectl_cmd_unjail, false },
{ "ujail", bectl_cmd_unjail, false },
{ "unmount", bectl_cmd_unmount, false },
{ "umount", bectl_cmd_unmount, false },
{ "check", bectl_cmd_check, true },
{ "jail", bectl_cmd_jail, false, false },
{ "list", bectl_cmd_list, false, false },
{ "mount", bectl_cmd_mount, false, false },
{ "rename", bectl_cmd_rename, false, true },
{ "unjail", bectl_cmd_unjail, false, false },
{ "ujail", bectl_cmd_unjail, false, false },
{ "unmount", bectl_cmd_unmount, false, false },
{ "umount", bectl_cmd_unmount, false, false },
{ "check", bectl_cmd_check, true, false },
};
static struct command_map_entry *
@@ -523,12 +525,42 @@ bectl_cmd_check(int argc, char *argv[] __unused)
return (0);
}
static char *
save_cmdline(int argc, char *argv[])
{
char *cmdline, *basename, *p;
int len, n, i;
len = MAXPATHLEN * 2 + 1; /* HIS_MAX_RECORD_LEN from zfs.h */
cmdline = p = malloc(len);
if (cmdline == NULL)
err(2, "malloc");
basename = strrchr(argv[0], '/');
if (basename == NULL)
basename = argv[0];
else
basename++;
n = strlcpy(p, basename, len);
for (i = 1; i < argc; i++) {
if (n >= len)
break;
p += n;
*p++ = ' ';
len -= (n + 1);
n = strlcpy(p, argv[i], len);
}
return (cmdline);
}
int
main(int argc, char *argv[])
{
struct command_map_entry *cmd;
const char *command;
char *root = NULL;
char *root = NULL, *cmdline = NULL;
int opt, rc;
while ((opt = getopt(argc, argv, "hr:")) != -1) {
@@ -565,10 +597,19 @@ main(int argc, char *argv[])
return (-1);
}
if (cmd->save_history)
cmdline = save_cmdline(argc+optind, argv-optind);
libbe_print_on_error(be, !cmd->silent);
rc = cmd->fn(argc, argv);
if (cmd->save_history) {
if (rc == 0)
be_log_history(be, cmdline);
free(cmdline);
}
libbe_close(be);
return (rc);
}