xref: /freebsd/sys/contrib/openzfs/module/zcommon/zfs_comutil.c (revision 1603881667360c015f6685131f2f25474fa67a72)
1eda14cbcSMatt Macy /*
2eda14cbcSMatt Macy  * CDDL HEADER START
3eda14cbcSMatt Macy  *
4eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy  *
8eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9eda14cbcSMatt Macy  * or http://www.opensolaris.org/os/licensing.
10eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11eda14cbcSMatt Macy  * and limitations under the License.
12eda14cbcSMatt Macy  *
13eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy  *
19eda14cbcSMatt Macy  * CDDL HEADER END
20eda14cbcSMatt Macy  */
21eda14cbcSMatt Macy /*
22eda14cbcSMatt Macy  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23eda14cbcSMatt Macy  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
24eda14cbcSMatt Macy  */
25eda14cbcSMatt Macy 
26eda14cbcSMatt Macy /*
27eda14cbcSMatt Macy  * This file is intended for functions that ought to be common between user
28eda14cbcSMatt Macy  * land (libzfs) and the kernel. When many common routines need to be shared
29*16038816SMartin Matuska  * then a separate file should be created.
30eda14cbcSMatt Macy  */
31eda14cbcSMatt Macy 
32eda14cbcSMatt Macy #if !defined(_KERNEL)
33eda14cbcSMatt Macy #include <string.h>
34eda14cbcSMatt Macy #endif
35eda14cbcSMatt Macy 
36eda14cbcSMatt Macy #include <sys/types.h>
37eda14cbcSMatt Macy #include <sys/fs/zfs.h>
38eda14cbcSMatt Macy #include <sys/nvpair.h>
39eda14cbcSMatt Macy #include "zfs_comutil.h"
40eda14cbcSMatt Macy #include <sys/zfs_ratelimit.h>
41eda14cbcSMatt Macy 
42eda14cbcSMatt Macy /*
43eda14cbcSMatt Macy  * Are there allocatable vdevs?
44eda14cbcSMatt Macy  */
45eda14cbcSMatt Macy boolean_t
46eda14cbcSMatt Macy zfs_allocatable_devs(nvlist_t *nv)
47eda14cbcSMatt Macy {
48eda14cbcSMatt Macy 	uint64_t is_log;
49eda14cbcSMatt Macy 	uint_t c;
50eda14cbcSMatt Macy 	nvlist_t **child;
51eda14cbcSMatt Macy 	uint_t children;
52eda14cbcSMatt Macy 
53eda14cbcSMatt Macy 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
54eda14cbcSMatt Macy 	    &child, &children) != 0) {
55eda14cbcSMatt Macy 		return (B_FALSE);
56eda14cbcSMatt Macy 	}
57eda14cbcSMatt Macy 	for (c = 0; c < children; c++) {
58eda14cbcSMatt Macy 		is_log = 0;
59eda14cbcSMatt Macy 		(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
60eda14cbcSMatt Macy 		    &is_log);
61eda14cbcSMatt Macy 		if (!is_log)
62eda14cbcSMatt Macy 			return (B_TRUE);
63eda14cbcSMatt Macy 	}
64eda14cbcSMatt Macy 	return (B_FALSE);
65eda14cbcSMatt Macy }
66eda14cbcSMatt Macy 
67eda14cbcSMatt Macy /*
68eda14cbcSMatt Macy  * Are there special vdevs?
69eda14cbcSMatt Macy  */
70eda14cbcSMatt Macy boolean_t
71eda14cbcSMatt Macy zfs_special_devs(nvlist_t *nv, char *type)
72eda14cbcSMatt Macy {
73eda14cbcSMatt Macy 	char *bias;
74eda14cbcSMatt Macy 	uint_t c;
75eda14cbcSMatt Macy 	nvlist_t **child;
76eda14cbcSMatt Macy 	uint_t children;
77eda14cbcSMatt Macy 
78eda14cbcSMatt Macy 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
79eda14cbcSMatt Macy 	    &child, &children) != 0) {
80eda14cbcSMatt Macy 		return (B_FALSE);
81eda14cbcSMatt Macy 	}
82eda14cbcSMatt Macy 	for (c = 0; c < children; c++) {
83eda14cbcSMatt Macy 		if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS,
84eda14cbcSMatt Macy 		    &bias) == 0) {
85eda14cbcSMatt Macy 			if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0 ||
86eda14cbcSMatt Macy 			    strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0) {
87eda14cbcSMatt Macy 				if (type != NULL && strcmp(bias, type) == 0) {
88eda14cbcSMatt Macy 					return (B_TRUE);
89eda14cbcSMatt Macy 				} else if (type == NULL) {
90eda14cbcSMatt Macy 					return (B_TRUE);
91eda14cbcSMatt Macy 				}
92eda14cbcSMatt Macy 			}
93eda14cbcSMatt Macy 		}
94eda14cbcSMatt Macy 	}
95eda14cbcSMatt Macy 	return (B_FALSE);
96eda14cbcSMatt Macy }
97eda14cbcSMatt Macy 
98eda14cbcSMatt Macy void
99eda14cbcSMatt Macy zpool_get_load_policy(nvlist_t *nvl, zpool_load_policy_t *zlpp)
100eda14cbcSMatt Macy {
101eda14cbcSMatt Macy 	nvlist_t *policy;
102eda14cbcSMatt Macy 	nvpair_t *elem;
103eda14cbcSMatt Macy 	char *nm;
104eda14cbcSMatt Macy 
105eda14cbcSMatt Macy 	/* Defaults */
106eda14cbcSMatt Macy 	zlpp->zlp_rewind = ZPOOL_NO_REWIND;
107eda14cbcSMatt Macy 	zlpp->zlp_maxmeta = 0;
108eda14cbcSMatt Macy 	zlpp->zlp_maxdata = UINT64_MAX;
109eda14cbcSMatt Macy 	zlpp->zlp_txg = UINT64_MAX;
110eda14cbcSMatt Macy 
111eda14cbcSMatt Macy 	if (nvl == NULL)
112eda14cbcSMatt Macy 		return;
113eda14cbcSMatt Macy 
114eda14cbcSMatt Macy 	elem = NULL;
115eda14cbcSMatt Macy 	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
116eda14cbcSMatt Macy 		nm = nvpair_name(elem);
117eda14cbcSMatt Macy 		if (strcmp(nm, ZPOOL_LOAD_POLICY) == 0) {
118eda14cbcSMatt Macy 			if (nvpair_value_nvlist(elem, &policy) == 0)
119eda14cbcSMatt Macy 				zpool_get_load_policy(policy, zlpp);
120eda14cbcSMatt Macy 			return;
121eda14cbcSMatt Macy 		} else if (strcmp(nm, ZPOOL_LOAD_REWIND_POLICY) == 0) {
122eda14cbcSMatt Macy 			if (nvpair_value_uint32(elem, &zlpp->zlp_rewind) == 0)
123eda14cbcSMatt Macy 				if (zlpp->zlp_rewind & ~ZPOOL_REWIND_POLICIES)
124eda14cbcSMatt Macy 					zlpp->zlp_rewind = ZPOOL_NO_REWIND;
125eda14cbcSMatt Macy 		} else if (strcmp(nm, ZPOOL_LOAD_REQUEST_TXG) == 0) {
126eda14cbcSMatt Macy 			(void) nvpair_value_uint64(elem, &zlpp->zlp_txg);
127eda14cbcSMatt Macy 		} else if (strcmp(nm, ZPOOL_LOAD_META_THRESH) == 0) {
128eda14cbcSMatt Macy 			(void) nvpair_value_uint64(elem, &zlpp->zlp_maxmeta);
129eda14cbcSMatt Macy 		} else if (strcmp(nm, ZPOOL_LOAD_DATA_THRESH) == 0) {
130eda14cbcSMatt Macy 			(void) nvpair_value_uint64(elem, &zlpp->zlp_maxdata);
131eda14cbcSMatt Macy 		}
132eda14cbcSMatt Macy 	}
133eda14cbcSMatt Macy 	if (zlpp->zlp_rewind == 0)
134eda14cbcSMatt Macy 		zlpp->zlp_rewind = ZPOOL_NO_REWIND;
135eda14cbcSMatt Macy }
136eda14cbcSMatt Macy 
137eda14cbcSMatt Macy typedef struct zfs_version_spa_map {
138eda14cbcSMatt Macy 	int	version_zpl;
139eda14cbcSMatt Macy 	int	version_spa;
140eda14cbcSMatt Macy } zfs_version_spa_map_t;
141eda14cbcSMatt Macy 
142eda14cbcSMatt Macy /*
143eda14cbcSMatt Macy  * Keep this table in monotonically increasing version number order.
144eda14cbcSMatt Macy  */
145eda14cbcSMatt Macy static zfs_version_spa_map_t zfs_version_table[] = {
146eda14cbcSMatt Macy 	{ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL},
147eda14cbcSMatt Macy 	{ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL},
148eda14cbcSMatt Macy 	{ZPL_VERSION_FUID, SPA_VERSION_FUID},
149eda14cbcSMatt Macy 	{ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE},
150eda14cbcSMatt Macy 	{ZPL_VERSION_SA, SPA_VERSION_SA},
151eda14cbcSMatt Macy 	{0, 0}
152eda14cbcSMatt Macy };
153eda14cbcSMatt Macy 
154eda14cbcSMatt Macy /*
155eda14cbcSMatt Macy  * Return the max zpl version for a corresponding spa version
156eda14cbcSMatt Macy  * -1 is returned if no mapping exists.
157eda14cbcSMatt Macy  */
158eda14cbcSMatt Macy int
159eda14cbcSMatt Macy zfs_zpl_version_map(int spa_version)
160eda14cbcSMatt Macy {
161eda14cbcSMatt Macy 	int i;
162eda14cbcSMatt Macy 	int version = -1;
163eda14cbcSMatt Macy 
164eda14cbcSMatt Macy 	for (i = 0; zfs_version_table[i].version_spa; i++) {
165eda14cbcSMatt Macy 		if (spa_version >= zfs_version_table[i].version_spa)
166eda14cbcSMatt Macy 			version = zfs_version_table[i].version_zpl;
167eda14cbcSMatt Macy 	}
168eda14cbcSMatt Macy 
169eda14cbcSMatt Macy 	return (version);
170eda14cbcSMatt Macy }
171eda14cbcSMatt Macy 
172eda14cbcSMatt Macy /*
173eda14cbcSMatt Macy  * Return the min spa version for a corresponding spa version
174eda14cbcSMatt Macy  * -1 is returned if no mapping exists.
175eda14cbcSMatt Macy  */
176eda14cbcSMatt Macy int
177eda14cbcSMatt Macy zfs_spa_version_map(int zpl_version)
178eda14cbcSMatt Macy {
179eda14cbcSMatt Macy 	int i;
180eda14cbcSMatt Macy 	int version = -1;
181eda14cbcSMatt Macy 
182eda14cbcSMatt Macy 	for (i = 0; zfs_version_table[i].version_zpl; i++) {
183eda14cbcSMatt Macy 		if (zfs_version_table[i].version_zpl >= zpl_version)
184eda14cbcSMatt Macy 			return (zfs_version_table[i].version_spa);
185eda14cbcSMatt Macy 	}
186eda14cbcSMatt Macy 
187eda14cbcSMatt Macy 	return (version);
188eda14cbcSMatt Macy }
189eda14cbcSMatt Macy 
190eda14cbcSMatt Macy /*
191eda14cbcSMatt Macy  * This is the table of legacy internal event names; it should not be modified.
192eda14cbcSMatt Macy  * The internal events are now stored in the history log as strings.
193eda14cbcSMatt Macy  */
194eda14cbcSMatt Macy const char *zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS] = {
195eda14cbcSMatt Macy 	"invalid event",
196eda14cbcSMatt Macy 	"pool create",
197eda14cbcSMatt Macy 	"vdev add",
198eda14cbcSMatt Macy 	"pool remove",
199eda14cbcSMatt Macy 	"pool destroy",
200eda14cbcSMatt Macy 	"pool export",
201eda14cbcSMatt Macy 	"pool import",
202eda14cbcSMatt Macy 	"vdev attach",
203eda14cbcSMatt Macy 	"vdev replace",
204eda14cbcSMatt Macy 	"vdev detach",
205eda14cbcSMatt Macy 	"vdev online",
206eda14cbcSMatt Macy 	"vdev offline",
207eda14cbcSMatt Macy 	"vdev upgrade",
208eda14cbcSMatt Macy 	"pool clear",
209eda14cbcSMatt Macy 	"pool scrub",
210eda14cbcSMatt Macy 	"pool property set",
211eda14cbcSMatt Macy 	"create",
212eda14cbcSMatt Macy 	"clone",
213eda14cbcSMatt Macy 	"destroy",
214eda14cbcSMatt Macy 	"destroy_begin_sync",
215eda14cbcSMatt Macy 	"inherit",
216eda14cbcSMatt Macy 	"property set",
217eda14cbcSMatt Macy 	"quota set",
218eda14cbcSMatt Macy 	"permission update",
219eda14cbcSMatt Macy 	"permission remove",
220eda14cbcSMatt Macy 	"permission who remove",
221eda14cbcSMatt Macy 	"promote",
222eda14cbcSMatt Macy 	"receive",
223eda14cbcSMatt Macy 	"rename",
224eda14cbcSMatt Macy 	"reservation set",
225eda14cbcSMatt Macy 	"replay_inc_sync",
226eda14cbcSMatt Macy 	"replay_full_sync",
227eda14cbcSMatt Macy 	"rollback",
228eda14cbcSMatt Macy 	"snapshot",
229eda14cbcSMatt Macy 	"filesystem version upgrade",
230eda14cbcSMatt Macy 	"refquota set",
231eda14cbcSMatt Macy 	"refreservation set",
232eda14cbcSMatt Macy 	"pool scrub done",
233eda14cbcSMatt Macy 	"user hold",
234eda14cbcSMatt Macy 	"user release",
235eda14cbcSMatt Macy 	"pool split",
236eda14cbcSMatt Macy };
237eda14cbcSMatt Macy 
238eda14cbcSMatt Macy boolean_t
239eda14cbcSMatt Macy zfs_dataset_name_hidden(const char *name)
240eda14cbcSMatt Macy {
241eda14cbcSMatt Macy 	/*
242eda14cbcSMatt Macy 	 * Skip over datasets that are not visible in this zone,
243eda14cbcSMatt Macy 	 * internal datasets (which have a $ in their name), and
244eda14cbcSMatt Macy 	 * temporary datasets (which have a % in their name).
245eda14cbcSMatt Macy 	 */
246eda14cbcSMatt Macy 	if (strchr(name, '$') != NULL)
247eda14cbcSMatt Macy 		return (B_TRUE);
248eda14cbcSMatt Macy 	if (strchr(name, '%') != NULL)
249eda14cbcSMatt Macy 		return (B_TRUE);
250eda14cbcSMatt Macy 	if (!INGLOBALZONE(curproc) && !zone_dataset_visible(name, NULL))
251eda14cbcSMatt Macy 		return (B_TRUE);
252eda14cbcSMatt Macy 	return (B_FALSE);
253eda14cbcSMatt Macy }
254eda14cbcSMatt Macy 
255eda14cbcSMatt Macy #if defined(_KERNEL)
256eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_allocatable_devs);
257eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_special_devs);
258eda14cbcSMatt Macy EXPORT_SYMBOL(zpool_get_load_policy);
259eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_zpl_version_map);
260eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_spa_version_map);
261eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_history_event_names);
262eda14cbcSMatt Macy EXPORT_SYMBOL(zfs_dataset_name_hidden);
263eda14cbcSMatt Macy #endif
264