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