Print this page
MFV: illumos-gate@f62db44dbcda5dd786bb821f1e6fd3ca2e6d4391
9616 Bogus error when attempting to set property on read-only pool
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matt Ahrens <matt@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
8520 lzc_rollback_to should support rolling back to origin
7198 libzfs should gracefully handle EINVAL from lzc_rollback
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
NEX-16502 libshare needs to support SMB in a zone
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-9406 Add a property to show that a dataset has been modified since a snapshot
Reviewed by: Alexey Komarov <alexey.komarov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-9436 Rate limiting controls (was QoS) per ZFS dataset, updates from demo
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-8852 Quality-of-Service (QoS) controls per NFS share
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-5795 Rename 'wrc' as 'wbc' in the source and in the tech docs
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-5060 WBC: Writecache and deduplication should not be used together
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-4830 writecache=off leaks data on special vdev (the data will never migrate)
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
6298 zfs_create_008_neg and zpool_create_023_neg need to be updated for large block support
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
2605 want to resume interrupted zfs send
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Xin Li <delphij@freebsd.org>
Reviewed by: Arne Jansen <sensille@gmx.net>
Approved by: Dan McDonald <danmcd@omniti.com>
4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R (fix studio build)
4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Garrett D'Amore <garrett@damore.org>
5813 zfs_setprop_error(): Handle errno value E2BIG.
Reviewed by: Paul Dagnelie <paul.dagnelie@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Richard Elling <richard.elling@richardelling.com>
Approved by: Garrett D'Amore <garrett@damore.org>
5745 zfs set allows only one dataset property to be set at a time
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com>
Reviewed by: Richard PALO <richard@NetBSD.org>
Reviewed by: Steven Hartland <killing@multiplay.co.uk>
Approved by: Rich Lowe <richlowe@richlowe.net>
NEX-4476 WRC: Allow to use write back cache per tree of datasets
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Revert "NEX-4476 WRC: Allow to use write back cache per tree of datasets"
This reverts commit fe97b74444278a6f36fec93179133641296312da.
NEX-4476 WRC: Allow to use write back cache per tree of datasets
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-4043 Renaming of autosnaps is not handled correctly
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3669 Faults for fans that don't exist
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
NEX-3891 Hide the snapshots that belong to in-kernel autosnap-service
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek@nexenta.com>
NEX-3558 KRRP Integration
NEX-2848 memory leak in the zfs_release() library call path
NEX-1456 Part 2, port FreeBSD patch - new zfs recv options support
SUP-642 Regression leading to AD usernames not being displayed by zfs userspace command.
re #8279 rb3915 need a mechanism to notify NMS about ZFS config changes (Opened code)

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzfs/common/libzfs_dataset.c
          +++ new/usr/src/lib/libzfs/common/libzfs_dataset.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + */
       25 +
       26 +/*
  24   27   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25   28   * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  26   29   * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
  27   30   * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
  28   31   * Copyright (c) 2013 Martin Matuska. All rights reserved.
  29   32   * Copyright (c) 2013 Steven Hartland. All rights reserved.
  30   33   * Copyright (c) 2014 Integros [integros.com]
  31      - * Copyright 2017 Nexenta Systems, Inc.
       34 + * Copyright 2018 Nexenta Systems, Inc.
  32   35   * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  33      - * Copyright 2017 RackTop Systems.
       36 + * Copyright 2017-2018 RackTop Systems.
  34   37   */
  35   38  
  36   39  #include <ctype.h>
  37   40  #include <errno.h>
  38   41  #include <libintl.h>
  39   42  #include <math.h>
  40   43  #include <stdio.h>
  41   44  #include <stdlib.h>
  42   45  #include <strings.h>
  43   46  #include <unistd.h>
↓ open down ↓ 13 lines elided ↑ open up ↑
  57   60  
  58   61  #include <sys/dnode.h>
  59   62  #include <sys/spa.h>
  60   63  #include <sys/zap.h>
  61   64  #include <libzfs.h>
  62   65  
  63   66  #include "zfs_namecheck.h"
  64   67  #include "zfs_prop.h"
  65   68  #include "libzfs_impl.h"
  66   69  #include "zfs_deleg.h"
       70 +#include "zfs_errno.h"
  67   71  
  68   72  static int userquota_propname_decode(const char *propname, boolean_t zoned,
  69   73      zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
  70   74  
  71   75  /*
  72   76   * Given a single type (not a mask of types), return the type in a human
  73   77   * readable form.
  74   78   */
  75   79  const char *
  76   80  zfs_type_to_name(zfs_type_t type)
↓ open down ↓ 358 lines elided ↑ open up ↑
 435  439           * We've managed to open the dataset and gather statistics.  Determine
 436  440           * the high-level type.
 437  441           */
 438  442          if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
 439  443                  zhp->zfs_head_type = ZFS_TYPE_VOLUME;
 440  444          else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
 441  445                  zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
 442  446          else
 443  447                  abort();
 444  448  
 445      -        if (zhp->zfs_dmustats.dds_is_snapshot)
      449 +        if (zhp->zfs_dmustats.dds_is_autosnapshot)
      450 +                zhp->zfs_type = ZFS_TYPE_AUTOSNAP;
      451 +        else if (zhp->zfs_dmustats.dds_is_snapshot)
 446  452                  zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
 447  453          else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
 448  454                  zhp->zfs_type = ZFS_TYPE_VOLUME;
 449  455          else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
 450  456                  zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
 451  457          else
 452  458                  abort();        /* we should never see any other types */
 453  459  
 454  460          if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
 455  461                  return (-1);
↓ open down ↓ 799 lines elided ↑ open up ↑
1255 1261                  case ZFS_PROP_SHARENFS:
1256 1262                          /*
1257 1263                           * For the mountpoint and sharenfs or sharesmb
1258 1264                           * properties, check if it can be set in a
1259 1265                           * global/non-global zone based on
1260 1266                           * the zoned property value:
1261 1267                           *
1262 1268                           *              global zone         non-global zone
1263 1269                           * --------------------------------------------------
1264 1270                           * zoned=on     mountpoint (no)     mountpoint (yes)
1265      -                         *              sharenfs (no)       sharenfs (no)
     1271 +                         *              sharenfs (no)       sharenfs (yes)
1266 1272                           *              sharesmb (no)       sharesmb (no)
1267 1273                           *
1268 1274                           * zoned=off    mountpoint (yes)        N/A
1269 1275                           *              sharenfs (yes)
1270 1276                           *              sharesmb (yes)
1271 1277                           */
1272 1278                          if (zoned) {
1273 1279                                  if (getzoneid() == GLOBAL_ZONEID) {
1274 1280                                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1275 1281                                              "'%s' cannot be set on "
1276 1282                                              "dataset in a non-global zone"),
1277 1283                                              propname);
1278 1284                                          (void) zfs_error(hdl, EZFS_ZONED,
1279 1285                                              errbuf);
1280 1286                                          goto error;
1281      -                                } else if (prop == ZFS_PROP_SHARENFS ||
1282      -                                    prop == ZFS_PROP_SHARESMB) {
1283      -                                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1284      -                                            "'%s' cannot be set in "
1285      -                                            "a non-global zone"), propname);
1286      -                                        (void) zfs_error(hdl, EZFS_ZONED,
1287      -                                            errbuf);
1288      -                                        goto error;
1289 1287                                  }
1290 1288                          } else if (getzoneid() != GLOBAL_ZONEID) {
1291 1289                                  /*
1292 1290                                   * If zoned property is 'off', this must be in
1293 1291                                   * a global zone. If not, something is wrong.
1294 1292                                   */
1295 1293                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1296 1294                                      "'%s' cannot be set while dataset "
1297 1295                                      "'zoned' property is set"), propname);
1298 1296                                  (void) zfs_error(hdl, EZFS_ZONED, errbuf);
↓ open down ↓ 251 lines elided ↑ open up ↑
1550 1548          case ENOTSUP:
1551 1549                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1552 1550                      "pool and or dataset must be upgraded to set this "
1553 1551                      "property or value"));
1554 1552                  (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1555 1553                  break;
1556 1554  
1557 1555          case ERANGE:
1558 1556                  if (prop == ZFS_PROP_COMPRESSION ||
1559 1557                      prop == ZFS_PROP_RECORDSIZE) {
1560      -                        (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1558 +                        (void) zfs_error_aux(hdl,
     1559 +                            dgettext(TEXT_DOMAIN,
1561 1560                              "property setting is not allowed on "
1562 1561                              "bootable datasets"));
1563 1562                          (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1564 1563                  } else if (prop == ZFS_PROP_CHECKSUM ||
1565 1564                      prop == ZFS_PROP_DEDUP) {
1566 1565                          (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1567 1566                              "property setting is not allowed on "
1568 1567                              "root pools"));
1569 1568                          (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1570 1569                  } else {
↓ open down ↓ 2 lines elided ↑ open up ↑
1573 1572                  break;
1574 1573  
1575 1574          case EINVAL:
1576 1575                  if (prop == ZPROP_INVAL) {
1577 1576                          (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1578 1577                  } else {
1579 1578                          (void) zfs_standard_error(hdl, err, errbuf);
1580 1579                  }
1581 1580                  break;
1582 1581  
     1582 +        case EKZFS_WBCCONFLICT:
     1583 +                if (prop == ZFS_PROP_WBC_MODE || prop == ZFS_PROP_DEDUP) {
     1584 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1585 +                            "WBC and deduplication cannot be "
     1586 +                            "active simultaneously on the "
     1587 +                            "same dataset"));
     1588 +                        (void) zfs_error(hdl, EZFS_WBCNOTSUP, errbuf);
     1589 +                } else {
     1590 +                        (void) zfs_standard_error(hdl, err, errbuf);
     1591 +                }
     1592 +
     1593 +                break;
     1594 +
1583 1595          case EOVERFLOW:
1584 1596                  /*
1585 1597                   * This platform can't address a volume this big.
1586 1598                   */
1587 1599  #ifdef _ILP32
1588 1600                  if (prop == ZFS_PROP_VOLSIZE) {
1589 1601                          (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1590 1602                          break;
1591 1603                  }
1592 1604  #endif
1593 1605                  /* FALLTHROUGH */
1594 1606          default:
1595      -                (void) zfs_standard_error(hdl, err, errbuf);
     1607 +                if (prop != ZFS_PROP_WBC_MODE) {
     1608 +                        (void) zfs_standard_error(hdl, err, errbuf);
     1609 +                        break;
     1610 +                }
     1611 +
     1612 +                switch (err) {
     1613 +                case EINPROGRESS:
     1614 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1615 +                            "WBC cannot be enabled for the dataset since "
     1616 +                            "the latter is currently in transition to "
     1617 +                            "wbc_mode = off. Try again later"));
     1618 +                        (void) zfs_error(hdl, EZFS_WBCINPROGRESS, errbuf);
     1619 +                        break;
     1620 +                case EALREADY:
     1621 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1622 +                            "WBC is already in the requested (on/off) "
     1623 +                            "state, nothing to do"));
     1624 +                        (void) zfs_error(hdl, EZFS_WBCALREADY, errbuf);
     1625 +                        break;
     1626 +                case EKZFS_WBCNOTSUP:
     1627 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1628 +                            "feature@wbc is not enabled or "
     1629 +                            "special device (special vdev) is not present"));
     1630 +                        (void) zfs_error(hdl, EZFS_WBCNOTSUP, errbuf);
     1631 +                        break;
     1632 +                case EKZFS_WBCCHILD:
     1633 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1634 +                            "a child dataset has this property enabled"));
     1635 +                        (void) zfs_error(hdl, EZFS_WBCCHILD, errbuf);
     1636 +                        break;
     1637 +                case EKZFS_WBCPARENT:
     1638 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1639 +                            "a parent dataset has this property enabled"));
     1640 +                        (void) zfs_error(hdl, EZFS_WBCPARENT, errbuf);
     1641 +                        break;
     1642 +                default:
     1643 +                        (void) zfs_standard_error(hdl, err, errbuf);
     1644 +                        break;
     1645 +                }
1596 1646          }
1597 1647  }
1598 1648  
1599 1649  /*
1600 1650   * Given a property name and value, set the property for the given dataset.
1601 1651   */
1602 1652  int
1603 1653  zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1604 1654  {
1605 1655          int ret = -1;
↓ open down ↓ 113 lines elided ↑ open up ↑
1719 1769           */
1720 1770          (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1721 1771  
1722 1772          if ((ret = zcmd_write_src_nvlist(hdl, &zc, nvl)) != 0 ||
1723 1773              (ret = zcmd_alloc_dst_nvlist(hdl, &zc, 0)) != 0)
1724 1774                  goto error;
1725 1775  
1726 1776          ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1727 1777  
1728 1778          if (ret != 0) {
     1779 +                if (zc.zc_nvlist_dst_filled == B_FALSE) {
     1780 +                        (void) zfs_standard_error(hdl, errno, errbuf);
     1781 +                        goto error;
     1782 +                }
     1783 +
1729 1784                  /* Get the list of unset properties back and report them. */
1730 1785                  nvlist_t *errorprops = NULL;
1731 1786                  if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
1732 1787                          goto error;
1733      -                for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
     1788 +                for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL);
1734 1789                      elem != NULL;
1735      -                    elem = nvlist_next_nvpair(nvl, elem)) {
     1790 +                    elem = nvlist_next_nvpair(errorprops, elem)) {
1736 1791                          zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem));
1737 1792                          zfs_setprop_error(hdl, prop, errno, errbuf);
1738 1793                  }
1739 1794                  nvlist_free(errorprops);
1740 1795  
1741 1796                  if (added_resv && errno == ENOSPC) {
1742 1797                          /* clean up the volsize property we tried to set */
1743 1798                          uint64_t old_volsize = zfs_prop_get_int(zhp,
1744 1799                              ZFS_PROP_VOLSIZE);
1745 1800                          nvlist_free(nvl);
↓ open down ↓ 81 lines elided ↑ open up ↑
1827 1882          /*
1828 1883           * Verify that this property is inheritable.
1829 1884           */
1830 1885          if (zfs_prop_readonly(prop))
1831 1886                  return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1832 1887  
1833 1888          if (!zfs_prop_inheritable(prop) && !received)
1834 1889                  return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1835 1890  
1836 1891          /*
     1892 +         * This property is inheritable by nature,
     1893 +         * but user can do only "set" operation,
     1894 +         * because "inherit" does not make sence
     1895 +         */
     1896 +        if (prop == ZFS_PROP_WBC_MODE)
     1897 +                return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
     1898 +
     1899 +        /*
1837 1900           * Check to see if the value applies to this type
1838 1901           */
1839 1902          if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1840 1903                  return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1841 1904  
1842 1905          /*
1843 1906           * Normalize the name, to get rid of shorthand abbreviations.
1844 1907           */
1845 1908          propname = zfs_prop_to_name(prop);
1846 1909          (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
↓ open down ↓ 221 lines elided ↑ open up ↑
2068 2131          case ZFS_PROP_CANMOUNT:
2069 2132          case ZFS_PROP_VOLSIZE:
2070 2133          case ZFS_PROP_QUOTA:
2071 2134          case ZFS_PROP_REFQUOTA:
2072 2135          case ZFS_PROP_RESERVATION:
2073 2136          case ZFS_PROP_REFRESERVATION:
2074 2137          case ZFS_PROP_FILESYSTEM_LIMIT:
2075 2138          case ZFS_PROP_SNAPSHOT_LIMIT:
2076 2139          case ZFS_PROP_FILESYSTEM_COUNT:
2077 2140          case ZFS_PROP_SNAPSHOT_COUNT:
     2141 +        case ZFS_PROP_RATE_LIMIT:
2078 2142                  *val = getprop_uint64(zhp, prop, source);
2079 2143  
2080 2144                  if (*source == NULL) {
2081 2145                          /* not default, must be local */
2082 2146                          *source = zhp->zfs_name;
2083 2147                  }
2084 2148                  break;
2085 2149  
2086 2150          case ZFS_PROP_MOUNTED:
2087 2151                  *val = (zhp->zfs_mntopts != NULL);
↓ open down ↓ 458 lines elided ↑ open up ↑
2546 2610                          else
2547 2611                                  zfs_nicenum(val, propbuf, proplen);
2548 2612                  }
2549 2613                  zcp_check(zhp, prop, val, NULL);
2550 2614                  break;
2551 2615  
2552 2616          case ZFS_PROP_FILESYSTEM_LIMIT:
2553 2617          case ZFS_PROP_SNAPSHOT_LIMIT:
2554 2618          case ZFS_PROP_FILESYSTEM_COUNT:
2555 2619          case ZFS_PROP_SNAPSHOT_COUNT:
     2620 +        case ZFS_PROP_RATE_LIMIT:
2556 2621  
2557 2622                  if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2558 2623                          return (-1);
2559 2624  
2560 2625                  /*
2561 2626                   * If limit is UINT64_MAX, we translate this into 'none' (unless
2562 2627                   * literal is set), and indicate that it's the default value.
2563 2628                   * Otherwise, we print the number nicely and indicate that it's
2564 2629                   * set locally.
2565 2630                   */
↓ open down ↓ 23 lines elided ↑ open up ↑
2589 2654                  switch (zhp->zfs_type) {
2590 2655                  case ZFS_TYPE_FILESYSTEM:
2591 2656                          str = "filesystem";
2592 2657                          break;
2593 2658                  case ZFS_TYPE_VOLUME:
2594 2659                          str = "volume";
2595 2660                          break;
2596 2661                  case ZFS_TYPE_SNAPSHOT:
2597 2662                          str = "snapshot";
2598 2663                          break;
     2664 +                case ZFS_TYPE_AUTOSNAP:
     2665 +                        str = "autosnap";
     2666 +                        break;
2599 2667                  case ZFS_TYPE_BOOKMARK:
2600 2668                          str = "bookmark";
2601 2669                          break;
2602 2670                  default:
2603 2671                          abort();
2604 2672                  }
2605 2673                  (void) snprintf(propbuf, proplen, "%s", str);
2606 2674                  zcp_check(zhp, prop, NULL, propbuf);
2607 2675                  break;
2608 2676  
↓ open down ↓ 66 lines elided ↑ open up ↑
2675 2743                   * GUIDs are stored as numbers, but they are identifiers.
2676 2744                   * We don't want them to be pretty printed, because pretty
2677 2745                   * printing mangles the ID into a truncated and useless value.
2678 2746                   */
2679 2747                  if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2680 2748                          return (-1);
2681 2749                  (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
2682 2750                  zcp_check(zhp, prop, val, NULL);
2683 2751                  break;
2684 2752  
     2753 +        case ZFS_PROP_MODIFIED:
     2754 +                /*
     2755 +                 * For a snapshot the "modified" pseudo-property is set to
     2756 +                 * "yes" if parent filesystem/zvol differs from the snapshot.
     2757 +                 * Even though it's a boolean value, the typical
     2758 +                 * values of "on" and "off" don't make sense, so we translate
     2759 +                 * to "yes" and "no".
     2760 +                 */
     2761 +                if (get_numeric_property(zhp, ZFS_PROP_MODIFIED,
     2762 +                    src, &source, &val) != 0)
     2763 +                        return (-1);
     2764 +                if (val != 0)
     2765 +                        (void) strlcpy(propbuf, "yes", proplen);
     2766 +                else
     2767 +                        (void) strlcpy(propbuf, "no", proplen);
     2768 +                break;
     2769 +
2685 2770          default:
2686 2771                  switch (zfs_prop_get_type(prop)) {
2687 2772                  case PROP_TYPE_NUMBER:
2688 2773                          if (get_numeric_property(zhp, prop, src,
2689 2774                              &source, &val) != 0) {
2690 2775                                  return (-1);
2691 2776                          }
2692 2777  
2693 2778                          if (literal) {
2694 2779                                  (void) snprintf(propbuf, proplen, "%llu",
↓ open down ↓ 440 lines elided ↑ open up ↑
3135 3220  }
3136 3221  
3137 3222  /*
3138 3223   * If accept_ancestor is false, then check to make sure that the given path has
3139 3224   * a parent, and that it exists.  If accept_ancestor is true, then find the
3140 3225   * closest existing ancestor for the given path.  In prefixlen return the
3141 3226   * length of already existing prefix of the given path.  We also fetch the
3142 3227   * 'zoned' property, which is used to validate property settings when creating
3143 3228   * new datasets.
3144 3229   */
3145      -static int
     3230 +int
3146 3231  check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
3147 3232      boolean_t accept_ancestor, int *prefixlen)
3148 3233  {
3149 3234          zfs_cmd_t zc = { 0 };
3150 3235          char parent[ZFS_MAX_DATASET_NAME_LEN];
3151 3236          char *slash;
3152 3237          zfs_handle_t *zhp;
3153 3238          char errbuf[1024];
3154 3239          uint64_t is_zoned;
3155 3240  
↓ open down ↓ 291 lines elided ↑ open up ↑
3447 3532                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3448 3533                              "volume size must be a multiple of volume block "
3449 3534                              "size"));
3450 3535                          return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3451 3536                  }
3452 3537          }
3453 3538  
3454 3539          /* create the dataset */
3455 3540          ret = lzc_create(path, ost, props);
3456 3541          nvlist_free(props);
     3542 +        if (ret == 0)
     3543 +                libzfs_log_event(hdl, path);
3457 3544  
3458 3545          /* check for failure */
3459 3546          if (ret != 0) {
3460 3547                  char parent[ZFS_MAX_DATASET_NAME_LEN];
3461 3548                  (void) parent_name(path, parent, sizeof (parent));
3462 3549  
3463 3550                  switch (errno) {
3464 3551                  case ENOENT:
3465 3552                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3466 3553                              "no such parent '%s'"), parent);
↓ open down ↓ 24 lines elided ↑ open up ↑
3491 3578  #endif
3492 3579                          /* FALLTHROUGH */
3493 3580                  default:
3494 3581                          return (zfs_standard_error(hdl, errno, errbuf));
3495 3582                  }
3496 3583          }
3497 3584  
3498 3585          return (0);
3499 3586  }
3500 3587  
     3588 +int
     3589 +zfs_check_krrp(libzfs_handle_t *hdl, const char *name)
     3590 +{
     3591 +        zfs_cmd_t zc = { 0 };
     3592 +        int err;
     3593 +
     3594 +        (void) strncpy(zc.zc_name, name, ZFS_MAX_DATASET_NAME_LEN);
     3595 +        zc.zc_name[ZFS_MAX_DATASET_NAME_LEN - 1] = '\0';
     3596 +
     3597 +        (void) zfs_ioctl(hdl, ZFS_IOC_CHECK_KRRP, &zc);
     3598 +        err = errno;
     3599 +
     3600 +        free((void *)(uintptr_t)zc.zc_nvlist_dst);
     3601 +
     3602 +        return (err);
     3603 +}
     3604 +
     3605 +int
     3606 +zfs_destroy_atomically(zfs_handle_t *zhp, boolean_t defer)
     3607 +{
     3608 +        zfs_cmd_t zc = { 0 };
     3609 +
     3610 +        if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
     3611 +                nvlist_t *nv = fnvlist_alloc();
     3612 +                fnvlist_add_boolean(nv, zhp->zfs_name);
     3613 +                int error = lzc_destroy_bookmarks(nv, NULL);
     3614 +                fnvlist_free(nv);
     3615 +                if (error != 0) {
     3616 +                        return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
     3617 +                            dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
     3618 +                            zhp->zfs_name));
     3619 +                }
     3620 +                return (0);
     3621 +        }
     3622 +
     3623 +        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
     3624 +
     3625 +        if (ZFS_IS_VOLUME(zhp)) {
     3626 +                zc.zc_objset_type = DMU_OST_ZVOL;
     3627 +        } else {
     3628 +                zc.zc_objset_type = DMU_OST_ZFS;
     3629 +        }
     3630 +
     3631 +        zc.zc_defer_destroy = defer;
     3632 +        zc.zc_guid = B_TRUE;
     3633 +        if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0 &&
     3634 +            errno != ENOENT) {
     3635 +                return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
     3636 +                    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
     3637 +                    zhp->zfs_name));
     3638 +        }
     3639 +
     3640 +        remove_mountpoint(zhp);
     3641 +
     3642 +        return (0);
     3643 +
     3644 +}
     3645 +
3501 3646  /*
3502 3647   * Destroys the given dataset.  The caller must make sure that the filesystem
3503 3648   * isn't mounted, and that there are no active dependents. If the file system
3504 3649   * does not exist this function does nothing.
3505 3650   */
3506 3651  int
3507 3652  zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
3508 3653  {
3509 3654          zfs_cmd_t zc = { 0 };
3510 3655  
↓ open down ↓ 78 lines elided ↑ open up ↑
3589 3734          return (ret);
3590 3735  }
3591 3736  
3592 3737  /*
3593 3738   * Destroys all the snapshots named in the nvlist.
3594 3739   */
3595 3740  int
3596 3741  zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
3597 3742  {
3598 3743          int ret;
     3744 +        nvpair_t *elem;
3599 3745          nvlist_t *errlist = NULL;
3600 3746  
3601 3747          ret = lzc_destroy_snaps(snaps, defer, &errlist);
     3748 +        if (ret == 0) {
     3749 +                for (elem = nvlist_next_nvpair(snaps, NULL); elem != NULL;
     3750 +                    elem = nvlist_next_nvpair(snaps, elem))
     3751 +                        libzfs_log_event(hdl, nvpair_name(elem));
     3752 +        }
3602 3753  
3603 3754          if (ret == 0) {
3604 3755                  nvlist_free(errlist);
3605 3756                  return (0);
3606 3757          }
3607 3758  
3608 3759          if (nvlist_empty(errlist)) {
3609 3760                  char errbuf[1024];
3610 3761                  (void) snprintf(errbuf, sizeof (errbuf),
3611 3762                      dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
↓ open down ↓ 59 lines elided ↑ open up ↑
3671 3822                  } else {
3672 3823                          type = ZFS_TYPE_FILESYSTEM;
3673 3824                  }
3674 3825                  if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3675 3826                      zhp, zhp->zpool_hdl, errbuf)) == NULL)
3676 3827                          return (-1);
3677 3828          }
3678 3829  
3679 3830          ret = lzc_clone(target, zhp->zfs_name, props);
3680 3831          nvlist_free(props);
     3832 +        if (ret == 0)
     3833 +                libzfs_log_event(hdl, target);
3681 3834  
3682 3835          if (ret != 0) {
3683 3836                  switch (errno) {
3684 3837  
3685 3838                  case ENOENT:
3686 3839                          /*
3687 3840                           * The parent doesn't exist.  We should have caught this
3688 3841                           * above, but there may a race condition that has since
3689 3842                           * destroyed the parent.
3690 3843                           *
↓ open down ↓ 39 lines elided ↑ open up ↑
3730 3883                      "snapshots can not be promoted"));
3731 3884                  return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3732 3885          }
3733 3886  
3734 3887          if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
3735 3888                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3736 3889                      "not a cloned filesystem"));
3737 3890                  return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3738 3891          }
3739 3892  
3740      -        if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
3741      -                return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3742      -
3743 3893          ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
3744 3894  
3745 3895          if (ret != 0) {
3746 3896                  switch (ret) {
3747 3897                  case EEXIST:
3748 3898                          /* There is a conflicting snapshot name. */
3749 3899                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3750 3900                              "conflicting snapshot '%s' from parent '%s'"),
3751 3901                              snapname, zhp->zfs_dmustats.dds_origin);
3752 3902                          return (zfs_error(hdl, EZFS_EXISTS, errbuf));
↓ open down ↓ 23 lines elided ↑ open up ↑
3776 3926  
3777 3927                  fnvlist_add_boolean(sd->sd_nvl, name);
3778 3928  
3779 3929                  rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
3780 3930          }
3781 3931          zfs_close(zhp);
3782 3932  
3783 3933          return (rv);
3784 3934  }
3785 3935  
3786      -int
3787      -zfs_remap_indirects(libzfs_handle_t *hdl, const char *fs)
3788      -{
3789      -        int err;
3790      -        char errbuf[1024];
3791      -
3792      -        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3793      -            "cannot remap filesystem '%s' "), fs);
3794      -
3795      -        err = lzc_remap(fs);
3796      -
3797      -        if (err != 0) {
3798      -                (void) zfs_standard_error(hdl, err, errbuf);
3799      -        }
3800      -
3801      -        return (err);
3802      -}
3803      -
3804 3936  /*
3805 3937   * Creates snapshots.  The keys in the snaps nvlist are the snapshots to be
3806 3938   * created.
3807 3939   */
3808 3940  int
3809 3941  zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
3810 3942  {
3811 3943          int ret;
3812 3944          char errbuf[1024];
3813 3945          nvpair_t *elem;
↓ open down ↓ 28 lines elided ↑ open up ↑
3842 3974  
3843 3975          if (props != NULL &&
3844 3976              (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3845 3977              props, B_FALSE, NULL, zpool_hdl, errbuf)) == NULL) {
3846 3978                  zpool_close(zpool_hdl);
3847 3979                  return (-1);
3848 3980          }
3849 3981          zpool_close(zpool_hdl);
3850 3982  
3851 3983          ret = lzc_snapshot(snaps, props, &errors);
     3984 +        if (ret == 0) {
     3985 +                for (elem = nvlist_next_nvpair(snaps, NULL); elem != NULL;
     3986 +                    elem = nvlist_next_nvpair(snaps, elem))
     3987 +                        libzfs_log_event(hdl, nvpair_name(elem));
     3988 +        }
3852 3989  
3853 3990          if (ret != 0) {
3854 3991                  boolean_t printed = B_FALSE;
3855 3992                  for (elem = nvlist_next_nvpair(errors, NULL);
3856 3993                      elem != NULL;
3857 3994                      elem = nvlist_next_nvpair(errors, elem)) {
3858 3995                          (void) snprintf(errbuf, sizeof (errbuf),
3859 3996                              dgettext(TEXT_DOMAIN,
3860 3997                              "cannot create snapshot '%s'"), nvpair_name(elem));
3861 3998                          (void) zfs_standard_error(hdl,
↓ open down ↓ 228 lines elided ↑ open up ↑
4090 4227          libzfs_handle_t *hdl = zhp->zfs_hdl;
4091 4228          char errbuf[1024];
4092 4229  
4093 4230          /* if we have the same exact name, just return success */
4094 4231          if (strcmp(zhp->zfs_name, target) == 0)
4095 4232                  return (0);
4096 4233  
4097 4234          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4098 4235              "cannot rename to '%s'"), target);
4099 4236  
4100      -        /* make sure source name is valid */
4101      -        if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
4102      -                return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
     4237 +        if (zhp->zfs_type == ZFS_TYPE_AUTOSNAP) {
     4238 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     4239 +                            "autosnapshots cannot be renamed"));
     4240 +                        return (zfs_error(hdl, EZFS_PERM, errbuf));
     4241 +        }
4103 4242  
4104 4243          /*
4105 4244           * Make sure the target name is valid
4106 4245           */
4107 4246          if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4108 4247                  if ((strchr(target, '@') == NULL) ||
4109 4248                      *target == '@') {
4110 4249                          /*
4111 4250                           * Snapshot target name is abbreviated,
4112 4251                           * reconstruct full dataset name
↓ open down ↓ 589 lines elided ↑ open up ↑
4702 4841                  ha->error = ENOENT;
4703 4842          } else if (!nvlist_exists(existing_holds, ha->tag)) {
4704 4843                  ha->error = ESRCH;
4705 4844          } else {
4706 4845                  nvlist_t *torelease = fnvlist_alloc();
4707 4846                  fnvlist_add_boolean(torelease, ha->tag);
4708 4847                  fnvlist_add_nvlist(ha->nvl, name, torelease);
4709 4848                  fnvlist_free(torelease);
4710 4849          }
4711 4850  
     4851 +        fnvlist_free(existing_holds);
     4852 +
4712 4853          if (ha->recursive)
4713 4854                  rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
4714 4855          zfs_close(zhp);
4715 4856          return (rv);
4716 4857  }
4717 4858  
4718 4859  int
4719 4860  zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
4720 4861      boolean_t recursive)
4721 4862  {
↓ open down ↓ 275 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX