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


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.

  25  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  26  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  27  * Copyright (c) 2017 Datto Inc.
  28  */
  29 
  30 /*
  31  * Internal utility routines for the ZFS library.
  32  */
  33 
  34 #include <errno.h>
  35 #include <fcntl.h>
  36 #include <libintl.h>
  37 #include <stdarg.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <strings.h>
  41 #include <unistd.h>
  42 #include <ctype.h>
  43 #include <math.h>
  44 #include <sys/filio.h>


 218                 return (dgettext(TEXT_DOMAIN, "pipe create failed"));
 219         case EZFS_THREADCREATEFAILED:
 220                 return (dgettext(TEXT_DOMAIN, "thread create failed"));
 221         case EZFS_POSTSPLIT_ONLINE:
 222                 return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
 223                     "into a new one"));
 224         case EZFS_SCRUB_PAUSED:
 225                 return (dgettext(TEXT_DOMAIN, "scrub is paused; "
 226                     "use 'zpool scrub' to resume"));
 227         case EZFS_SCRUBBING:
 228                 return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
 229                     "use 'zpool scrub -s' to cancel current scrub"));
 230         case EZFS_NO_SCRUB:
 231                 return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
 232         case EZFS_DIFF:
 233                 return (dgettext(TEXT_DOMAIN, "unable to generate diffs"));
 234         case EZFS_DIFFDATA:
 235                 return (dgettext(TEXT_DOMAIN, "invalid diff data"));
 236         case EZFS_POOLREADONLY:
 237                 return (dgettext(TEXT_DOMAIN, "pool is read-only"));
 238         case EZFS_NO_PENDING:
 239                 return (dgettext(TEXT_DOMAIN, "operation is not "
 240                     "in progress"));






 241         case EZFS_UNKNOWN:
 242                 return (dgettext(TEXT_DOMAIN, "unknown error"));
 243         default:
 244                 assert(hdl->libzfs_error == 0);
 245                 return (dgettext(TEXT_DOMAIN, "no error"));
 246         }
 247 }
 248 
 249 /*PRINTFLIKE2*/
 250 void
 251 zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
 252 {
 253         va_list ap;
 254 
 255         va_start(ap, fmt);
 256 
 257         (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
 258             fmt, ap);
 259         hdl->libzfs_desc_active = 1;
 260 


 372 
 373         case ENOSPC:
 374         case EDQUOT:
 375                 zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
 376                 return (-1);
 377 
 378         case EEXIST:
 379                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 380                     "dataset already exists"));
 381                 zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
 382                 break;
 383 
 384         case EBUSY:
 385                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 386                     "dataset is busy"));
 387                 zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 388                 break;
 389         case EROFS:
 390                 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 391                 break;



 392         case ENAMETOOLONG:
 393                 zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
 394                 break;
 395         case ENOTSUP:
 396                 zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
 397                 break;
 398         case EAGAIN:
 399                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 400                     "pool I/O is currently suspended"));
 401                 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
 402                 break;
 403         default:
 404                 zfs_error_aux(hdl, strerror(error));
 405                 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 406                 break;
 407         }
 408 
 409         va_end(ap);
 410         return (-1);
 411 }
 412 
 413 int












































 414 zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
 415 {
 416         return (zpool_standard_error_fmt(hdl, error, "%s", msg));
 417 }
 418 
 419 /*PRINTFLIKE3*/
 420 int
 421 zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
 422 {
 423         va_list ap;
 424 
 425         va_start(ap, fmt);
 426 
 427         if (zfs_common_error(hdl, error, fmt, ap) != 0) {
 428                 va_end(ap);
 429                 return (-1);
 430         }
 431 
 432         switch (error) {
 433         case ENODEV:
 434                 zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
 435                 break;
 436 
 437         case ENOENT:
 438                 zfs_error_aux(hdl,
 439                     dgettext(TEXT_DOMAIN, "no such pool or dataset"));
 440                 zfs_verror(hdl, EZFS_NOENT, fmt, ap);
 441                 break;
 442 
 443         case EEXIST:
 444                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 445                     "pool already exists"));
 446                 zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
 447                 break;
 448 
 449         case EBUSY:
 450                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));

 451                 zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 452                 break;
 453 
 454         case ENXIO:
 455                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 456                     "one or more devices is currently unavailable"));
 457                 zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
 458                 break;
 459 
 460         case ENAMETOOLONG:
 461                 zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
 462                 break;
 463 
 464         case ENOTSUP:
 465                 zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap);
 466                 break;
 467 
 468         case EINVAL:
 469                 zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
 470                 break;
 471 
 472         case ENOSPC:
 473         case EDQUOT:
 474                 zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
 475                 return (-1);
 476 
 477         case EAGAIN:
 478                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 479                     "pool I/O is currently suspended"));
 480                 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
 481                 break;
 482 
 483         case EROFS:
 484                 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 485                 break;
 486         /* There is no pending operation to cancel */
 487         case ENOTACTIVE:
 488                 zfs_verror(hdl, EZFS_NO_PENDING, fmt, ap);
 489                 break;
 490 
 491         default:
 492                 zfs_error_aux(hdl, strerror(error));
 493                 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 494         }
 495 
 496         va_end(ap);
 497         return (-1);
 498 }
 499 
 500 /*
 501  * Display an out of memory error message and abort the current program.
 502  */
 503 int
 504 no_memory(libzfs_handle_t *hdl)
 505 {
 506         return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
 507 }
 508 
 509 /*


 605 
 606         if ((hdl->libzfs_mnttab = fopen(MNTTAB, "rF")) == NULL) {
 607                 (void) close(hdl->libzfs_fd);
 608                 free(hdl);
 609                 return (NULL);
 610         }
 611 
 612         hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "rF");
 613 
 614         if (libzfs_core_init() != 0) {
 615                 (void) close(hdl->libzfs_fd);
 616                 (void) fclose(hdl->libzfs_mnttab);
 617                 (void) fclose(hdl->libzfs_sharetab);
 618                 free(hdl);
 619                 return (NULL);
 620         }
 621 
 622         zfs_prop_init();
 623         zpool_prop_init();
 624         zpool_feature_init();


 625         libzfs_mnttab_init(hdl);
 626 
 627         if (getenv("ZFS_PROP_DEBUG") != NULL) {
 628                 hdl->libzfs_prop_debug = B_TRUE;
 629         }
 630 
 631         return (hdl);
 632 }
 633 
 634 void
 635 libzfs_fini(libzfs_handle_t *hdl)
 636 {
 637         (void) close(hdl->libzfs_fd);
 638         if (hdl->libzfs_mnttab)
 639                 (void) fclose(hdl->libzfs_mnttab);
 640         if (hdl->libzfs_sharetab)
 641                 (void) fclose(hdl->libzfs_sharetab);


 642         zfs_uninit_libshare(hdl);
 643         zpool_free_handles(hdl);
 644         libzfs_fru_clear(hdl, B_TRUE);
 645         namespace_clear(hdl);
 646         libzfs_mnttab_fini(hdl);
 647         libzfs_core_fini();
 648         free(hdl);
 649 }
 650 
 651 libzfs_handle_t *
 652 zpool_get_handle(zpool_handle_t *zhp)
 653 {
 654         return (zhp->zpool_hdl);
 655 }
 656 
 657 libzfs_handle_t *
 658 zfs_get_handle(zfs_handle_t *zhp)
 659 {
 660         return (zhp->zfs_hdl);
 661 }


 790 int
 791 zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
 792 {
 793         return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
 794             &zc->zc_nvlist_src_size, nvl));
 795 }
 796 
 797 /*
 798  * Unpacks an nvlist from the ZFS ioctl command structure.
 799  */
 800 int
 801 zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
 802 {
 803         if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
 804             zc->zc_nvlist_dst_size, nvlp, 0) != 0)
 805                 return (no_memory(hdl));
 806 
 807         return (0);
 808 }
 809 








 810 int
 811 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
 812 {
 813         return (ioctl(hdl->libzfs_fd, request, zc));






 814 }
 815 
 816 /*
 817  * ================================================================
 818  * API shared by zfs and zpool property management
 819  * ================================================================
 820  */
 821 
 822 static void
 823 zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
 824 {
 825         zprop_list_t *pl = cbp->cb_proplist;
 826         int i;
 827         char *title;
 828         size_t len;
 829 
 830         cbp->cb_first = B_FALSE;
 831         if (cbp->cb_scripted)
 832                 return;
 833 


1029         (void) printf("\n");
1030 }
1031 
1032 /*
1033  * Given a numeric suffix, convert the value into a number of bits that the
1034  * resulting value must be shifted.
1035  */
1036 static int
1037 str2shift(libzfs_handle_t *hdl, const char *buf)
1038 {
1039         const char *ends = "BKMGTPEZ";
1040         int i;
1041 
1042         if (buf[0] == '\0')
1043                 return (0);
1044         for (i = 0; i < strlen(ends); i++) {
1045                 if (toupper(buf[0]) == ends[i])
1046                         break;
1047         }
1048         if (i == strlen(ends)) {

1049                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1050                     "invalid numeric suffix '%s'"), buf);
1051                 return (-1);
1052         }
1053 
1054         /*
1055          * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
1056          * allow 'BB' - that's just weird.
1057          */
1058         if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
1059             toupper(buf[0]) != 'B'))
1060                 return (10*i);
1061 

1062         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1063             "invalid numeric suffix '%s'"), buf);
1064         return (-1);
1065 }
1066 
1067 /*
1068  * Convert a string of the form '100G' into a real number.  Used when setting
1069  * properties or creating a volume.  'buf' is used to place an extended error
1070  * message for the caller to use.
1071  */
1072 int
1073 zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
1074 {
1075         char *end;
1076         int shift;
1077 
1078         *num = 0;
1079 
1080         /* Check to see if this looks like a number.  */
1081         if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {


1143  * (index, boolean, etc) if they are specified as strings and add the
1144  * resulting nvpair to the returned nvlist.
1145  *
1146  * At the DSL layer, all properties are either 64-bit numbers or strings.
1147  * We want the user to be able to ignore this fact and specify properties
1148  * as native values (numbers, for example) or as strings (to simplify
1149  * command line utilities).  This also handles converting index types
1150  * (compression, checksum, etc) from strings to their on-disk index.
1151  */
1152 int
1153 zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
1154     zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
1155     const char *errbuf)
1156 {
1157         data_type_t datatype = nvpair_type(elem);
1158         zprop_type_t proptype;
1159         const char *propname;
1160         char *value;
1161         boolean_t isnone = B_FALSE;
1162 
1163         if (type == ZFS_TYPE_POOL) {

1164                 proptype = zpool_prop_get_type(prop);
1165                 propname = zpool_prop_to_name(prop);
1166         } else {









1167                 proptype = zfs_prop_get_type(prop);
1168                 propname = zfs_prop_to_name(prop);
1169         }
1170 
1171         /*
1172          * Convert any properties to the internal DSL value types.
1173          */
1174         *svalp = NULL;
1175         *ivalp = 0;
1176 
1177         switch (proptype) {
1178         case PROP_TYPE_STRING:
1179                 if (datatype != DATA_TYPE_STRING) {
1180                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1181                             "'%s' must be a string"), nvpair_name(elem));
1182                         goto error;
1183                 }
1184                 (void) nvpair_value_string(elem, svalp);
1185                 if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
1186                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,


1474                         return (-1);
1475 
1476                 entry->pl_prop = (type == ZFS_TYPE_POOL) ?  ZPOOL_PROP_NAME :
1477                     ZFS_PROP_NAME;
1478                 entry->pl_width = zprop_width(entry->pl_prop,
1479                     &entry->pl_fixed, type);
1480                 entry->pl_all = B_TRUE;
1481                 entry->pl_next = *plp;
1482                 *plp = entry;
1483         }
1484         return (0);
1485 }
1486 
1487 int
1488 zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
1489     zfs_type_t type)
1490 {
1491         return (zprop_iter_common(func, cb, show_all, ordered, type));
1492 }
1493 
















































































































































































































































































































































































































































1494 /*
1495  * zfs_get_hole_count retrieves the number of holes (blocks which are
1496  * zero-filled) in the specified file using the _FIO_COUNT_FILLED ioctl. It
1497  * also optionally fetches the block size when bs is non-NULL. With hole count
1498  * and block size the full space consumed by the holes of a file can be
1499  * calculated.
1500  *
1501  * On success, zero is returned, the count argument is set to the
1502  * number of holes, and the bs argument is set to the block size (if it is
1503  * not NULL). On error, a non-zero errno is returned and the values in count
1504  * and bs are undefined.
1505  */
1506 int
1507 zfs_get_hole_count(const char *path, uint64_t *count, uint64_t *bs)
1508 {
1509         int fd, err;
1510         struct stat64 ss;
1511         uint64_t fill;
1512 
1513         fd = open(path, O_RDONLY | O_LARGEFILE);




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  26  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  27  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  28  * Copyright (c) 2017 Datto Inc.
  29  */
  30 
  31 /*
  32  * Internal utility routines for the ZFS library.
  33  */
  34 
  35 #include <errno.h>
  36 #include <fcntl.h>
  37 #include <libintl.h>
  38 #include <stdarg.h>
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <strings.h>
  42 #include <unistd.h>
  43 #include <ctype.h>
  44 #include <math.h>
  45 #include <sys/filio.h>


 219                 return (dgettext(TEXT_DOMAIN, "pipe create failed"));
 220         case EZFS_THREADCREATEFAILED:
 221                 return (dgettext(TEXT_DOMAIN, "thread create failed"));
 222         case EZFS_POSTSPLIT_ONLINE:
 223                 return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
 224                     "into a new one"));
 225         case EZFS_SCRUB_PAUSED:
 226                 return (dgettext(TEXT_DOMAIN, "scrub is paused; "
 227                     "use 'zpool scrub' to resume"));
 228         case EZFS_SCRUBBING:
 229                 return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
 230                     "use 'zpool scrub -s' to cancel current scrub"));
 231         case EZFS_NO_SCRUB:
 232                 return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
 233         case EZFS_DIFF:
 234                 return (dgettext(TEXT_DOMAIN, "unable to generate diffs"));
 235         case EZFS_DIFFDATA:
 236                 return (dgettext(TEXT_DOMAIN, "invalid diff data"));
 237         case EZFS_POOLREADONLY:
 238                 return (dgettext(TEXT_DOMAIN, "pool is read-only"));
 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"));
 248         case EZFS_UNKNOWN:
 249                 return (dgettext(TEXT_DOMAIN, "unknown error"));
 250         default:
 251                 assert(hdl->libzfs_error == 0);
 252                 return (dgettext(TEXT_DOMAIN, "no error"));
 253         }
 254 }
 255 
 256 /*PRINTFLIKE2*/
 257 void
 258 zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
 259 {
 260         va_list ap;
 261 
 262         va_start(ap, fmt);
 263 
 264         (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
 265             fmt, ap);
 266         hdl->libzfs_desc_active = 1;
 267 


 379 
 380         case ENOSPC:
 381         case EDQUOT:
 382                 zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
 383                 return (-1);
 384 
 385         case EEXIST:
 386                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 387                     "dataset already exists"));
 388                 zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
 389                 break;
 390 
 391         case EBUSY:
 392                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 393                     "dataset is busy"));
 394                 zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 395                 break;
 396         case EROFS:
 397                 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 398                 break;
 399         case EINVAL:
 400                 zfs_verror(hdl, EZFS_INVALIDNAME, fmt, ap);
 401                 break;
 402         case ENAMETOOLONG:
 403                 zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
 404                 break;
 405         case ENOTSUP:
 406                 zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
 407                 break;
 408         case EAGAIN:
 409                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 410                     "pool I/O is currently suspended"));
 411                 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
 412                 break;
 413         default:
 414                 zfs_error_aux(hdl, strerror(error));
 415                 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 416                 break;
 417         }
 418 
 419         va_end(ap);
 420         return (-1);
 421 }
 422 
 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
 468 zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
 469 {
 470         return (zpool_standard_error_fmt(hdl, error, "%s", msg));
 471 }
 472 
 473 /*PRINTFLIKE3*/
 474 int
 475 zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
 476 {
 477         va_list ap;
 478 
 479         va_start(ap, fmt);
 480 
 481         if (zfs_common_error(hdl, error, fmt, ap) != 0) {
 482                 va_end(ap);
 483                 return (-1);
 484         }
 485 
 486         switch (error) {
 487         case ENODEV:
 488                 zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
 489                 break;
 490 
 491         case ENOENT:
 492                 zfs_error_aux(hdl,
 493                     dgettext(TEXT_DOMAIN, "no such pool or dataset"));
 494                 zfs_verror(hdl, EZFS_NOENT, fmt, ap);
 495                 break;
 496 
 497         case EEXIST:
 498                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 499                     "pool already exists"));
 500                 zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
 501                 break;
 502 
 503         case EBUSY:
 504                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 505                     "pool or device is busy"));
 506                 zfs_verror(hdl, EZFS_BUSY, fmt, ap);
 507                 break;
 508 
 509         case ENXIO:
 510                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 511                     "one or more devices is currently unavailable"));
 512                 zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
 513                 break;
 514 
 515         case ENAMETOOLONG:
 516                 zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
 517                 break;
 518 
 519         case ENOTSUP:
 520                 zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap);
 521                 break;
 522 
 523         case EINVAL:
 524                 zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
 525                 break;
 526 
 527         case ENOSPC:
 528         case EDQUOT:
 529                 zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
 530                 return (-1);
 531 
 532         case EAGAIN:
 533                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 534                     "pool I/O is currently suspended"));
 535                 zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
 536                 break;
 537 
 538         case EROFS:
 539                 zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
 540                 break;




 541 
 542         default:
 543                 zfs_error_aux(hdl, strerror(error));
 544                 zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
 545         }
 546 
 547         va_end(ap);
 548         return (-1);
 549 }
 550 
 551 /*
 552  * Display an out of memory error message and abort the current program.
 553  */
 554 int
 555 no_memory(libzfs_handle_t *hdl)
 556 {
 557         return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
 558 }
 559 
 560 /*


 656 
 657         if ((hdl->libzfs_mnttab = fopen(MNTTAB, "rF")) == NULL) {
 658                 (void) close(hdl->libzfs_fd);
 659                 free(hdl);
 660                 return (NULL);
 661         }
 662 
 663         hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "rF");
 664 
 665         if (libzfs_core_init() != 0) {
 666                 (void) close(hdl->libzfs_fd);
 667                 (void) fclose(hdl->libzfs_mnttab);
 668                 (void) fclose(hdl->libzfs_sharetab);
 669                 free(hdl);
 670                 return (NULL);
 671         }
 672 
 673         zfs_prop_init();
 674         zpool_prop_init();
 675         zpool_feature_init();
 676         vdev_prop_init();
 677         cos_prop_init();
 678         libzfs_mnttab_init(hdl);
 679 
 680         if (getenv("ZFS_PROP_DEBUG") != NULL) {
 681                 hdl->libzfs_prop_debug = B_TRUE;
 682         }
 683 
 684         return (hdl);
 685 }
 686 
 687 void
 688 libzfs_fini(libzfs_handle_t *hdl)
 689 {
 690         (void) close(hdl->libzfs_fd);
 691         if (hdl->libzfs_mnttab)
 692                 (void) fclose(hdl->libzfs_mnttab);
 693         if (hdl->libzfs_sharetab)
 694                 (void) fclose(hdl->libzfs_sharetab);
 695         if (hdl->libzfs_log_str)
 696                 free(hdl->libzfs_log_str);
 697         zfs_uninit_libshare(hdl);
 698         zpool_free_handles(hdl);
 699         libzfs_fru_clear(hdl, B_TRUE);
 700         namespace_clear(hdl);
 701         libzfs_mnttab_fini(hdl);
 702         libzfs_core_fini();
 703         free(hdl);
 704 }
 705 
 706 libzfs_handle_t *
 707 zpool_get_handle(zpool_handle_t *zhp)
 708 {
 709         return (zhp->zpool_hdl);
 710 }
 711 
 712 libzfs_handle_t *
 713 zfs_get_handle(zfs_handle_t *zhp)
 714 {
 715         return (zhp->zfs_hdl);
 716 }


 845 int
 846 zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
 847 {
 848         return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
 849             &zc->zc_nvlist_src_size, nvl));
 850 }
 851 
 852 /*
 853  * Unpacks an nvlist from the ZFS ioctl command structure.
 854  */
 855 int
 856 zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
 857 {
 858         if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
 859             zc->zc_nvlist_dst_size, nvlp, 0) != 0)
 860                 return (no_memory(hdl));
 861 
 862         return (0);
 863 }
 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 
 873 int
 874 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
 875 {
 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);
 883 }
 884 
 885 /*
 886  * ================================================================
 887  * API shared by zfs and zpool property management
 888  * ================================================================
 889  */
 890 
 891 static void
 892 zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
 893 {
 894         zprop_list_t *pl = cbp->cb_proplist;
 895         int i;
 896         char *title;
 897         size_t len;
 898 
 899         cbp->cb_first = B_FALSE;
 900         if (cbp->cb_scripted)
 901                 return;
 902 


1098         (void) printf("\n");
1099 }
1100 
1101 /*
1102  * Given a numeric suffix, convert the value into a number of bits that the
1103  * resulting value must be shifted.
1104  */
1105 static int
1106 str2shift(libzfs_handle_t *hdl, const char *buf)
1107 {
1108         const char *ends = "BKMGTPEZ";
1109         int i;
1110 
1111         if (buf[0] == '\0')
1112                 return (0);
1113         for (i = 0; i < strlen(ends); i++) {
1114                 if (toupper(buf[0]) == ends[i])
1115                         break;
1116         }
1117         if (i == strlen(ends)) {
1118                 if (hdl)
1119                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1120                             "invalid numeric suffix '%s'"), buf);
1121                 return (-1);
1122         }
1123 
1124         /*
1125          * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
1126          * allow 'BB' - that's just weird.
1127          */
1128         if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
1129             toupper(buf[0]) != 'B'))
1130                 return (10*i);
1131 
1132         if (hdl)
1133                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1134                     "invalid numeric suffix '%s'"), buf);
1135         return (-1);
1136 }
1137 
1138 /*
1139  * Convert a string of the form '100G' into a real number.  Used when setting
1140  * properties or creating a volume.  'buf' is used to place an extended error
1141  * message for the caller to use.
1142  */
1143 int
1144 zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
1145 {
1146         char *end;
1147         int shift;
1148 
1149         *num = 0;
1150 
1151         /* Check to see if this looks like a number.  */
1152         if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {


1214  * (index, boolean, etc) if they are specified as strings and add the
1215  * resulting nvpair to the returned nvlist.
1216  *
1217  * At the DSL layer, all properties are either 64-bit numbers or strings.
1218  * We want the user to be able to ignore this fact and specify properties
1219  * as native values (numbers, for example) or as strings (to simplify
1220  * command line utilities).  This also handles converting index types
1221  * (compression, checksum, etc) from strings to their on-disk index.
1222  */
1223 int
1224 zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
1225     zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
1226     const char *errbuf)
1227 {
1228         data_type_t datatype = nvpair_type(elem);
1229         zprop_type_t proptype;
1230         const char *propname;
1231         char *value;
1232         boolean_t isnone = B_FALSE;
1233 
1234         switch (type) {
1235         case ZFS_TYPE_POOL:
1236                 proptype = zpool_prop_get_type(prop);
1237                 propname = zpool_prop_to_name(prop);
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:
1248                 proptype = zfs_prop_get_type(prop);
1249                 propname = zfs_prop_to_name(prop);
1250         }
1251 
1252         /*
1253          * Convert any properties to the internal DSL value types.
1254          */
1255         *svalp = NULL;
1256         *ivalp = 0;
1257 
1258         switch (proptype) {
1259         case PROP_TYPE_STRING:
1260                 if (datatype != DATA_TYPE_STRING) {
1261                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1262                             "'%s' must be a string"), nvpair_name(elem));
1263                         goto error;
1264                 }
1265                 (void) nvpair_value_string(elem, svalp);
1266                 if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
1267                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,


1555                         return (-1);
1556 
1557                 entry->pl_prop = (type == ZFS_TYPE_POOL) ?  ZPOOL_PROP_NAME :
1558                     ZFS_PROP_NAME;
1559                 entry->pl_width = zprop_width(entry->pl_prop,
1560                     &entry->pl_fixed, type);
1561                 entry->pl_all = B_TRUE;
1562                 entry->pl_next = *plp;
1563                 *plp = entry;
1564         }
1565         return (0);
1566 }
1567 
1568 int
1569 zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
1570     zfs_type_t type)
1571 {
1572         return (zprop_iter_common(func, cb, show_all, ordered, type));
1573 }
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 
2007 /*
2008  * zfs_get_hole_count retrieves the number of holes (blocks which are
2009  * zero-filled) in the specified file using the _FIO_COUNT_FILLED ioctl. It
2010  * also optionally fetches the block size when bs is non-NULL. With hole count
2011  * and block size the full space consumed by the holes of a file can be
2012  * calculated.
2013  *
2014  * On success, zero is returned, the count argument is set to the
2015  * number of holes, and the bs argument is set to the block size (if it is
2016  * not NULL). On error, a non-zero errno is returned and the values in count
2017  * and bs are undefined.
2018  */
2019 int
2020 zfs_get_hole_count(const char *path, uint64_t *count, uint64_t *bs)
2021 {
2022         int fd, err;
2023         struct stat64 ss;
2024         uint64_t fill;
2025 
2026         fd = open(path, O_RDONLY | O_LARGEFILE);