Print this page
5882 Temporary pool names
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>


 191         kmem_free(temp, MAXPATHLEN);
 192         return (err);
 193 }
 194 
 195 /*
 196  * Synchronize pool configuration to disk.  This must be called with the
 197  * namespace lock held. Synchronizing the pool cache is typically done after
 198  * the configuration has been synced to the MOS. This exposes a window where
 199  * the MOS config will have been updated but the cache file has not. If
 200  * the system were to crash at that instant then the cached config may not
 201  * contain the correct information to open the pool and an explicit import
 202  * would be required.
 203  */
 204 void
 205 spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
 206 {
 207         spa_config_dirent_t *dp, *tdp;
 208         nvlist_t *nvl;
 209         boolean_t ccw_failure;
 210         int error;

 211 
 212         ASSERT(MUTEX_HELD(&spa_namespace_lock));
 213 
 214         if (rootdir == NULL || !(spa_mode_global & FWRITE))
 215                 return;
 216 
 217         /*
 218          * Iterate over all cachefiles for the pool, past or present.  When the
 219          * cachefile is changed, the new one is pushed onto this list, allowing
 220          * us to update previous cachefiles that no longer contain this pool.
 221          */
 222         ccw_failure = B_FALSE;
 223         for (dp = list_head(&target->spa_config_list); dp != NULL;
 224             dp = list_next(&target->spa_config_list, dp)) {
 225                 spa_t *spa = NULL;
 226                 if (dp->scd_path == NULL)
 227                         continue;
 228 
 229                 /*
 230                  * Iterate over all pools, adding any matching pools to 'nvl'.


 237                          * is readonly. Since we cannot guarantee that a
 238                          * readonly pool would successfully import upon reboot,
 239                          * we don't allow them to be written to the cache file.
 240                          */
 241                         if ((spa == target && removing) ||
 242                             !spa_writeable(spa))
 243                                 continue;
 244 
 245                         mutex_enter(&spa->spa_props_lock);
 246                         tdp = list_head(&spa->spa_config_list);
 247                         if (spa->spa_config == NULL ||
 248                             tdp->scd_path == NULL ||
 249                             strcmp(tdp->scd_path, dp->scd_path) != 0) {
 250                                 mutex_exit(&spa->spa_props_lock);
 251                                 continue;
 252                         }
 253 
 254                         if (nvl == NULL)
 255                                 nvl = fnvlist_alloc();
 256 
 257                         fnvlist_add_nvlist(nvl, spa->spa_name,







 258                             spa->spa_config);
 259                         mutex_exit(&spa->spa_props_lock);
 260                 }
 261 
 262                 error = spa_config_write(dp, nvl);
 263                 if (error != 0)
 264                         ccw_failure = B_TRUE;
 265                 nvlist_free(nvl);
 266         }
 267 
 268         if (ccw_failure) {
 269                 /*
 270                  * Keep trying so that configuration data is
 271                  * written if/when any temporary filesystem
 272                  * resource issues are resolved.
 273                  */
 274                 if (target->spa_ccw_fail_time == 0) {
 275                         zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
 276                             target, NULL, NULL, 0, 0);
 277                 }


 342         if (spa->spa_config != NULL && spa->spa_config != config)
 343                 nvlist_free(spa->spa_config);
 344         spa->spa_config = config;
 345         mutex_exit(&spa->spa_props_lock);
 346 }
 347 
 348 /*
 349  * Generate the pool's configuration based on the current in-core state.
 350  *
 351  * We infer whether to generate a complete config or just one top-level config
 352  * based on whether vd is the root vdev.
 353  */
 354 nvlist_t *
 355 spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
 356 {
 357         nvlist_t *config, *nvroot;
 358         vdev_t *rvd = spa->spa_root_vdev;
 359         unsigned long hostid = 0;
 360         boolean_t locked = B_FALSE;
 361         uint64_t split_guid;

 362 
 363         if (vd == NULL) {
 364                 vd = rvd;
 365                 locked = B_TRUE;
 366                 spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
 367         }
 368 
 369         ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER) ==
 370             (SCL_CONFIG | SCL_STATE));
 371 
 372         /*
 373          * If txg is -1, report the current value of spa->spa_config_txg.
 374          */
 375         if (txg == -1ULL)
 376                 txg = spa->spa_config_txg;
 377 

















 378         config = fnvlist_alloc();
 379 
 380         fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION, spa_version(spa));
 381         fnvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, spa_name(spa));
 382         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, spa_state(spa));
 383         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg);
 384         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa));
 385         if (spa->spa_comment != NULL) {
 386                 fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT,
 387                     spa->spa_comment);
 388         }
 389 
 390         hostid = zone_get_hostid(NULL);
 391 
 392         if (hostid != 0) {
 393                 fnvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid);
 394         }
 395         fnvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, utsname.nodename);
 396 
 397         int config_gen_flags = 0;
 398         if (vd != rvd) {
 399                 fnvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
 400                     vd->vdev_top->vdev_guid);
 401                 fnvlist_add_uint64(config, ZPOOL_CONFIG_GUID,




 191         kmem_free(temp, MAXPATHLEN);
 192         return (err);
 193 }
 194 
 195 /*
 196  * Synchronize pool configuration to disk.  This must be called with the
 197  * namespace lock held. Synchronizing the pool cache is typically done after
 198  * the configuration has been synced to the MOS. This exposes a window where
 199  * the MOS config will have been updated but the cache file has not. If
 200  * the system were to crash at that instant then the cached config may not
 201  * contain the correct information to open the pool and an explicit import
 202  * would be required.
 203  */
 204 void
 205 spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
 206 {
 207         spa_config_dirent_t *dp, *tdp;
 208         nvlist_t *nvl;
 209         boolean_t ccw_failure;
 210         int error;
 211         char *pool_name;
 212 
 213         ASSERT(MUTEX_HELD(&spa_namespace_lock));
 214 
 215         if (rootdir == NULL || !(spa_mode_global & FWRITE))
 216                 return;
 217 
 218         /*
 219          * Iterate over all cachefiles for the pool, past or present.  When the
 220          * cachefile is changed, the new one is pushed onto this list, allowing
 221          * us to update previous cachefiles that no longer contain this pool.
 222          */
 223         ccw_failure = B_FALSE;
 224         for (dp = list_head(&target->spa_config_list); dp != NULL;
 225             dp = list_next(&target->spa_config_list, dp)) {
 226                 spa_t *spa = NULL;
 227                 if (dp->scd_path == NULL)
 228                         continue;
 229 
 230                 /*
 231                  * Iterate over all pools, adding any matching pools to 'nvl'.


 238                          * is readonly. Since we cannot guarantee that a
 239                          * readonly pool would successfully import upon reboot,
 240                          * we don't allow them to be written to the cache file.
 241                          */
 242                         if ((spa == target && removing) ||
 243                             !spa_writeable(spa))
 244                                 continue;
 245 
 246                         mutex_enter(&spa->spa_props_lock);
 247                         tdp = list_head(&spa->spa_config_list);
 248                         if (spa->spa_config == NULL ||
 249                             tdp->scd_path == NULL ||
 250                             strcmp(tdp->scd_path, dp->scd_path) != 0) {
 251                                 mutex_exit(&spa->spa_props_lock);
 252                                 continue;
 253                         }
 254 
 255                         if (nvl == NULL)
 256                                 nvl = fnvlist_alloc();
 257 
 258                         if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
 259                                 pool_name = fnvlist_lookup_string(
 260                                     spa->spa_config, ZPOOL_CONFIG_POOL_NAME);
 261                         } else {
 262                                 pool_name = spa_name(spa);
 263                         }
 264 
 265                         fnvlist_add_nvlist(nvl, pool_name,
 266                             spa->spa_config);
 267                         mutex_exit(&spa->spa_props_lock);
 268                 }
 269 
 270                 error = spa_config_write(dp, nvl);
 271                 if (error != 0)
 272                         ccw_failure = B_TRUE;
 273                 nvlist_free(nvl);
 274         }
 275 
 276         if (ccw_failure) {
 277                 /*
 278                  * Keep trying so that configuration data is
 279                  * written if/when any temporary filesystem
 280                  * resource issues are resolved.
 281                  */
 282                 if (target->spa_ccw_fail_time == 0) {
 283                         zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
 284                             target, NULL, NULL, 0, 0);
 285                 }


 350         if (spa->spa_config != NULL && spa->spa_config != config)
 351                 nvlist_free(spa->spa_config);
 352         spa->spa_config = config;
 353         mutex_exit(&spa->spa_props_lock);
 354 }
 355 
 356 /*
 357  * Generate the pool's configuration based on the current in-core state.
 358  *
 359  * We infer whether to generate a complete config or just one top-level config
 360  * based on whether vd is the root vdev.
 361  */
 362 nvlist_t *
 363 spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
 364 {
 365         nvlist_t *config, *nvroot;
 366         vdev_t *rvd = spa->spa_root_vdev;
 367         unsigned long hostid = 0;
 368         boolean_t locked = B_FALSE;
 369         uint64_t split_guid;
 370         char *pool_name;
 371 
 372         if (vd == NULL) {
 373                 vd = rvd;
 374                 locked = B_TRUE;
 375                 spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
 376         }
 377 
 378         ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER) ==
 379             (SCL_CONFIG | SCL_STATE));
 380 
 381         /*
 382          * If txg is -1, report the current value of spa->spa_config_txg.
 383          */
 384         if (txg == -1ULL)
 385                 txg = spa->spa_config_txg;
 386 
 387         /*
 388          * Originally, users had to handle spa namespace collisions by either
 389          * exporting the already imported pool or by specifying a new name for
 390          * the pool with a conflicting name. In the case of root pools from
 391          * virtual guests, neither approach to collision resolution is
 392          * reasonable. This is addressed by extending the new name syntax with
 393          * an option to specify that the new name is temporary. When specified,
 394          * ZFS_IMPORT_TEMP_NAME will be set in spa->spa_import_flags to tell us
 395          * to use the previous name, which we do below.
 396          */
 397         if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
 398                 pool_name = fnvlist_lookup_string(spa->spa_config,
 399                     ZPOOL_CONFIG_POOL_NAME);
 400         } else {
 401                 pool_name = spa_name(spa);
 402         }
 403 
 404         config = fnvlist_alloc();
 405 
 406         fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION, spa_version(spa));
 407         fnvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, pool_name);
 408         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, spa_state(spa));
 409         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg);
 410         fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa));
 411         if (spa->spa_comment != NULL) {
 412                 fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT,
 413                     spa->spa_comment);
 414         }
 415 
 416         hostid = zone_get_hostid(NULL);
 417 
 418         if (hostid != 0) {
 419                 fnvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid);
 420         }
 421         fnvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, utsname.nodename);
 422 
 423         int config_gen_flags = 0;
 424         if (vd != rvd) {
 425                 fnvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
 426                     vd->vdev_top->vdev_guid);
 427                 fnvlist_add_uint64(config, ZPOOL_CONFIG_GUID,