Print this page
NEX-5063 Passing invalid trim rate to zpool(1M) coredumps
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
6328 Fix cstyle errors in zfs codebase (fix studio)
6328 Fix cstyle errors in zfs codebase
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Jorgen Lundman <lundman@lundman.net>
Approved by: Robert Mustacchi <rm@joyent.com>
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>
5692 expose the number of hole blocks in a file
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Boris Protopopov <bprotopopov@hotmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-4336 zpool vdev-get with an unsuported prop name core dumps
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3558 KRRP Integration
OS-103 handle CoS descriptor persistent references across vdev operations
OS-102 add man page info and tests for vdev/CoS properties and ZFS meta features
Moved closed ZFS files to open repo, changed Makefiles accordingly
Removed unneeded weak symbols
re #8279 rb3915 need a mechanism to notify NMS about ZFS config changes (fix lint -courtesy of Yuri Pankov)
re #12584 rb4049 zfsxx latest code merge (fix lint - courtesy of Yuri Pankov)
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
re #8279 rb3915 need a mechanism to notify NMS about ZFS config changes (Opened code)
Bug 11205: add missing libzfs_closed_stubs.c to fix opensource-only build.
ZFS plus work: special vdevs, cos, cos/vdev properties

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzfs/common/libzfs_util.c
          +++ new/usr/src/lib/libzfs/common/libzfs_util.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  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   24   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  25   26   * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  26   27   * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  27   28   * Copyright (c) 2017 Datto Inc.
  28   29   */
  29   30  
  30   31  /*
  31   32   * Internal utility routines for the ZFS library.
  32   33   */
  33   34  
  34   35  #include <errno.h>
↓ open down ↓ 193 lines elided ↑ open up ↑
 228  229                  return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
 229  230                      "use 'zpool scrub -s' to cancel current scrub"));
 230  231          case EZFS_NO_SCRUB:
 231  232                  return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
 232  233          case EZFS_DIFF:
 233  234                  return (dgettext(TEXT_DOMAIN, "unable to generate diffs"));
 234  235          case EZFS_DIFFDATA:
 235  236                  return (dgettext(TEXT_DOMAIN, "invalid diff data"));
 236  237          case EZFS_POOLREADONLY:
 237  238                  return (dgettext(TEXT_DOMAIN, "pool is read-only"));
 238      -        case EZFS_NO_PENDING:
 239      -                return (dgettext(TEXT_DOMAIN, "operation is not "
 240      -                    "in progress"));
      239 +        case EZFS_PROPNOTSUP:
      240 +                return (dgettext(TEXT_DOMAIN, "property is not supported"));
      241 +        case EZFS_COSNOTFOUND:
      242 +                return (dgettext(TEXT_DOMAIN, "CoS descriptor not found"));
      243 +        case EZFS_COSEXIST:
      244 +                return (dgettext(TEXT_DOMAIN, "CoS descriptor already exists"));
      245 +        case EZFS_COSREF:
      246 +                return (dgettext(TEXT_DOMAIN,
      247 +                        "CoS descriptor is still referenced"));
 241  248          case EZFS_UNKNOWN:
 242  249                  return (dgettext(TEXT_DOMAIN, "unknown error"));
 243  250          default:
 244  251                  assert(hdl->libzfs_error == 0);
 245  252                  return (dgettext(TEXT_DOMAIN, "no error"));
 246  253          }
 247  254  }
 248  255  
 249  256  /*PRINTFLIKE2*/
 250  257  void
↓ open down ↓ 131 lines elided ↑ open up ↑
 382  389                  break;
 383  390  
 384  391          case EBUSY:
 385  392                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 386  393                      "dataset is busy"));
 387  394                  zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 388  395                  break;
 389  396          case EROFS:
 390  397                  zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 391  398                  break;
      399 +        case EINVAL:
      400 +                zfs_verror(hdl, EZFS_INVALIDNAME, fmt, ap);
      401 +                break;
 392  402          case ENAMETOOLONG:
 393  403                  zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
 394  404                  break;
 395  405          case ENOTSUP:
 396  406                  zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
 397  407                  break;
 398  408          case EAGAIN:
 399  409                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 400  410                      "pool I/O is currently suspended"));
 401  411                  zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
↓ open down ↓ 2 lines elided ↑ open up ↑
 404  414                  zfs_error_aux(hdl, strerror(error));
 405  415                  zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 406  416                  break;
 407  417          }
 408  418  
 409  419          va_end(ap);
 410  420          return (-1);
 411  421  }
 412  422  
 413  423  int
      424 +zpool_vprop_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
      425 +{
      426 +        return (zpool_vprop_standard_error_fmt(hdl, error, "%s", msg));
      427 +}
      428 +
      429 +/*PRINTFLIKE3*/
      430 +int
      431 +zpool_vprop_standard_error_fmt(libzfs_handle_t *hdl, int error,
      432 +    const char *fmt, ...)
      433 +{
      434 +        va_list ap;
      435 +
      436 +        va_start(ap, fmt);
      437 +
      438 +        if (zfs_common_error(hdl, error, fmt, ap) != 0) {
      439 +                va_end(ap);
      440 +                return (-1);
      441 +        }
      442 +
      443 +        switch (error) {
      444 +        case ENOENT:
      445 +                zfs_verror(hdl, EZFS_COSNOTFOUND, fmt, ap);
      446 +                break;
      447 +        case ENOTSUP:
      448 +                zfs_verror(hdl, EZFS_PROPNOTSUP, fmt, ap);
      449 +                break;
      450 +
      451 +        case EEXIST:
      452 +                zfs_verror(hdl, EZFS_COSEXIST, fmt, ap);
      453 +                break;
      454 +        case EBUSY:
      455 +                zfs_verror(hdl, EZFS_COSREF, fmt, ap);
      456 +                break;
      457 +        default:
      458 +                zfs_error_aux(hdl, strerror(error));
      459 +                zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
      460 +                break;
      461 +        }
      462 +
      463 +        va_end(ap);
      464 +        return (-1);
      465 +}
      466 +
      467 +int
 414  468  zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
 415  469  {
 416  470          return (zpool_standard_error_fmt(hdl, error, "%s", msg));
 417  471  }
 418  472  
 419  473  /*PRINTFLIKE3*/
 420  474  int
 421  475  zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
 422  476  {
 423  477          va_list ap;
↓ open down ↓ 16 lines elided ↑ open up ↑
 440  494                  zfs_verror(hdl, EZFS_NOENT, fmt, ap);
 441  495                  break;
 442  496  
 443  497          case EEXIST:
 444  498                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 445  499                      "pool already exists"));
 446  500                  zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
 447  501                  break;
 448  502  
 449  503          case EBUSY:
 450      -                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
      504 +                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
      505 +                    "pool or device is busy"));
 451  506                  zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 452  507                  break;
 453  508  
 454  509          case ENXIO:
 455  510                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 456  511                      "one or more devices is currently unavailable"));
 457  512                  zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
 458  513                  break;
 459  514  
 460  515          case ENAMETOOLONG:
↓ open down ↓ 15 lines elided ↑ open up ↑
 476  531  
 477  532          case EAGAIN:
 478  533                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 479  534                      "pool I/O is currently suspended"));
 480  535                  zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
 481  536                  break;
 482  537  
 483  538          case EROFS:
 484  539                  zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 485  540                  break;
 486      -        /* There is no pending operation to cancel */
 487      -        case ENOTACTIVE:
 488      -                zfs_verror(hdl, EZFS_NO_PENDING, fmt, ap);
 489      -                break;
 490  541  
 491  542          default:
 492  543                  zfs_error_aux(hdl, strerror(error));
 493  544                  zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 494  545          }
 495  546  
 496  547          va_end(ap);
 497  548          return (-1);
 498  549  }
 499  550  
↓ open down ↓ 115 lines elided ↑ open up ↑
 615  666                  (void) close(hdl->libzfs_fd);
 616  667                  (void) fclose(hdl->libzfs_mnttab);
 617  668                  (void) fclose(hdl->libzfs_sharetab);
 618  669                  free(hdl);
 619  670                  return (NULL);
 620  671          }
 621  672  
 622  673          zfs_prop_init();
 623  674          zpool_prop_init();
 624  675          zpool_feature_init();
      676 +        vdev_prop_init();
      677 +        cos_prop_init();
 625  678          libzfs_mnttab_init(hdl);
 626  679  
 627  680          if (getenv("ZFS_PROP_DEBUG") != NULL) {
 628  681                  hdl->libzfs_prop_debug = B_TRUE;
 629  682          }
 630  683  
 631  684          return (hdl);
 632  685  }
 633  686  
 634  687  void
 635  688  libzfs_fini(libzfs_handle_t *hdl)
 636  689  {
 637  690          (void) close(hdl->libzfs_fd);
 638  691          if (hdl->libzfs_mnttab)
 639  692                  (void) fclose(hdl->libzfs_mnttab);
 640  693          if (hdl->libzfs_sharetab)
 641  694                  (void) fclose(hdl->libzfs_sharetab);
      695 +        if (hdl->libzfs_log_str)
      696 +                free(hdl->libzfs_log_str);
 642  697          zfs_uninit_libshare(hdl);
 643  698          zpool_free_handles(hdl);
 644  699          libzfs_fru_clear(hdl, B_TRUE);
 645  700          namespace_clear(hdl);
 646  701          libzfs_mnttab_fini(hdl);
 647  702          libzfs_core_fini();
 648  703          free(hdl);
 649  704  }
 650  705  
 651  706  libzfs_handle_t *
↓ open down ↓ 148 lines elided ↑ open up ↑
 800  855  int
 801  856  zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
 802  857  {
 803  858          if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
 804  859              zc->zc_nvlist_dst_size, nvlp, 0) != 0)
 805  860                  return (no_memory(hdl));
 806  861  
 807  862          return (0);
 808  863  }
 809  864  
      865 +#pragma weak libzfs_log_event = libzfs_log_event_stub
      866 +
      867 +/* ARGSUSED hdl zc */
      868 +void
      869 +libzfs_log_event_stub(libzfs_handle_t *hdl, const char *zc)
      870 +{
      871 +}
      872 +
 810  873  int
 811  874  zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
 812  875  {
 813      -        return (ioctl(hdl->libzfs_fd, request, zc));
      876 +        int error;
      877 +
      878 +        error = ioctl(hdl->libzfs_fd, request, zc);
      879 +        if (error == 0)
      880 +                libzfs_log_event(hdl, zc->zc_name);
      881 +
      882 +        return (error);
 814  883  }
 815  884  
 816  885  /*
 817  886   * ================================================================
 818  887   * API shared by zfs and zpool property management
 819  888   * ================================================================
 820  889   */
 821  890  
 822  891  static void
 823  892  zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
↓ open down ↓ 215 lines elided ↑ open up ↑
1039 1108          const char *ends = "BKMGTPEZ";
1040 1109          int i;
1041 1110  
1042 1111          if (buf[0] == '\0')
1043 1112                  return (0);
1044 1113          for (i = 0; i < strlen(ends); i++) {
1045 1114                  if (toupper(buf[0]) == ends[i])
1046 1115                          break;
1047 1116          }
1048 1117          if (i == strlen(ends)) {
1049      -                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1050      -                    "invalid numeric suffix '%s'"), buf);
     1118 +                if (hdl)
     1119 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1120 +                            "invalid numeric suffix '%s'"), buf);
1051 1121                  return (-1);
1052 1122          }
1053 1123  
1054 1124          /*
1055 1125           * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
1056 1126           * allow 'BB' - that's just weird.
1057 1127           */
1058 1128          if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
1059 1129              toupper(buf[0]) != 'B'))
1060 1130                  return (10*i);
1061 1131  
1062      -        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1063      -            "invalid numeric suffix '%s'"), buf);
     1132 +        if (hdl)
     1133 +                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1134 +                    "invalid numeric suffix '%s'"), buf);
1064 1135          return (-1);
1065 1136  }
1066 1137  
1067 1138  /*
1068 1139   * Convert a string of the form '100G' into a real number.  Used when setting
1069 1140   * properties or creating a volume.  'buf' is used to place an extended error
1070 1141   * message for the caller to use.
1071 1142   */
1072 1143  int
1073 1144  zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
↓ open down ↓ 79 lines elided ↑ open up ↑
1153 1224  zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
1154 1225      zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
1155 1226      const char *errbuf)
1156 1227  {
1157 1228          data_type_t datatype = nvpair_type(elem);
1158 1229          zprop_type_t proptype;
1159 1230          const char *propname;
1160 1231          char *value;
1161 1232          boolean_t isnone = B_FALSE;
1162 1233  
1163      -        if (type == ZFS_TYPE_POOL) {
     1234 +        switch (type) {
     1235 +        case ZFS_TYPE_POOL:
1164 1236                  proptype = zpool_prop_get_type(prop);
1165 1237                  propname = zpool_prop_to_name(prop);
1166      -        } else {
     1238 +                break;
     1239 +        case ZFS_TYPE_VDEV:
     1240 +                proptype = vdev_prop_get_type(prop);
     1241 +                propname = vdev_prop_to_name(prop);
     1242 +                break;
     1243 +        case ZFS_TYPE_COS:
     1244 +                proptype = cos_prop_get_type(prop);
     1245 +                propname = cos_prop_to_name(prop);
     1246 +                break;
     1247 +        default:
1167 1248                  proptype = zfs_prop_get_type(prop);
1168 1249                  propname = zfs_prop_to_name(prop);
1169 1250          }
1170 1251  
1171 1252          /*
1172 1253           * Convert any properties to the internal DSL value types.
1173 1254           */
1174 1255          *svalp = NULL;
1175 1256          *ivalp = 0;
1176 1257  
↓ open down ↓ 307 lines elided ↑ open up ↑
1484 1565          return (0);
1485 1566  }
1486 1567  
1487 1568  int
1488 1569  zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
1489 1570      zfs_type_t type)
1490 1571  {
1491 1572          return (zprop_iter_common(func, cb, show_all, ordered, type));
1492 1573  }
1493 1574  
     1575 +int
     1576 +vdev_get_proplist(libzfs_handle_t *hdl, char *props, zprop_list_t **listp)
     1577 +{
     1578 +        *listp = NULL;
     1579 +
     1580 +        /*
     1581 +         * If 'all' is specified, return a NULL list.
     1582 +         */
     1583 +        if (strcmp(props, "all") == 0) {
     1584 +                vdev_prop_t prop;
     1585 +                for (prop = VDEV_PROP_PATH; prop < VDEV_NUM_PROPS; prop++) {
     1586 +                        const char *propname = vdev_prop_to_name(prop);
     1587 +                        if (addlist(hdl, (char *)propname, listp,
     1588 +                            ZFS_TYPE_VDEV))
     1589 +                                return (-1);
     1590 +                        listp = &(*listp)->pl_next;
     1591 +                }
     1592 +
     1593 +                return (0);
     1594 +        }
     1595 +
     1596 +        /*
     1597 +         * If no props were specified, return an error.
     1598 +         */
     1599 +        if (props[0] == '\0') {
     1600 +                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1601 +                    "no properties specified"));
     1602 +                return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
     1603 +                    "bad property list")));
     1604 +        }
     1605 +
     1606 +        /*
     1607 +         * It would be nice to use getsubopt() here, but the inclusion of column
     1608 +         * aliases makes this more effort than it's worth.
     1609 +         */
     1610 +        while (*props != '\0') {
     1611 +                size_t len;
     1612 +                char *p;
     1613 +                char c;
     1614 +
     1615 +                if ((p = strchr(props, ',')) == NULL) {
     1616 +                        len = strlen(props);
     1617 +                        p = props + len;
     1618 +                } else {
     1619 +                        len = p - props;
     1620 +                }
     1621 +
     1622 +                /*
     1623 +                 * Check for empty options.
     1624 +                 */
     1625 +                if (len == 0) {
     1626 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1627 +                            "empty property name"));
     1628 +                        return (zfs_error(hdl, EZFS_BADPROP,
     1629 +                            dgettext(TEXT_DOMAIN, "bad property list")));
     1630 +                }
     1631 +
     1632 +                /*
     1633 +                 * Check all regular property names.
     1634 +                 */
     1635 +                c = props[len];
     1636 +                props[len] = '\0';
     1637 +
     1638 +                /*
     1639 +                 * Make sure we're looking at a valid prop.
     1640 +                 */
     1641 +                if (vdev_name_to_prop(props) == ZPROP_INVAL) {
     1642 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1643 +                            "invalid property '%s'"), props);
     1644 +                        return (zfs_error(hdl, EZFS_BADPROP,
     1645 +                            dgettext(TEXT_DOMAIN, "bad property list")));
     1646 +                }
     1647 +
     1648 +                if (addlist(hdl, props, listp, ZFS_TYPE_VDEV))
     1649 +                        return (-1);
     1650 +                listp = &(*listp)->pl_next;
     1651 +
     1652 +                props = p;
     1653 +                if (c == ',')
     1654 +                        props++;
     1655 +        }
     1656 +
     1657 +        return (0);
     1658 +}
     1659 +
     1660 +int
     1661 +cos_get_proplist(libzfs_handle_t *hdl, char *props, zprop_list_t **listp)
     1662 +{
     1663 +        *listp = NULL;
     1664 +
     1665 +        /*
     1666 +         * If 'all' is specified, return a NULL list.
     1667 +         */
     1668 +        if (strcmp(props, "all") == 0) {
     1669 +                cos_prop_t prop;
     1670 +                for (prop = COS_PROP_GUID; prop < COS_NUM_PROPS; prop++) {
     1671 +                        const char *propname = cos_prop_to_name(prop);
     1672 +                        if (addlist(hdl, (char *)propname, listp,
     1673 +                            ZFS_TYPE_COS))
     1674 +                                return (-1);
     1675 +                        listp = &(*listp)->pl_next;
     1676 +                }
     1677 +
     1678 +                return (0);
     1679 +        }
     1680 +
     1681 +        /*
     1682 +         * If no props were specified, return an error.
     1683 +         */
     1684 +        if (props[0] == '\0') {
     1685 +                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1686 +                    "no properties specified"));
     1687 +                return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
     1688 +                    "bad property list")));
     1689 +        }
     1690 +
     1691 +        /*
     1692 +         * It would be nice to use getsubopt() here, but the inclusion of column
     1693 +         * aliases makes this more effort than it's worth.
     1694 +         */
     1695 +        while (*props != '\0') {
     1696 +                size_t len;
     1697 +                char *p;
     1698 +                char c;
     1699 +
     1700 +                if ((p = strchr(props, ',')) == NULL) {
     1701 +                        len = strlen(props);
     1702 +                        p = props + len;
     1703 +                } else {
     1704 +                        len = p - props;
     1705 +                }
     1706 +
     1707 +                /*
     1708 +                 * Check for empty options.
     1709 +                 */
     1710 +                if (len == 0) {
     1711 +                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
     1712 +                            "empty property name"));
     1713 +                        return (zfs_error(hdl, EZFS_BADPROP,
     1714 +                            dgettext(TEXT_DOMAIN, "bad property list")));
     1715 +                }
     1716 +
     1717 +                /*
     1718 +                 * Check all regular property names.
     1719 +                 */
     1720 +                c = props[len];
     1721 +                props[len] = '\0';
     1722 +
     1723 +                if (addlist(hdl, props, listp, ZFS_TYPE_COS))
     1724 +                        return (-1);
     1725 +                listp = &(*listp)->pl_next;
     1726 +
     1727 +                props = p;
     1728 +                if (c == ',')
     1729 +                        props++;
     1730 +        }
     1731 +
     1732 +        return (0);
     1733 +}
     1734 +
     1735 +void
     1736 +vdev_print_headers(zprop_get_cbdata_t *cbp)
     1737 +{
     1738 +        zprop_list_t *pl = cbp->cb_proplist;
     1739 +        int i;
     1740 +        char *title;
     1741 +        size_t len;
     1742 +
     1743 +        cbp->cb_first = B_FALSE;
     1744 +        if (cbp->cb_scripted)
     1745 +                return;
     1746 +
     1747 +        /*
     1748 +         * Start with the length of the column headers.
     1749 +         */
     1750 +        cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN,
     1751 +            "POOLNAME"));
     1752 +        cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN,
     1753 +            "c0t0d0s0"));
     1754 +        cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN,
     1755 +            "PROPERTY"));
     1756 +        cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN,
     1757 +            "VALUE"));
     1758 +
     1759 +        for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
     1760 +                /*
     1761 +                 * 'PROPERTY' column
     1762 +                 */
     1763 +                const char *propname = vdev_prop_to_name(pl->pl_prop);
     1764 +
     1765 +                len = strlen(propname);
     1766 +                if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
     1767 +                        cbp->cb_colwidths[GET_COL_PROPERTY] = len;
     1768 +
     1769 +                /*
     1770 +                 * 'VALUE' column.
     1771 +                 */
     1772 +                if (pl != cbp->cb_proplist &&
     1773 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE])
     1774 +                        cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width;
     1775 +
     1776 +                /*
     1777 +                 * 'NAME'
     1778 +                 */
     1779 +                if (pl->pl_prop == 0 &&
     1780 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
     1781 +                        cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
     1782 +                }
     1783 +                /*
     1784 +                 * 'SOURCE'
     1785 +                 */
     1786 +                if (pl->pl_prop == 0 &&
     1787 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_SOURCE]) {
     1788 +                        cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width;
     1789 +                }
     1790 +        }
     1791 +
     1792 +        /*
     1793 +         * Now go through and print the headers.
     1794 +         */
     1795 +        for (i = 0; i < ZFS_GET_NCOLS-1; i++) {
     1796 +                switch (cbp->cb_columns[i]) {
     1797 +                case GET_COL_NAME:
     1798 +                        title = dgettext(TEXT_DOMAIN, "POOLNAME");
     1799 +                        break;
     1800 +                case GET_COL_SOURCE:
     1801 +                        title = dgettext(TEXT_DOMAIN, "VDEV");
     1802 +                        break;
     1803 +                case GET_COL_PROPERTY:
     1804 +                        title = dgettext(TEXT_DOMAIN, "PROPERTY");
     1805 +                        break;
     1806 +                case GET_COL_VALUE:
     1807 +                        title = dgettext(TEXT_DOMAIN, "VALUE");
     1808 +                        break;
     1809 +                default:
     1810 +                        title = NULL;
     1811 +                }
     1812 +
     1813 +                if (title != NULL) {
     1814 +                        if (i == (ZFS_GET_NCOLS - 1) ||
     1815 +                            cbp->cb_columns[i + 1] == GET_COL_NONE)
     1816 +                                (void) printf("%s", title);
     1817 +                        else
     1818 +                                (void) printf("%-*s  ",
     1819 +                                    cbp->cb_colwidths[cbp->cb_columns[i]],
     1820 +                                    title);
     1821 +                }
     1822 +        }
     1823 +        (void) printf("\n");
     1824 +}
     1825 +
     1826 +void
     1827 +cos_print_headers(zprop_get_cbdata_t *cbp)
     1828 +{
     1829 +        zprop_list_t *pl = cbp->cb_proplist;
     1830 +        int i;
     1831 +        char *title;
     1832 +        size_t len;
     1833 +
     1834 +        cbp->cb_first = B_FALSE;
     1835 +        if (cbp->cb_scripted)
     1836 +                return;
     1837 +
     1838 +        /*
     1839 +         * Start with the length of the column headers.
     1840 +         */
     1841 +        cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN,
     1842 +            "POOLNAME"));
     1843 +        cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN,
     1844 +            "c0t0d0s0"));
     1845 +        cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN,
     1846 +            "PROPERTY"));
     1847 +        cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN,
     1848 +            "VALUE"));
     1849 +
     1850 +        for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
     1851 +                /*
     1852 +                 * 'PROPERTY' column
     1853 +                 */
     1854 +                const char *propname = cos_prop_to_name(pl->pl_prop);
     1855 +
     1856 +                len = strlen(propname);
     1857 +                if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
     1858 +                        cbp->cb_colwidths[GET_COL_PROPERTY] = len;
     1859 +
     1860 +                /*
     1861 +                 * 'VALUE' column.
     1862 +                 */
     1863 +                if (pl != cbp->cb_proplist &&
     1864 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE])
     1865 +                        cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width;
     1866 +
     1867 +                /*
     1868 +                 * 'NAME'
     1869 +                 */
     1870 +                if (pl->pl_prop == 0 &&
     1871 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
     1872 +                        cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
     1873 +                }
     1874 +                /*
     1875 +                 * 'SOURCE'
     1876 +                 */
     1877 +                if (pl->pl_prop == 0 &&
     1878 +                    pl->pl_width > cbp->cb_colwidths[GET_COL_SOURCE]) {
     1879 +                        cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width;
     1880 +                }
     1881 +        }
     1882 +
     1883 +        /*
     1884 +         * Now go through and print the headers.
     1885 +         */
     1886 +        for (i = 0; i < ZFS_GET_NCOLS-1; i++) {
     1887 +                switch (cbp->cb_columns[i]) {
     1888 +                case GET_COL_NAME:
     1889 +                        title = dgettext(TEXT_DOMAIN, "POOLNAME");
     1890 +                        break;
     1891 +                case GET_COL_SOURCE:
     1892 +                        title = dgettext(TEXT_DOMAIN, "COS");
     1893 +                        break;
     1894 +                case GET_COL_PROPERTY:
     1895 +                        title = dgettext(TEXT_DOMAIN, "PROPERTY");
     1896 +                        break;
     1897 +                case GET_COL_VALUE:
     1898 +                        title = dgettext(TEXT_DOMAIN, "VALUE");
     1899 +                        break;
     1900 +                default:
     1901 +                        title = NULL;
     1902 +                }
     1903 +
     1904 +                if (title != NULL) {
     1905 +                        if (i == (ZFS_GET_NCOLS - 1) ||
     1906 +                            cbp->cb_columns[i + 1] == GET_COL_NONE)
     1907 +                                (void) printf("%s", title);
     1908 +                        else
     1909 +                                (void) printf("%-*s  ",
     1910 +                                    cbp->cb_colwidths[cbp->cb_columns[i]],
     1911 +                                    title);
     1912 +                }
     1913 +        }
     1914 +        (void) printf("\n");
     1915 +}
     1916 +
     1917 +void
     1918 +vdev_print_one_property(const char *poolname, const char *vdevname,
     1919 +    zprop_get_cbdata_t *cbp, const char *propname, const char *value)
     1920 +{
     1921 +        int i;
     1922 +        const char *str;
     1923 +
     1924 +        if (cbp->cb_first)
     1925 +                vdev_print_headers(cbp);
     1926 +
     1927 +        for (i = 0; i < ZFS_GET_NCOLS; i++) {
     1928 +                switch (cbp->cb_columns[i]) {
     1929 +                case GET_COL_NAME:
     1930 +                        str = poolname;
     1931 +                        break;
     1932 +
     1933 +                case GET_COL_SOURCE:
     1934 +                        str = vdevname;
     1935 +                        break;
     1936 +
     1937 +                case GET_COL_PROPERTY:
     1938 +                        str = propname;
     1939 +                        break;
     1940 +
     1941 +                case GET_COL_VALUE:
     1942 +                        str = value;
     1943 +                        break;
     1944 +
     1945 +                default:
     1946 +                        continue;
     1947 +                }
     1948 +
     1949 +                if (cbp->cb_columns[i + 1] == GET_COL_NONE)
     1950 +                        (void) printf("%s", str);
     1951 +                else if (cbp->cb_scripted)
     1952 +                        (void) printf("%s\t", str);
     1953 +                else
     1954 +                        (void) printf("%-*s  ",
     1955 +                            cbp->cb_colwidths[cbp->cb_columns[i]],
     1956 +                            str);
     1957 +        }
     1958 +
     1959 +        (void) printf("\n");
     1960 +}
     1961 +
     1962 +void
     1963 +cos_print_one_property(const char *poolname, const char *cosname,
     1964 +    zprop_get_cbdata_t *cbp, const char *propname, const char *value)
     1965 +{
     1966 +        int i;
     1967 +        const char *str;
     1968 +
     1969 +        if (cbp->cb_first)
     1970 +                cos_print_headers(cbp);
     1971 +
     1972 +        for (i = 0; i < ZFS_GET_NCOLS; i++) {
     1973 +                switch (cbp->cb_columns[i]) {
     1974 +                case GET_COL_NAME:
     1975 +                        str = poolname;
     1976 +                        break;
     1977 +
     1978 +                case GET_COL_SOURCE:
     1979 +                        str = cosname;
     1980 +                        break;
     1981 +
     1982 +                case GET_COL_PROPERTY:
     1983 +                        str = propname;
     1984 +                        break;
     1985 +
     1986 +                case GET_COL_VALUE:
     1987 +                        str = value;
     1988 +                        break;
     1989 +
     1990 +                default:
     1991 +                        continue;
     1992 +                }
     1993 +
     1994 +                if (cbp->cb_columns[i + 1] == GET_COL_NONE)
     1995 +                        (void) printf("%s", str);
     1996 +                else if (cbp->cb_scripted)
     1997 +                        (void) printf("%s\t", str);
     1998 +                else
     1999 +                        (void) printf("%-*s  ",
     2000 +                            cbp->cb_colwidths[cbp->cb_columns[i]],
     2001 +                            str);
     2002 +        }
     2003 +
     2004 +        (void) printf("\n");
     2005 +}
     2006 +
1494 2007  /*
1495 2008   * zfs_get_hole_count retrieves the number of holes (blocks which are
1496 2009   * zero-filled) in the specified file using the _FIO_COUNT_FILLED ioctl. It
1497 2010   * also optionally fetches the block size when bs is non-NULL. With hole count
1498 2011   * and block size the full space consumed by the holes of a file can be
1499 2012   * calculated.
1500 2013   *
1501 2014   * On success, zero is returned, the count argument is set to the
1502 2015   * number of holes, and the bs argument is set to the block size (if it is
1503 2016   * not NULL). On error, a non-zero errno is returned and the values in count
↓ open down ↓ 36 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX