aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorRichard Elling <[email protected]>2019-05-23 14:28:53 -0700
committerBrian Behlendorf <[email protected]>2019-05-23 14:28:53 -0700
commit78fac8d925fdd64584292fbda4ed9e3e2bbaae66 (patch)
tree4a98ae5d6271b8287f7030eb10a111ddf77b4e64 /module
parentbff2361aeb32a83c26e2992733864ca99cced257 (diff)
Fix kstat state update during pool transition
When reading kstats, the health (aka state) of the pool is stored into /proc/spl/kstat/zfs/POOLNAME/state via spa_state_to_name(). However, during import/export there is a case where the spa exists, but the root vdev does not exist. This fix checks that case and sets the state to "TRANSITIONING" Unfortunately, it is not easy to reproduce a test for this. It was detected randomly during ZTS runs while kstats were also being sampled regularly. After this change, further testing did not trip on the case and the TRANSITIONING state was collected at least once by the kstats. For posterity, the backtrace prior to this fix is: [Mon May 13 17:21:00 2019] RIP: 0010:spa_state_to_name+0x10/0xb0 [zfs] ... Mon May 13 17:21:00 2019] Call Trace: [Mon May 13 17:21:00 2019] spa_state_data+0x1a/0x40 [zfs] [Mon May 13 17:21:00 2019] kstat_seq_show+0x117/0x440 [spl] [Mon May 13 17:21:00 2019] seq_read+0xe5/0x430 [Mon May 13 17:21:00 2019] proc_reg_read+0x45/0x70 [Mon May 13 17:21:00 2019] __vfs_read+0x1b/0x40 [Mon May 13 17:21:00 2019] vfs_read+0x8e/0x130 [Mon May 13 17:21:00 2019] SyS_read+0x55/0xc0 [Mon May 13 17:21:00 2019] ? SyS_fcntl+0x5d/0xb0 [Mon May 13 17:21:00 2019] do_syscall_64+0x73/0x130 [Mon May 13 17:21:00 2019] entry_SYSCALL_64_after_hwframe+0x3d/0xa2 Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Tony Hutter <[email protected]> Signed-off-by: Richard Elling <[email protected]> Closes #8746
Diffstat (limited to 'module')
-rw-r--r--module/zfs/spa_misc.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index e2d1ae3fc..dddbe9cfa 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -2582,8 +2582,18 @@ spa_set_missing_tvds(spa_t *spa, uint64_t missing)
const char *
spa_state_to_name(spa_t *spa)
{
- vdev_state_t state = spa->spa_root_vdev->vdev_state;
- vdev_aux_t aux = spa->spa_root_vdev->vdev_stat.vs_aux;
+ ASSERT3P(spa, !=, NULL);
+
+ /*
+ * it is possible for the spa to exist, without root vdev
+ * as the spa transitions during import/export
+ */
+ vdev_t *rvd = spa->spa_root_vdev;
+ if (rvd == NULL) {
+ return ("TRANSITIONING");
+ }
+ vdev_state_t state = rvd->vdev_state;
+ vdev_aux_t aux = rvd->vdev_stat.vs_aux;
if (spa_suspended(spa) &&
(spa_get_failmode(spa) != ZIO_FAILURE_MODE_CONTINUE))