Bug 220916 - kernel panic when reboot -r to zfs root because ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); is triggered in spa_remove()
Summary: kernel panic when reboot -r to zfs root because ASSERT(spa->spa_state == POOL...
Status: Closed DUPLICATE of bug 210721
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: arm64 Any
: --- Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-22 01:17 UTC by David NewHamlet
Modified: 2017-07-22 08:17 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David NewHamlet 2017-07-22 01:17:04 UTC
git 66cab836b0e5b1e7ba73227c4ddf58a8cb7c668a

When test reboot -r (switch root filesystem to new one from userspace) with zfs root, ASSERT is triggered in spa_remove().

Reproduce:

1. boot into rescue shell(or normal system).
2. import/create other zfs pool(for example pi3tank), a spa registered.
3. create/refresh dataset for new root filesystem: pi3tank/bsdrootfs.
4. zpool export pi3tank
5. kenv vfs.root.mountfrom=zfs:pi3tank/bsdrootfs && reboot -r
6. ASSERT panic ...

Analyse:

In spa_import_rootpool (sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c: 4062), spa_unload and spa_deactivate should be called for a zfs pool with spa->spa_state != POOL_STATE_UNINITIALIZED although this zfs pool has been exported.

Fix(works for me):

--- cut here ---
--- /home/david/sandspace/private-freebsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c.orig
+++ /home/david/sandspace/private-freebsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -4079,6 +4079,10 @@
 		 * Remove the existing root pool from the namespace so that we
 		 * can replace it with the correct config we just read in.
 		 */
+		if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
+			spa_unload(spa);
+			spa_deactivate(spa);
+		}
 		spa_remove(spa);
 	}
 
@@ -4294,6 +4298,10 @@
 			 * that we can replace it with the correct config
 			 * we just read in.
 			 */
+			if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
+				spa_unload(spa);
+				spa_deactivate(spa);
+			}
 			spa_remove(spa);
 		}
 		spa = spa_add(pname, config, NULL);
--- cut here ---

ASSERT panic information:

Trying to mount root from zfs:pi3tank/bsdrootfs []...
panic: solaris assert: spa->spa_state == POOL_STATE_UNINITIALIZED, file: /home/david/sandspace/private-freebsd/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c, line: 805
cpuid = 2
time = 318
KDB: stack backtrace:
db_trace_self() at db_trace_self_wrapper+0x28
	 pc = 0xffff000000747b80  lr = 0xffff00000018ce8c
	 sp = 0xffff000078bbcd50  fp = 0xffff000078bbcf60

db_trace_self_wrapper() at vpanic+0x184
	 pc = 0xffff00000018ce8c  lr = 0xffff0000004373a8
	 sp = 0xffff000078bbcf70  fp = 0xffff000078bbcff0

vpanic() at panic+0x48
	 pc = 0xffff0000004373a8  lr = 0xffff000000437434
	 sp = 0xffff000078bbd000  fp = 0xffff000078bbd080

panic() at assfail+0x28
	 pc = 0xffff000000437434  lr = 0xffff000000043378
	 sp = 0xffff000078bbd090  fp = 0xffff000078bbd090

assfail() at spa_remove+0x6c
	 pc = 0xffff000000043378  lr = 0xffff0000000d0a80
	 sp = 0xffff000078bbd0a0  fp = 0xffff000078bbd0d0

spa_remove() at spa_import_rootpool+0x658
	 pc = 0xffff0000000d0a80  lr = 0xffff0000000c46d8
	 sp = 0xffff000078bbd0e0  fp = 0xffff000078bbd180

spa_import_rootpool() at zfs_mount+0x384
	 pc = 0xffff0000000c46d8  lr = 0xffff000000112bec
	 sp = 0xffff000078bbd190  fp = 0xffff000078bbd340

zfs_mount() at vfs_donmount+0xcfc
	 pc = 0xffff000000112bec  lr = 0xffff0000004ec35c
	 sp = 0xffff000078bbd350  fp = 0xffff000078bbd590

vfs_donmount() at kernel_mount+0x58
	 pc = 0xffff0000004ec35c  lr = 0xffff0000004eef7c
	 sp = 0xffff000078bbd5a0  fp = 0xffff000078bbd5f0

kernel_mount() at parse_mount+0x39c
	 pc = 0xffff0000004eef7c  lr = 0xffff0000004f1578
	 sp = 0xffff000078bbd600  fp = 0xffff000078bbd750

parse_mount() at vfs_mountroot+0x574
	 pc = 0xffff0000004f1578  lr = 0xffff0000004ef93c
	 sp = 0xffff000078bbd760  fp = 0xffff000078bbd920

vfs_mountroot() at sys_reboot+0x2bc
	 pc = 0xffff0000004ef93c  lr = 0xffff0000004368dc
	 sp = 0xffff000078bbd930  fp = 0xffff000078bbd9a0

sys_reboot() at do_el0_sync+0x884
	 pc = 0xffff0000004368dc  lr = 0xffff0000007611bc
	 sp = 0xffff000078bbd9b0  fp = 0xffff000078bbda70

do_el0_sync() at handle_el0_sync+0x74
	 pc = 0xffff0000007611bc  lr = 0xffff0000007499f4
	 sp = 0xffff000078bbda80  fp = 0xffff000078bbdb90

handle_el0_sync() at 0x30d9c
	 pc = 0xffff0000007499f4  lr = 0x0000000000030d9c
	 sp = 0xffff000078bbdba0  fp = 0x0000ffffffffe7f0

KDB: enter: panic
[ thread pid 1 tid 100002 ]
Stopped at      kdb_enter+0x40: undefined       d4200000
db>
Comment 1 Andriy Gapon freebsd_committer freebsd_triage 2017-07-22 08:17:17 UTC

*** This bug has been marked as a duplicate of bug 210721 ***