Print this page
4171 clean up spa_feature_*() interfaces
4172 implement extensible_dataset feature for use by other zpool features
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>


   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 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2012 by Delphix. All rights reserved.
  26  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  27  */
  28 
  29 #include <ctype.h>
  30 #include <errno.h>
  31 #include <devid.h>
  32 #include <fcntl.h>
  33 #include <libintl.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <unistd.h>
  38 #include <libgen.h>
  39 #include <sys/efi_partition.h>
  40 #include <sys/vtoc.h>
  41 #include <sys/zfs_ioctl.h>
  42 #include <dlfcn.h>
  43 
  44 #include "zfs_namecheck.h"
  45 #include "zfs_prop.h"


 396         zpool_prop_t prop;
 397         char *strval;
 398         uint64_t intval;
 399         char *slash, *check;
 400         struct stat64 statbuf;
 401         zpool_handle_t *zhp;
 402         nvlist_t *nvroot;
 403 
 404         if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
 405                 (void) no_memory(hdl);
 406                 return (NULL);
 407         }
 408 
 409         elem = NULL;
 410         while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
 411                 const char *propname = nvpair_name(elem);
 412 
 413                 prop = zpool_name_to_prop(propname);
 414                 if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
 415                         int err;
 416                         zfeature_info_t *feature;
 417                         char *fname = strchr(propname, '@') + 1;
 418 
 419                         err = zfeature_lookup_name(fname, &feature);
 420                         if (err != 0) {
 421                                 ASSERT3U(err, ==, ENOENT);
 422                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 423                                     "invalid feature '%s'"), fname);
 424                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 425                                 goto error;
 426                         }
 427 
 428                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
 429                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 430                                     "'%s' must be a string"), propname);
 431                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 432                                 goto error;
 433                         }
 434 
 435                         (void) nvpair_value_string(elem, &strval);
 436                         if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
 437                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 438                                     "property '%s' can only be set to "
 439                                     "'enabled'"), propname);


 790 int
 791 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
 792     size_t len)
 793 {
 794         uint64_t refcount;
 795         boolean_t found = B_FALSE;
 796         nvlist_t *features = zpool_get_features(zhp);
 797         boolean_t supported;
 798         const char *feature = strchr(propname, '@') + 1;
 799 
 800         supported = zpool_prop_feature(propname);
 801         ASSERT(supported || zfs_prop_unsupported(propname));
 802 
 803         /*
 804          * Convert from feature name to feature guid. This conversion is
 805          * unecessary for unsupported@... properties because they already
 806          * use guids.
 807          */
 808         if (supported) {
 809                 int ret;
 810                 zfeature_info_t *fi;
 811 
 812                 ret = zfeature_lookup_name(feature, &fi);
 813                 if (ret != 0) {
 814                         (void) strlcpy(buf, "-", len);
 815                         return (ENOTSUP);
 816                 }
 817                 feature = fi->fi_guid;
 818         }
 819 
 820         if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
 821                 found = B_TRUE;
 822 
 823         if (supported) {
 824                 if (!found) {
 825                         (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
 826                 } else  {
 827                         if (refcount == 0)
 828                                 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
 829                         else
 830                                 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
 831                 }
 832         } else {
 833                 if (found) {
 834                         if (refcount == 0) {
 835                                 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
 836                         } else {
 837                                 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);




   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 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2013 by Delphix. All rights reserved.
  26  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  27  */
  28 
  29 #include <ctype.h>
  30 #include <errno.h>
  31 #include <devid.h>
  32 #include <fcntl.h>
  33 #include <libintl.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <unistd.h>
  38 #include <libgen.h>
  39 #include <sys/efi_partition.h>
  40 #include <sys/vtoc.h>
  41 #include <sys/zfs_ioctl.h>
  42 #include <dlfcn.h>
  43 
  44 #include "zfs_namecheck.h"
  45 #include "zfs_prop.h"


 396         zpool_prop_t prop;
 397         char *strval;
 398         uint64_t intval;
 399         char *slash, *check;
 400         struct stat64 statbuf;
 401         zpool_handle_t *zhp;
 402         nvlist_t *nvroot;
 403 
 404         if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
 405                 (void) no_memory(hdl);
 406                 return (NULL);
 407         }
 408 
 409         elem = NULL;
 410         while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
 411                 const char *propname = nvpair_name(elem);
 412 
 413                 prop = zpool_name_to_prop(propname);
 414                 if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
 415                         int err;

 416                         char *fname = strchr(propname, '@') + 1;
 417 
 418                         err = zfeature_lookup_name(fname, NULL);
 419                         if (err != 0) {
 420                                 ASSERT3U(err, ==, ENOENT);
 421                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 422                                     "invalid feature '%s'"), fname);
 423                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 424                                 goto error;
 425                         }
 426 
 427                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
 428                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 429                                     "'%s' must be a string"), propname);
 430                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 431                                 goto error;
 432                         }
 433 
 434                         (void) nvpair_value_string(elem, &strval);
 435                         if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
 436                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 437                                     "property '%s' can only be set to "
 438                                     "'enabled'"), propname);


 789 int
 790 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
 791     size_t len)
 792 {
 793         uint64_t refcount;
 794         boolean_t found = B_FALSE;
 795         nvlist_t *features = zpool_get_features(zhp);
 796         boolean_t supported;
 797         const char *feature = strchr(propname, '@') + 1;
 798 
 799         supported = zpool_prop_feature(propname);
 800         ASSERT(supported || zfs_prop_unsupported(propname));
 801 
 802         /*
 803          * Convert from feature name to feature guid. This conversion is
 804          * unecessary for unsupported@... properties because they already
 805          * use guids.
 806          */
 807         if (supported) {
 808                 int ret;
 809                 spa_feature_t fid;
 810 
 811                 ret = zfeature_lookup_name(feature, &fid);
 812                 if (ret != 0) {
 813                         (void) strlcpy(buf, "-", len);
 814                         return (ENOTSUP);
 815                 }
 816                 feature = spa_feature_table[fid].fi_guid;
 817         }
 818 
 819         if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
 820                 found = B_TRUE;
 821 
 822         if (supported) {
 823                 if (!found) {
 824                         (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
 825                 } else  {
 826                         if (refcount == 0)
 827                                 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
 828                         else
 829                                 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
 830                 }
 831         } else {
 832                 if (found) {
 833                         if (refcount == 0) {
 834                                 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
 835                         } else {
 836                                 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);