]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa.c
Report pool suspended due to MMP
[mirror_zfs.git] / module / zfs / spa.c
index f576293ebf3c3d21493f2c5b79ff0bd3ffdbd4e4..561f4d04bfc9c0a17354880e419157afb06126ed 100644 (file)
@@ -2341,7 +2341,8 @@ vdev_count_verify_zaps(vdev_t *vd)
  * Determine whether the activity check is required.
  */
 static boolean_t
-spa_activity_check_required(spa_t *spa, uberblock_t *ub, nvlist_t *config)
+spa_activity_check_required(spa_t *spa, uberblock_t *ub, nvlist_t *label,
+    nvlist_t *config)
 {
        uint64_t state = 0;
        uint64_t hostid = 0;
@@ -2358,7 +2359,6 @@ spa_activity_check_required(spa_t *spa, uberblock_t *ub, nvlist_t *config)
        }
 
        (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state);
-       (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
 
        /*
         * Disable the MMP activity check - This is used by zdb which
@@ -2384,8 +2384,12 @@ spa_activity_check_required(spa_t *spa, uberblock_t *ub, nvlist_t *config)
 
        /*
         * Allow the activity check to be skipped when importing the pool
-        * on the same host which last imported it.
+        * on the same host which last imported it.  Since the hostid from
+        * configuration may be stale use the one read from the label.
         */
+       if (nvlist_exists(label, ZPOOL_CONFIG_HOSTID))
+               hostid = fnvlist_lookup_uint64(label, ZPOOL_CONFIG_HOSTID);
+
        if (hostid == spa_get_hostid())
                return (B_FALSE);
 
@@ -2651,14 +2655,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
         * pool is truly inactive and can be safely imported.  Prevent
         * hosts which don't have a hostid set from importing the pool.
         */
-       activity_check = spa_activity_check_required(spa, ub, config);
+       activity_check = spa_activity_check_required(spa, ub, label, config);
        if (activity_check) {
-               error = spa_activity_check(spa, ub, config);
-               if (error) {
-                       nvlist_free(label);
-                       return (error);
-               }
-
                if (ub->ub_mmp_magic == MMP_MAGIC && ub->ub_mmp_delay &&
                    spa_get_hostid() == 0) {
                        nvlist_free(label);
@@ -2667,6 +2665,12 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                        return (spa_vdev_err(rvd, VDEV_AUX_ACTIVE, EREMOTEIO));
                }
 
+               error = spa_activity_check(spa, ub, config);
+               if (error) {
+                       nvlist_free(label);
+                       return (error);
+               }
+
                fnvlist_add_uint64(spa->spa_load_info,
                    ZPOOL_CONFIG_MMP_STATE, MMP_STATE_INACTIVE);
                fnvlist_add_uint64(spa->spa_load_info,
@@ -3257,7 +3261,7 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
                 * Log the fact that we booted up (so that we can detect if
                 * we rebooted in the middle of an operation).
                 */
-               spa_history_log_version(spa, "open");
+               spa_history_log_version(spa, "open", NULL);
 
                /*
                 * Delete any inconsistent datasets.
@@ -3774,10 +3778,14 @@ spa_get_stats(const char *name, nvlist_t **config,
                            ZPOOL_CONFIG_ERRCOUNT,
                            spa_get_errlog_size(spa)) == 0);
 
-                       if (spa_suspended(spa))
+                       if (spa_suspended(spa)) {
                                VERIFY(nvlist_add_uint64(*config,
                                    ZPOOL_CONFIG_SUSPENDED,
                                    spa->spa_failmode) == 0);
+                               VERIFY(nvlist_add_uint64(*config,
+                                   ZPOOL_CONFIG_SUSPENDED_REASON,
+                                   spa->spa_suspended) == 0);
+                       }
 
                        spa_add_spares(spa, *config);
                        spa_add_l2cache(spa, *config);
@@ -4139,6 +4147,15 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
 
        tx = dmu_tx_create_assigned(dp, txg);
 
+       /*
+        * Create the pool's history object.
+        */
+       if (version >= SPA_VERSION_ZPOOL_HISTORY && !spa->spa_history)
+               spa_history_create_obj(spa, tx);
+
+       spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_CREATE);
+       spa_history_log_version(spa, "create", tx);
+
        /*
         * Create the pool config object.
         */
@@ -4187,12 +4204,6 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        VERIFY3U(0, ==, bpobj_open(&spa->spa_deferred_bpobj,
            spa->spa_meta_objset, obj));
 
-       /*
-        * Create the pool's history object.
-        */
-       if (version >= SPA_VERSION_ZPOOL_HISTORY)
-               spa_history_create_obj(spa, tx);
-
        /*
         * Generate some random noise for salted checksums to operate on.
         */
@@ -4226,9 +4237,6 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
        txg_wait_synced(spa->spa_dsl_pool, txg);
 
        spa_config_sync(spa, B_FALSE, B_TRUE);
-       spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_CREATE);
-
-       spa_history_log_version(spa, "create");
 
        /*
         * Don't count references from objsets that are already closed
@@ -4415,7 +4423,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
         */
        spa_async_request(spa, SPA_ASYNC_AUTOEXPAND);
 
-       spa_history_log_version(spa, "import");
+       spa_history_log_version(spa, "import", NULL);
 
        spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
 
@@ -4618,7 +4626,10 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
        }
 
 export_spa:
-       spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_DESTROY);
+       if (new_state == POOL_STATE_DESTROYED)
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_DESTROY);
+       else if (new_state == POOL_STATE_EXPORTED)
+               spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_EXPORT);
 
        if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
                spa_unload(spa);
@@ -6962,7 +6973,7 @@ spa_sync(spa_t *spa, uint64_t txg)
 
                if (error == 0)
                        break;
-               zio_suspend(spa, NULL);
+               zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR);
                zio_resume_wait(spa);
        }
        dmu_tx_commit(tx);