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>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzfs/common/libzfs_pool.c
          +++ new/usr/src/lib/libzfs/common/libzfs_pool.c
↓ open down ↓ 26 lines elided ↑ open up ↑
  27   27  
  28   28  #include <ctype.h>
  29   29  #include <errno.h>
  30   30  #include <devid.h>
  31   31  #include <fcntl.h>
  32   32  #include <libintl.h>
  33   33  #include <stdio.h>
  34   34  #include <stdlib.h>
  35   35  #include <strings.h>
  36   36  #include <unistd.h>
       37 +#include <libgen.h>
  37   38  #include <sys/efi_partition.h>
  38   39  #include <sys/vtoc.h>
  39   40  #include <sys/zfs_ioctl.h>
  40   41  #include <dlfcn.h>
  41   42  
  42   43  #include "zfs_namecheck.h"
  43   44  #include "zfs_prop.h"
  44   45  #include "libzfs_impl.h"
  45   46  #include "zfs_comutil.h"
  46   47  #include "zfeature_common.h"
↓ open down ↓ 1151 lines elided ↑ open up ↑
1198 1199          nvlist_free(zc_props);
1199 1200          nvlist_free(zc_fsprops);
1200 1201          return (ret);
1201 1202  }
1202 1203  
1203 1204  /*
1204 1205   * Destroy the given pool.  It is up to the caller to ensure that there are no
1205 1206   * datasets left in the pool.
1206 1207   */
1207 1208  int
1208      -zpool_destroy(zpool_handle_t *zhp)
     1209 +zpool_destroy(zpool_handle_t *zhp, const char *log_str)
1209 1210  {
1210 1211          zfs_cmd_t zc = { 0 };
1211 1212          zfs_handle_t *zfp = NULL;
1212 1213          libzfs_handle_t *hdl = zhp->zpool_hdl;
1213 1214          char msg[1024];
1214 1215  
1215 1216          if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1216 1217              (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
1217 1218                  return (-1);
1218 1219  
1219 1220          (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
     1221 +        zc.zc_history = (uint64_t)(uintptr_t)log_str;
1220 1222  
1221 1223          if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1222 1224                  (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1223 1225                      "cannot destroy '%s'"), zhp->zpool_name);
1224 1226  
1225 1227                  if (errno == EROFS) {
1226 1228                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1227 1229                              "one or more devices is read only"));
1228 1230                          (void) zfs_error(hdl, EZFS_BADDEV, msg);
1229 1231                  } else {
↓ open down ↓ 134 lines elided ↑ open up ↑
1364 1366  
1365 1367          zcmd_free_nvlists(&zc);
1366 1368  
1367 1369          return (ret);
1368 1370  }
1369 1371  
1370 1372  /*
1371 1373   * Exports the pool from the system.  The caller must ensure that there are no
1372 1374   * mounted datasets in the pool.
1373 1375   */
1374      -int
1375      -zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
     1376 +static int
     1377 +zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
     1378 +    const char *log_str)
1376 1379  {
1377 1380          zfs_cmd_t zc = { 0 };
1378 1381          char msg[1024];
1379 1382  
1380 1383          (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1381 1384              "cannot export '%s'"), zhp->zpool_name);
1382 1385  
1383 1386          (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1384 1387          zc.zc_cookie = force;
1385 1388          zc.zc_guid = hardforce;
     1389 +        zc.zc_history = (uint64_t)(uintptr_t)log_str;
1386 1390  
1387 1391          if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
1388 1392                  switch (errno) {
1389 1393                  case EXDEV:
1390 1394                          zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
1391 1395                              "use '-f' to override the following errors:\n"
1392 1396                              "'%s' has an active shared spare which could be"
1393 1397                              " used by other pools once '%s' is exported."),
1394 1398                              zhp->zpool_name, zhp->zpool_name);
1395 1399                          return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
↓ open down ↓ 1 lines elided ↑ open up ↑
1397 1401                  default:
1398 1402                          return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
1399 1403                              msg));
1400 1404                  }
1401 1405          }
1402 1406  
1403 1407          return (0);
1404 1408  }
1405 1409  
1406 1410  int
1407      -zpool_export(zpool_handle_t *zhp, boolean_t force)
     1411 +zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
1408 1412  {
1409      -        return (zpool_export_common(zhp, force, B_FALSE));
     1413 +        return (zpool_export_common(zhp, force, B_FALSE, log_str));
1410 1414  }
1411 1415  
1412 1416  int
1413      -zpool_export_force(zpool_handle_t *zhp)
     1417 +zpool_export_force(zpool_handle_t *zhp, const char *log_str)
1414 1418  {
1415      -        return (zpool_export_common(zhp, B_TRUE, B_TRUE));
     1419 +        return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
1416 1420  }
1417 1421  
1418 1422  static void
1419 1423  zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1420 1424      nvlist_t *config)
1421 1425  {
1422 1426          nvlist_t *nv = NULL;
1423 1427          uint64_t rewindto;
1424 1428          int64_t loss = -1;
1425 1429          struct tm t;
↓ open down ↓ 2141 lines elided ↑ open up ↑
3567 3571          zc.zc_cookie = new_version;
3568 3572  
3569 3573          if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
3570 3574                  return (zpool_standard_error_fmt(hdl, errno,
3571 3575                      dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
3572 3576                      zhp->zpool_name));
3573 3577          return (0);
3574 3578  }
3575 3579  
3576 3580  void
3577      -zpool_set_history_str(const char *subcommand, int argc, char **argv,
3578      -    char *history_str)
     3581 +zfs_save_arguments(int argc, char **argv, char *string, int len)
3579 3582  {
3580      -        int i;
3581      -
3582      -        (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
3583      -        for (i = 1; i < argc; i++) {
3584      -                if (strlen(history_str) + 1 + strlen(argv[i]) >
3585      -                    HIS_MAX_RECORD_LEN)
3586      -                        break;
3587      -                (void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN);
3588      -                (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
     3583 +        (void) strlcpy(string, basename(argv[0]), len);
     3584 +        for (int i = 1; i < argc; i++) {
     3585 +                (void) strlcat(string, " ", len);
     3586 +                (void) strlcat(string, argv[i], len);
3589 3587          }
3590 3588  }
3591 3589  
3592      -/*
3593      - * Stage command history for logging.
3594      - */
3595 3590  int
3596      -zpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
     3591 +zpool_log_history(libzfs_handle_t *hdl, const char *message)
3597 3592  {
3598      -        if (history_str == NULL)
3599      -                return (EINVAL);
3600      -
3601      -        if (strlen(history_str) > HIS_MAX_RECORD_LEN)
3602      -                return (EINVAL);
3603      -
3604      -        if (hdl->libzfs_log_str != NULL)
3605      -                free(hdl->libzfs_log_str);
3606      -
3607      -        if ((hdl->libzfs_log_str = strdup(history_str)) == NULL)
3608      -                return (no_memory(hdl));
     3593 +        zfs_cmd_t zc = { 0 };
     3594 +        nvlist_t *args;
     3595 +        int err;
3609 3596  
3610      -        return (0);
     3597 +        args = fnvlist_alloc();
     3598 +        fnvlist_add_string(args, "message", message);
     3599 +        err = zcmd_write_src_nvlist(hdl, &zc, args);
     3600 +        if (err == 0)
     3601 +                err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
     3602 +        nvlist_free(args);
     3603 +        zcmd_free_nvlists(&zc);
     3604 +        return (err);
3611 3605  }
3612 3606  
3613 3607  /*
3614 3608   * Perform ioctl to get some command history of a pool.
3615 3609   *
3616 3610   * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
3617 3611   * logical offset of the history buffer to start reading from.
3618 3612   *
3619 3613   * Upon return, 'off' is the next logical offset to read from and
3620 3614   * 'len' is the actual amount of bytes read into 'buf'.
↓ open down ↓ 464 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX