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);
|