spa_config.c (251631) | spa_config.c (251636) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 13 unchanged lines hidden (view full) --- 22/* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2012 by Delphix. All rights reserved. 26 */ 27 28#include <sys/zfs_context.h> 29#include <sys/spa.h> | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 13 unchanged lines hidden (view full) --- 22/* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2012 by Delphix. All rights reserved. 26 */ 27 28#include <sys/zfs_context.h> 29#include <sys/spa.h> |
30#include <sys/fm/fs/zfs.h> |
|
30#include <sys/spa_impl.h> 31#include <sys/nvpair.h> 32#include <sys/uio.h> 33#include <sys/fs/zfs.h> 34#include <sys/vdev_impl.h> 35#include <sys/zfs_ioctl.h> 36#include <sys/utsname.h> 37#include <sys/sunddi.h> --- 96 unchanged lines hidden (view full) --- 134 135out: 136 if (buf != NULL) 137 kmem_free(buf, fsize); 138 139 kobj_close_file(file); 140} 141 | 31#include <sys/spa_impl.h> 32#include <sys/nvpair.h> 33#include <sys/uio.h> 34#include <sys/fs/zfs.h> 35#include <sys/vdev_impl.h> 36#include <sys/zfs_ioctl.h> 37#include <sys/utsname.h> 38#include <sys/sunddi.h> --- 96 unchanged lines hidden (view full) --- 135 136out: 137 if (buf != NULL) 138 kmem_free(buf, fsize); 139 140 kobj_close_file(file); 141} 142 |
142static void | 143static int |
143spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) 144{ 145 size_t buflen; 146 char *buf; 147 vnode_t *vp; 148 int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX; 149 char *temp; | 144spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) 145{ 146 size_t buflen; 147 char *buf; 148 vnode_t *vp; 149 int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX; 150 char *temp; |
151 int err; |
|
150 151 /* 152 * If the nvlist is empty (NULL), then remove the old cachefile. 153 */ 154 if (nvl == NULL) { | 152 153 /* 154 * If the nvlist is empty (NULL), then remove the old cachefile. 155 */ 156 if (nvl == NULL) { |
155 (void) vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); 156 return; | 157 err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE); 158 return (err); |
157 } 158 159 /* 160 * Pack the configuration into a buffer. 161 */ 162 VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0); 163 164 buf = kmem_alloc(buflen, KM_SLEEP); --- 4 unchanged lines hidden (view full) --- 169 170 /* 171 * Write the configuration to disk. We need to do the traditional 172 * 'write to temporary file, sync, move over original' to make sure we 173 * always have a consistent view of the data. 174 */ 175 (void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path); 176 | 159 } 160 161 /* 162 * Pack the configuration into a buffer. 163 */ 164 VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0); 165 166 buf = kmem_alloc(buflen, KM_SLEEP); --- 4 unchanged lines hidden (view full) --- 171 172 /* 173 * Write the configuration to disk. We need to do the traditional 174 * 'write to temporary file, sync, move over original' to make sure we 175 * always have a consistent view of the data. 176 */ 177 (void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path); 178 |
177 if (vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0) == 0) { 178 if (vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, 179 0, RLIM64_INFINITY, kcred, NULL) == 0 && 180 VOP_FSYNC(vp, FSYNC, kcred, NULL) == 0) { 181 (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); 182 } | 179 err = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0); 180 if (err == 0) { 181 err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE, 182 0, RLIM64_INFINITY, kcred, NULL); 183 if (err == 0) 184 err = VOP_FSYNC(vp, FSYNC, kcred, NULL); 185 if (err == 0) 186 err = vn_rename(temp, dp->scd_path, UIO_SYSSPACE); |
183 (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); 184 } 185 186 (void) vn_remove(temp, UIO_SYSSPACE, RMFILE); 187 188 kmem_free(buf, buflen); 189 kmem_free(temp, MAXPATHLEN); | 187 (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); 188 } 189 190 (void) vn_remove(temp, UIO_SYSSPACE, RMFILE); 191 192 kmem_free(buf, buflen); 193 kmem_free(temp, MAXPATHLEN); |
194 return (err); |
|
190} 191 192/* 193 * Synchronize pool configuration to disk. This must be called with the 194 * namespace lock held. 195 */ 196void 197spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) 198{ 199 spa_config_dirent_t *dp, *tdp; 200 nvlist_t *nvl; | 195} 196 197/* 198 * Synchronize pool configuration to disk. This must be called with the 199 * namespace lock held. 200 */ 201void 202spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) 203{ 204 spa_config_dirent_t *dp, *tdp; 205 nvlist_t *nvl; |
206 boolean_t ccw_failure; 207 int error; |
|
201 202 ASSERT(MUTEX_HELD(&spa_namespace_lock)); 203 204 if (rootdir == NULL || !(spa_mode_global & FWRITE)) 205 return; 206 207 /* 208 * Iterate over all cachefiles for the pool, past or present. When the 209 * cachefile is changed, the new one is pushed onto this list, allowing 210 * us to update previous cachefiles that no longer contain this pool. 211 */ | 208 209 ASSERT(MUTEX_HELD(&spa_namespace_lock)); 210 211 if (rootdir == NULL || !(spa_mode_global & FWRITE)) 212 return; 213 214 /* 215 * Iterate over all cachefiles for the pool, past or present. When the 216 * cachefile is changed, the new one is pushed onto this list, allowing 217 * us to update previous cachefiles that no longer contain this pool. 218 */ |
219 ccw_failure = B_FALSE; |
|
212 for (dp = list_head(&target->spa_config_list); dp != NULL; 213 dp = list_next(&target->spa_config_list, dp)) { 214 spa_t *spa = NULL; 215 if (dp->scd_path == NULL) 216 continue; 217 218 /* 219 * Iterate over all pools, adding any matching pools to 'nvl'. --- 24 unchanged lines hidden (view full) --- 244 VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, 245 KM_SLEEP) == 0); 246 247 VERIFY(nvlist_add_nvlist(nvl, spa->spa_name, 248 spa->spa_config) == 0); 249 mutex_exit(&spa->spa_props_lock); 250 } 251 | 220 for (dp = list_head(&target->spa_config_list); dp != NULL; 221 dp = list_next(&target->spa_config_list, dp)) { 222 spa_t *spa = NULL; 223 if (dp->scd_path == NULL) 224 continue; 225 226 /* 227 * Iterate over all pools, adding any matching pools to 'nvl'. --- 24 unchanged lines hidden (view full) --- 252 VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, 253 KM_SLEEP) == 0); 254 255 VERIFY(nvlist_add_nvlist(nvl, spa->spa_name, 256 spa->spa_config) == 0); 257 mutex_exit(&spa->spa_props_lock); 258 } 259 |
252 spa_config_write(dp, nvl); | 260 error = spa_config_write(dp, nvl); 261 if (error != 0) 262 ccw_failure = B_TRUE; |
253 nvlist_free(nvl); 254 } 255 | 263 nvlist_free(nvl); 264 } 265 |
266 if (ccw_failure) { 267 /* 268 * Keep trying so that configuration data is 269 * written if/when any temporary filesystem 270 * resource issues are resolved. 271 */ 272 if (target->spa_ccw_fail_time == 0) { 273 zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE, 274 target, NULL, NULL, 0, 0); 275 } 276 target->spa_ccw_fail_time = gethrtime(); 277 spa_async_request(target, SPA_ASYNC_CONFIG_UPDATE); 278 } else { 279 /* 280 * Do not rate limit future attempts to update 281 * the config cache. 282 */ 283 target->spa_ccw_fail_time = 0; 284 } 285 |
|
256 /* 257 * Remove any config entries older than the current one. 258 */ 259 dp = list_head(&target->spa_config_list); 260 while ((tdp = list_next(&target->spa_config_list, dp)) != NULL) { 261 list_remove(&target->spa_config_list, tdp); 262 if (tdp->scd_path != NULL) 263 spa_strfree(tdp->scd_path); --- 244 unchanged lines hidden --- | 286 /* 287 * Remove any config entries older than the current one. 288 */ 289 dp = list_head(&target->spa_config_list); 290 while ((tdp = list_next(&target->spa_config_list, dp)) != NULL) { 291 list_remove(&target->spa_config_list, tdp); 292 if (tdp->scd_path != NULL) 293 spa_strfree(tdp->scd_path); --- 244 unchanged lines hidden --- |