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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user