Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>

@@ -32,10 +32,11 @@
 #include <libintl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <strings.h>
 #include <unistd.h>
+#include <libgen.h>
 #include <sys/efi_partition.h>
 #include <sys/vtoc.h>
 #include <sys/zfs_ioctl.h>
 #include <dlfcn.h>
 

@@ -1203,11 +1204,11 @@
 /*
  * Destroy the given pool.  It is up to the caller to ensure that there are no
  * datasets left in the pool.
  */
 int
-zpool_destroy(zpool_handle_t *zhp)
+zpool_destroy(zpool_handle_t *zhp, const char *log_str)
 {
         zfs_cmd_t zc = { 0 };
         zfs_handle_t *zfp = NULL;
         libzfs_handle_t *hdl = zhp->zpool_hdl;
         char msg[1024];

@@ -1215,10 +1216,11 @@
         if (zhp->zpool_state == POOL_STATE_ACTIVE &&
             (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
                 return (-1);
 
         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+        zc.zc_history = (uint64_t)(uintptr_t)log_str;
 
         if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
                     "cannot destroy '%s'"), zhp->zpool_name);
 

@@ -1369,22 +1371,24 @@
 
 /*
  * Exports the pool from the system.  The caller must ensure that there are no
  * mounted datasets in the pool.
  */
-int
-zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
+static int
+zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
+    const char *log_str)
 {
         zfs_cmd_t zc = { 0 };
         char msg[1024];
 
         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
             "cannot export '%s'"), zhp->zpool_name);
 
         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
         zc.zc_cookie = force;
         zc.zc_guid = hardforce;
+        zc.zc_history = (uint64_t)(uintptr_t)log_str;
 
         if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
                 switch (errno) {
                 case EXDEV:
                         zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,

@@ -1402,19 +1406,19 @@
 
         return (0);
 }
 
 int
-zpool_export(zpool_handle_t *zhp, boolean_t force)
+zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
 {
-        return (zpool_export_common(zhp, force, B_FALSE));
+        return (zpool_export_common(zhp, force, B_FALSE, log_str));
 }
 
 int
-zpool_export_force(zpool_handle_t *zhp)
+zpool_export_force(zpool_handle_t *zhp, const char *log_str)
 {
-        return (zpool_export_common(zhp, B_TRUE, B_TRUE));
+        return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
 }
 
 static void
 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
     nvlist_t *config)

@@ -3572,44 +3576,34 @@
                     zhp->zpool_name));
         return (0);
 }
 
 void
-zpool_set_history_str(const char *subcommand, int argc, char **argv,
-    char *history_str)
+zfs_save_arguments(int argc, char **argv, char *string, int len)
 {
-        int i;
-
-        (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
-        for (i = 1; i < argc; i++) {
-                if (strlen(history_str) + 1 + strlen(argv[i]) >
-                    HIS_MAX_RECORD_LEN)
-                        break;
-                (void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
-                (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
+        (void) strlcpy(string, basename(argv[0]), len);
+        for (int i = 1; i < argc; i++) {
+                (void) strlcat(string, " ", len);
+                (void) strlcat(string, argv[i], len);
         }
 }
 
-/*
- * Stage command history for logging.
- */
 int
-zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
+zpool_log_history(libzfs_handle_t *hdl, const char *message)
 {
-        if (history_str == NULL)
-                return (EINVAL);
-
-        if (strlen(history_str) > HIS_MAX_RECORD_LEN)
-                return (EINVAL);
-
-        if (hdl->libzfs_log_str != NULL)
-                free(hdl->libzfs_log_str);
-
-        if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
-                return (no_memory(hdl));
+        zfs_cmd_t zc = { 0 };
+        nvlist_t *args;
+        int err;
 
-        return (0);
+        args = fnvlist_alloc();
+        fnvlist_add_string(args, "message", message);
+        err = zcmd_write_src_nvlist(hdl, &zc, args);
+        if (err == 0)
+                err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
+        nvlist_free(args);
+        zcmd_free_nvlists(&zc);
+        return (err);
 }
 
 /*
  * Perform ioctl to get some command history of a pool.
  *