Print this page
NEX-9989 Changing volume names can result in double imports and data corruption
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5064 On-demand trim should store operation start and stop time
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-3984 On-demand TRIM
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Conflicts:
        usr/src/common/zfs/zpool_prop.c
        usr/src/uts/common/sys/fs/zfs.h
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
Bug 11205: add missing libzfs_closed_stubs.c to fix opensource-only build.
ZFS plus work: special vdevs, cos, cos/vdev properties

*** 19,29 **** * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright 2017 Joyent, Inc. */ #include <sys/spa.h> --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright 2017 Joyent, Inc. */ #include <sys/spa.h>
*** 54,64 **** * * For each cache file, we have a single nvlist which holds all the * configuration information. When the module loads, we read this information * from /etc/zfs/zpool.cache and populate the SPA namespace. This namespace is * maintained independently in spa.c. Whenever the namespace is modified, or ! * the configuration of a pool is changed, we call spa_write_cachefile(), which * walks through all the active pools and writes the configuration to disk. */ static uint64_t spa_config_generation = 1; --- 54,64 ---- * * For each cache file, we have a single nvlist which holds all the * configuration information. When the module loads, we read this information * from /etc/zfs/zpool.cache and populate the SPA namespace. This namespace is * maintained independently in spa.c. Whenever the namespace is modified, or ! * the configuration of a pool is changed, we call spa_config_sync(), which * walks through all the active pools and writes the configuration to disk. */ static uint64_t spa_config_generation = 1;
*** 120,136 **** * each one with the specified configuration. */ mutex_enter(&spa_namespace_lock); nvpair = NULL; while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) { if (nvpair_type(nvpair) != DATA_TYPE_NVLIST) continue; child = fnvpair_value_nvlist(nvpair); ! if (spa_lookup(nvpair_name(nvpair)) != NULL) continue; (void) spa_add(nvpair_name(nvpair), child, NULL); } mutex_exit(&spa_namespace_lock); nvlist_free(nvlist); --- 120,143 ---- * each one with the specified configuration. */ mutex_enter(&spa_namespace_lock); nvpair = NULL; while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) { + uint64_t guid = 0; + if (nvpair_type(nvpair) != DATA_TYPE_NVLIST) continue; child = fnvpair_value_nvlist(nvpair); + /* a zero guid means we simply will ignore the check later */ + (void) nvlist_lookup_uint64(child, ZPOOL_CONFIG_POOL_GUID, + &guid); ! if (spa_lookup(nvpair_name(nvpair)) != NULL || ! spa_config_guid_exists(guid)) { continue; + } (void) spa_add(nvpair_name(nvpair), child, NULL); } mutex_exit(&spa_namespace_lock); nvlist_free(nvlist);
*** 196,210 **** * Synchronize pool configuration to disk. This must be called with the * namespace lock held. Synchronizing the pool cache is typically done after * the configuration has been synced to the MOS. This exposes a window where * the MOS config will have been updated but the cache file has not. If * the system were to crash at that instant then the cached config may not ! * contain the correct information to open the pool and an explicit import * would be required. */ void ! spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent) { spa_config_dirent_t *dp, *tdp; nvlist_t *nvl; boolean_t ccw_failure; int error; --- 203,217 ---- * Synchronize pool configuration to disk. This must be called with the * namespace lock held. Synchronizing the pool cache is typically done after * the configuration has been synced to the MOS. This exposes a window where * the MOS config will have been updated but the cache file has not. If * the system were to crash at that instant then the cached config may not ! * contain the correct information to open the pool and an explicity import * would be required. */ void ! spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) { spa_config_dirent_t *dp, *tdp; nvlist_t *nvl; boolean_t ccw_failure; int error;
*** 337,347 **** void spa_config_set(spa_t *spa, nvlist_t *config) { mutex_enter(&spa->spa_props_lock); - if (spa->spa_config != NULL && spa->spa_config != config) nvlist_free(spa->spa_config); spa->spa_config = config; mutex_exit(&spa->spa_props_lock); } --- 344,353 ----
*** 385,396 **** if (spa->spa_comment != NULL) { fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT, spa->spa_comment); } hostid = zone_get_hostid(NULL); ! if (hostid != 0) { fnvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid); } fnvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, utsname.nodename); --- 391,409 ---- if (spa->spa_comment != NULL) { fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT, spa->spa_comment); } + #ifdef _KERNEL hostid = zone_get_hostid(NULL); ! #else /* _KERNEL */ ! /* ! * We're emulating the system's hostid in userland, so we can't use ! * zone_get_hostid(). ! */ ! (void) ddi_strtoul(hw_serial, NULL, 10, &hostid); ! #endif /* _KERNEL */ if (hostid != 0) { fnvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid); } fnvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, utsname.nodename);
*** 402,411 **** --- 415,427 ---- vd->vdev_guid); if (vd->vdev_isspare) { fnvlist_add_uint64(config, ZPOOL_CONFIG_IS_SPARE, 1ULL); } + if (vd->vdev_isspecial) + fnvlist_add_uint64(config, + ZPOOL_CONFIG_IS_SPECIAL, 1ULL); if (vd->vdev_islog) { fnvlist_add_uint64(config, ZPOOL_CONFIG_IS_LOG, 1ULL); } vd = vd->vdev_top; /* label contains top config */
*** 441,450 **** --- 457,479 ---- nvroot = vdev_config_generate(spa, vd, getstats, config_gen_flags); fnvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot); nvlist_free(nvroot); + /* If we're getting stats, calculate trim progress from leaf vdevs. */ + if (getstats) { + uint64_t prog, rate, start_time, stop_time; + + spa_get_trim_prog(spa, &prog, &rate, &start_time, &stop_time); + fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_PROG, prog); + fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_RATE, rate); + fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_START_TIME, + start_time); + fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_STOP_TIME, + stop_time); + } + /* * Store what's necessary for reading the MOS in the label. */ fnvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ, spa->spa_label_features);
*** 523,535 **** txg_wait_synced(spa->spa_dsl_pool, txg); /* * Update the global config cache to reflect the new mosconfig. */ ! if (!spa->spa_is_root) { ! spa_write_cachefile(spa, B_FALSE, ! what != SPA_CONFIG_UPDATE_POOL); ! } if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS); } --- 552,562 ---- txg_wait_synced(spa->spa_dsl_pool, txg); /* * Update the global config cache to reflect the new mosconfig. */ ! if (!spa->spa_is_root) ! spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS); }