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