Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   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  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2011 by Delphix. All rights reserved.
  24  */
  25 
  26 /*
  27  * Internal utility routines for the ZFS library.
  28  */
  29 
  30 #include <errno.h>
  31 #include <fcntl.h>
  32 #include <libintl.h>
  33 #include <stdarg.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <unistd.h>
  38 #include <ctype.h>
  39 #include <math.h>
  40 #include <sys/mnttab.h>
  41 #include <sys/mntent.h>
  42 #include <sys/types.h>
  43 
  44 #include <libzfs.h>
  45 
  46 #include "libzfs_impl.h"
  47 #include "zfs_prop.h"

  48 
  49 int
  50 libzfs_errno(libzfs_handle_t *hdl)
  51 {
  52         return (hdl->libzfs_error);
  53 }
  54 
  55 const char *
  56 libzfs_error_action(libzfs_handle_t *hdl)
  57 {
  58         return (hdl->libzfs_action);
  59 }
  60 
  61 const char *
  62 libzfs_error_description(libzfs_handle_t *hdl)
  63 {
  64         if (hdl->libzfs_desc[0] != '\0')
  65                 return (hdl->libzfs_desc);
  66 
  67         switch (hdl->libzfs_error) {


  95                 return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
  96                     "this system"));
  97         case EZFS_INVALIDNAME:
  98                 return (dgettext(TEXT_DOMAIN, "invalid name"));
  99         case EZFS_BADRESTORE:
 100                 return (dgettext(TEXT_DOMAIN, "unable to restore to "
 101                     "destination"));
 102         case EZFS_BADBACKUP:
 103                 return (dgettext(TEXT_DOMAIN, "backup failed"));
 104         case EZFS_BADTARGET:
 105                 return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
 106         case EZFS_NODEVICE:
 107                 return (dgettext(TEXT_DOMAIN, "no such device in pool"));
 108         case EZFS_BADDEV:
 109                 return (dgettext(TEXT_DOMAIN, "invalid device"));
 110         case EZFS_NOREPLICAS:
 111                 return (dgettext(TEXT_DOMAIN, "no valid replicas"));
 112         case EZFS_RESILVERING:
 113                 return (dgettext(TEXT_DOMAIN, "currently resilvering"));
 114         case EZFS_BADVERSION:
 115                 return (dgettext(TEXT_DOMAIN, "unsupported version"));

 116         case EZFS_POOLUNAVAIL:
 117                 return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
 118         case EZFS_DEVOVERFLOW:
 119                 return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
 120         case EZFS_BADPATH:
 121                 return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
 122         case EZFS_CROSSTARGET:
 123                 return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
 124                     "pools"));
 125         case EZFS_ZONED:
 126                 return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
 127         case EZFS_MOUNTFAILED:
 128                 return (dgettext(TEXT_DOMAIN, "mount failed"));
 129         case EZFS_UMOUNTFAILED:
 130                 return (dgettext(TEXT_DOMAIN, "umount failed"));
 131         case EZFS_UNSHARENFSFAILED:
 132                 return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
 133         case EZFS_SHARENFSFAILED:
 134                 return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
 135         case EZFS_UNSHARESMBFAILED:


 612 
 613         if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
 614                 return (NULL);
 615         }
 616 
 617         if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
 618                 free(hdl);
 619                 return (NULL);
 620         }
 621 
 622         if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
 623                 (void) close(hdl->libzfs_fd);
 624                 free(hdl);
 625                 return (NULL);
 626         }
 627 
 628         hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
 629 
 630         zfs_prop_init();
 631         zpool_prop_init();

 632         libzfs_mnttab_init(hdl);
 633 
 634         return (hdl);
 635 }
 636 
 637 void
 638 libzfs_fini(libzfs_handle_t *hdl)
 639 {
 640         (void) close(hdl->libzfs_fd);
 641         if (hdl->libzfs_mnttab)
 642                 (void) fclose(hdl->libzfs_mnttab);
 643         if (hdl->libzfs_sharetab)
 644                 (void) fclose(hdl->libzfs_sharetab);
 645         zfs_uninit_libshare(hdl);
 646         if (hdl->libzfs_log_str)
 647                 (void) free(hdl->libzfs_log_str);
 648         zpool_free_handles(hdl);
 649         libzfs_fru_clear(hdl, B_TRUE);
 650         namespace_clear(hdl);
 651         libzfs_mnttab_fini(hdl);


1265         return (-1);
1266 }
1267 
1268 static int
1269 addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
1270     zfs_type_t type)
1271 {
1272         int prop;
1273         zprop_list_t *entry;
1274 
1275         prop = zprop_name_to_prop(propname, type);
1276 
1277         if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
1278                 prop = ZPROP_INVAL;
1279 
1280         /*
1281          * When no property table entry can be found, return failure if
1282          * this is a pool property or if this isn't a user-defined
1283          * dataset property,
1284          */
1285         if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
1286             (!zfs_prop_user(propname) && !zfs_prop_userquota(propname) &&
1287             !zfs_prop_written(propname)))) {


1288                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1289                     "invalid property '%s'"), propname);
1290                 return (zfs_error(hdl, EZFS_BADPROP,
1291                     dgettext(TEXT_DOMAIN, "bad property list")));
1292         }
1293 
1294         if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
1295                 return (-1);
1296 
1297         entry->pl_prop = prop;
1298         if (prop == ZPROP_INVAL) {
1299                 if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {

1300                         free(entry);
1301                         return (-1);
1302                 }
1303                 entry->pl_width = strlen(propname);
1304         } else {
1305                 entry->pl_width = zprop_width(prop, &entry->pl_fixed,
1306                     type);
1307         }
1308 
1309         *listp = entry;
1310 
1311         return (0);
1312 }
1313 
1314 /*
1315  * Given a comma-separated list of properties, construct a property list
1316  * containing both user-defined and native properties.  This function will
1317  * return a NULL list if 'all' is specified, which can later be expanded
1318  * by zprop_expand_list().
1319  */


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   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) 2012 by Delphix. All rights reserved.
  25  */
  26 
  27 /*
  28  * Internal utility routines for the ZFS library.
  29  */
  30 
  31 #include <errno.h>
  32 #include <fcntl.h>
  33 #include <libintl.h>
  34 #include <stdarg.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <strings.h>
  38 #include <unistd.h>
  39 #include <ctype.h>
  40 #include <math.h>
  41 #include <sys/mnttab.h>
  42 #include <sys/mntent.h>
  43 #include <sys/types.h>
  44 
  45 #include <libzfs.h>
  46 
  47 #include "libzfs_impl.h"
  48 #include "zfs_prop.h"
  49 #include "zfeature_common.h"
  50 
  51 int
  52 libzfs_errno(libzfs_handle_t *hdl)
  53 {
  54         return (hdl->libzfs_error);
  55 }
  56 
  57 const char *
  58 libzfs_error_action(libzfs_handle_t *hdl)
  59 {
  60         return (hdl->libzfs_action);
  61 }
  62 
  63 const char *
  64 libzfs_error_description(libzfs_handle_t *hdl)
  65 {
  66         if (hdl->libzfs_desc[0] != '\0')
  67                 return (hdl->libzfs_desc);
  68 
  69         switch (hdl->libzfs_error) {


  97                 return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
  98                     "this system"));
  99         case EZFS_INVALIDNAME:
 100                 return (dgettext(TEXT_DOMAIN, "invalid name"));
 101         case EZFS_BADRESTORE:
 102                 return (dgettext(TEXT_DOMAIN, "unable to restore to "
 103                     "destination"));
 104         case EZFS_BADBACKUP:
 105                 return (dgettext(TEXT_DOMAIN, "backup failed"));
 106         case EZFS_BADTARGET:
 107                 return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
 108         case EZFS_NODEVICE:
 109                 return (dgettext(TEXT_DOMAIN, "no such device in pool"));
 110         case EZFS_BADDEV:
 111                 return (dgettext(TEXT_DOMAIN, "invalid device"));
 112         case EZFS_NOREPLICAS:
 113                 return (dgettext(TEXT_DOMAIN, "no valid replicas"));
 114         case EZFS_RESILVERING:
 115                 return (dgettext(TEXT_DOMAIN, "currently resilvering"));
 116         case EZFS_BADVERSION:
 117                 return (dgettext(TEXT_DOMAIN, "unsupported version or "
 118                     "feature"));
 119         case EZFS_POOLUNAVAIL:
 120                 return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
 121         case EZFS_DEVOVERFLOW:
 122                 return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
 123         case EZFS_BADPATH:
 124                 return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
 125         case EZFS_CROSSTARGET:
 126                 return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
 127                     "pools"));
 128         case EZFS_ZONED:
 129                 return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
 130         case EZFS_MOUNTFAILED:
 131                 return (dgettext(TEXT_DOMAIN, "mount failed"));
 132         case EZFS_UMOUNTFAILED:
 133                 return (dgettext(TEXT_DOMAIN, "umount failed"));
 134         case EZFS_UNSHARENFSFAILED:
 135                 return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
 136         case EZFS_SHARENFSFAILED:
 137                 return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
 138         case EZFS_UNSHARESMBFAILED:


 615 
 616         if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
 617                 return (NULL);
 618         }
 619 
 620         if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
 621                 free(hdl);
 622                 return (NULL);
 623         }
 624 
 625         if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) {
 626                 (void) close(hdl->libzfs_fd);
 627                 free(hdl);
 628                 return (NULL);
 629         }
 630 
 631         hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r");
 632 
 633         zfs_prop_init();
 634         zpool_prop_init();
 635         zpool_feature_init();
 636         libzfs_mnttab_init(hdl);
 637 
 638         return (hdl);
 639 }
 640 
 641 void
 642 libzfs_fini(libzfs_handle_t *hdl)
 643 {
 644         (void) close(hdl->libzfs_fd);
 645         if (hdl->libzfs_mnttab)
 646                 (void) fclose(hdl->libzfs_mnttab);
 647         if (hdl->libzfs_sharetab)
 648                 (void) fclose(hdl->libzfs_sharetab);
 649         zfs_uninit_libshare(hdl);
 650         if (hdl->libzfs_log_str)
 651                 (void) free(hdl->libzfs_log_str);
 652         zpool_free_handles(hdl);
 653         libzfs_fru_clear(hdl, B_TRUE);
 654         namespace_clear(hdl);
 655         libzfs_mnttab_fini(hdl);


1269         return (-1);
1270 }
1271 
1272 static int
1273 addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
1274     zfs_type_t type)
1275 {
1276         int prop;
1277         zprop_list_t *entry;
1278 
1279         prop = zprop_name_to_prop(propname, type);
1280 
1281         if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
1282                 prop = ZPROP_INVAL;
1283 
1284         /*
1285          * When no property table entry can be found, return failure if
1286          * this is a pool property or if this isn't a user-defined
1287          * dataset property,
1288          */
1289         if (prop == ZPROP_INVAL && ((type == ZFS_TYPE_POOL &&
1290             !zpool_prop_feature(propname) &&
1291             !zpool_prop_unsupported(propname)) ||
1292             (type == ZFS_TYPE_DATASET && !zfs_prop_user(propname) &&
1293             !zfs_prop_userquota(propname) && !zfs_prop_written(propname)))) {
1294                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1295                     "invalid property '%s'"), propname);
1296                 return (zfs_error(hdl, EZFS_BADPROP,
1297                     dgettext(TEXT_DOMAIN, "bad property list")));
1298         }
1299 
1300         if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
1301                 return (-1);
1302 
1303         entry->pl_prop = prop;
1304         if (prop == ZPROP_INVAL) {
1305                 if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) ==
1306                     NULL) {
1307                         free(entry);
1308                         return (-1);
1309                 }
1310                 entry->pl_width = strlen(propname);
1311         } else {
1312                 entry->pl_width = zprop_width(prop, &entry->pl_fixed,
1313                     type);
1314         }
1315 
1316         *listp = entry;
1317 
1318         return (0);
1319 }
1320 
1321 /*
1322  * Given a comma-separated list of properties, construct a property list
1323  * containing both user-defined and native properties.  This function will
1324  * return a NULL list if 'all' is specified, which can later be expanded
1325  * by zprop_expand_list().
1326  */