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