X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fspa_config.c;h=849ae46ec6c8f0594fd2999c6e629e174d4ca279;hb=31455ab13056da037410353f10c484dfca3d3ebc;hp=cdeda3f93cbaa0efde515765f53b42261f44bbd0;hpb=428870ff734fdaccc342b33fc53cf94724409a46;p=zfs.git diff --git a/module/zfs/spa_config.c b/module/zfs/spa_config.c index cdeda3f..849ae46 100644 --- a/module/zfs/spa_config.c +++ b/module/zfs/spa_config.c @@ -21,6 +21,8 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include @@ -33,6 +35,7 @@ #include #include #include +#include #ifdef _KERNEL #include #include @@ -61,7 +64,8 @@ static uint64_t spa_config_generation = 1; * This can be overridden in userland to preserve an alternate namespace for * userland pools when doing testing. */ -const char *spa_config_path = ZPOOL_CACHE; +char *spa_config_path = ZPOOL_CACHE; +int zfs_autoimport_disable = 0; /* * Called when the module is first loaded, this routine loads the configuration @@ -78,10 +82,13 @@ spa_config_load(void) struct _buf *file; uint64_t fsize; + if (zfs_autoimport_disable) + return; + /* * Open the configuration file. */ - pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); + pathname = kmem_alloc(MAXPATHLEN, KM_PUSHPAGE); (void) snprintf(pathname, MAXPATHLEN, "%s%s", (rootdir != NULL) ? "./" : "", spa_config_path); @@ -96,7 +103,7 @@ spa_config_load(void) if (kobj_get_filesize(file, &fsize) != 0) goto out; - buf = kmem_alloc(fsize, KM_SLEEP); + buf = kmem_alloc(fsize, KM_PUSHPAGE | KM_NODEBUG); /* * Read the nvlist from the file. @@ -107,7 +114,7 @@ spa_config_load(void) /* * Unpack the nvlist. */ - if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0) + if (nvlist_unpack(buf, fsize, &nvlist, KM_PUSHPAGE) != 0) goto out; /* @@ -159,11 +166,11 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) */ VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0); - buf = kmem_alloc(buflen, KM_SLEEP); - temp = kmem_zalloc(MAXPATHLEN, KM_SLEEP); + buf = kmem_alloc(buflen, KM_PUSHPAGE | KM_NODEBUG); + temp = kmem_zalloc(MAXPATHLEN, KM_PUSHPAGE); VERIFY(nvlist_pack(nvl, &buf, &buflen, NV_ENCODE_XDR, - KM_SLEEP) == 0); + KM_PUSHPAGE) == 0); /* * Write the configuration to disk. We need to do the traditional @@ -179,7 +186,6 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); } (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); - VN_RELE(vp); } (void) vn_remove(temp, UIO_SYSSPACE, RMFILE); @@ -233,7 +239,7 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) if (nvl == NULL) VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, - KM_SLEEP) == 0); + KM_PUSHPAGE) == 0); VERIFY(nvlist_add_nvlist(nvl, spa->spa_name, spa->spa_config) == 0); @@ -258,7 +264,7 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) spa_config_generation++; if (postsysevent) - spa_event_notify(target, NULL, ESC_ZFS_CONFIG_SYNC); + spa_event_notify(target, NULL, FM_EREPORT_ZFS_CONFIG_SYNC); } /* @@ -276,7 +282,7 @@ spa_all_configs(uint64_t *generation) if (*generation == spa_config_generation) return (NULL); - VERIFY(nvlist_alloc(&pools, NV_UNIQUE_NAME, KM_SLEEP) == 0); + VERIFY(nvlist_alloc(&pools, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0); mutex_enter(&spa_namespace_lock); while ((spa = spa_next(spa)) != NULL) { @@ -304,24 +310,6 @@ spa_config_set(spa_t *spa, nvlist_t *config) mutex_exit(&spa->spa_props_lock); } -/* Add discovered rewind info, if any to the provided nvlist */ -void -spa_rewind_data_to_nvlist(spa_t *spa, nvlist_t *tonvl) -{ - int64_t loss = 0; - - if (tonvl == NULL || spa->spa_load_txg == 0) - return; - - VERIFY(nvlist_add_uint64(tonvl, ZPOOL_CONFIG_LOAD_TIME, - spa->spa_load_txg_ts) == 0); - if (spa->spa_last_ubsync_txg) - loss = spa->spa_last_ubsync_txg_ts - spa->spa_load_txg_ts; - VERIFY(nvlist_add_int64(tonvl, ZPOOL_CONFIG_REWIND_TIME, loss) == 0); - VERIFY(nvlist_add_uint64(tonvl, ZPOOL_CONFIG_LOAD_DATA_ERRORS, - spa->spa_load_data_errors) == 0); -} - /* * Generate the pool's configuration based on the current in-core state. * We infer whether to generate a complete config or just one top-level config @@ -351,7 +339,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) if (txg == -1ULL) txg = spa->spa_config_txg; - VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, KM_SLEEP) == 0); + VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, KM_PUSHPAGE) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VERSION, spa_version(spa)) == 0); @@ -363,6 +351,10 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) txg) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa)) == 0); + VERIFY(spa->spa_comment == NULL || nvlist_add_string(config, + ZPOOL_CONFIG_COMMENT, spa->spa_comment) == 0); + + #ifdef _KERNEL hostid = zone_get_hostid(NULL); #else /* _KERNEL */ @@ -403,8 +395,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) /* * Add the top-level config. We even add this on pools which - * don't support holes in the namespace as older pools will - * just ignore it. + * don't support holes in the namespace. */ vdev_top_config_generate(spa, config); @@ -422,26 +413,32 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); nvlist_free(nvroot); + /* + * Store what's necessary for reading the MOS in the label. + */ + VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ, + spa->spa_label_features) == 0); + if (getstats && spa_load_state(spa) == SPA_LOAD_NONE) { ddt_histogram_t *ddh; ddt_stat_t *dds; ddt_object_t *ddo; - ddh = kmem_zalloc(sizeof (ddt_histogram_t), KM_SLEEP); + ddh = kmem_zalloc(sizeof (ddt_histogram_t), KM_PUSHPAGE); ddt_get_dedup_histogram(spa, ddh); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, (uint64_t *)ddh, sizeof (*ddh) / sizeof (uint64_t)) == 0); kmem_free(ddh, sizeof (ddt_histogram_t)); - ddo = kmem_zalloc(sizeof (ddt_object_t), KM_SLEEP); + ddo = kmem_zalloc(sizeof (ddt_object_t), KM_PUSHPAGE); ddt_get_dedup_object_stats(spa, ddo); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, (uint64_t *)ddo, sizeof (*ddo) / sizeof (uint64_t)) == 0); kmem_free(ddo, sizeof (ddt_object_t)); - dds = kmem_zalloc(sizeof (ddt_stat_t), KM_SLEEP); + dds = kmem_zalloc(sizeof (ddt_stat_t), KM_PUSHPAGE); ddt_get_dedup_stats(spa, dds); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, @@ -449,8 +446,6 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) kmem_free(dds, sizeof (ddt_stat_t)); } - spa_rewind_data_to_nvlist(spa, config); - if (locked) spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG); @@ -506,3 +501,19 @@ spa_config_update(spa_t *spa, int what) if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS); } + +#if defined(_KERNEL) && defined(HAVE_SPL) +EXPORT_SYMBOL(spa_config_sync); +EXPORT_SYMBOL(spa_config_load); +EXPORT_SYMBOL(spa_all_configs); +EXPORT_SYMBOL(spa_config_set); +EXPORT_SYMBOL(spa_config_generate); +EXPORT_SYMBOL(spa_config_update); + +module_param(spa_config_path, charp, 0444); +MODULE_PARM_DESC(spa_config_path, "SPA config file (/etc/zfs/zpool.cache)"); + +module_param(zfs_autoimport_disable, int, 0644); +MODULE_PARM_DESC(zfs_autoimport_disable, "Disable pool import at module load"); + +#endif