summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gerdts <mike.gerdts@joyent.com>2018-12-03 15:19:44 +0000
committerMike Gerdts <mike.gerdts@joyent.com>2018-12-05 19:34:57 +0000
commita454ac291ee3d52860e81c8b77efa408915b3aa3 (patch)
treefd22fdc255f9214627976557f1d65cd1d9bfa3c0
parent5b87e03ada692fb585a6a15a0cccfff5eb39e8ea (diff)
downloadillumos-joyent-a454ac291ee3d52860e81c8b77efa408915b3aa3.tar.gz
OS-7410 vmm_zsd assert tripped on zone shutdown
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Reviewed by: Mike Zeller <mike.zeller@joyent.com> Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm_zsd.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/io/vmm/vmm_zsd.c b/usr/src/uts/i86pc/io/vmm/vmm_zsd.c
index 8313dfbb50..0271cc339e 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm_zsd.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm_zsd.c
@@ -105,6 +105,7 @@ static void *
vmm_zsd_create(zoneid_t zid)
{
vmm_zsd_t *zsd;
+ zone_t *zone;
zsd = kmem_zalloc(sizeof (*zsd), KM_SLEEP);
@@ -114,7 +115,20 @@ vmm_zsd_create(zoneid_t zid)
zsd->vz_zoneid = zid;
mutex_init(&zsd->vz_lock, NULL, MUTEX_DEFAULT, NULL);
- zsd->vz_active = B_TRUE;
+
+ /*
+ * If the vmm module is loaded while this zone is in the midst of
+ * shutting down, vmm_zsd_destroy() may be called without
+ * vmm_zsd_shutdown() ever being called. If it is shutting down, there
+ * is no sense in letting any in-flight VM creation succeed so set
+ * vz_active accordingly.
+ *
+ * zone_find_by_id_nolock() is used rather than zone_find_by_id()
+ * so that the zone is returned regardless of state.
+ */
+ zone = zone_find_by_id_nolock(zid);
+ VERIFY(zone != NULL);
+ zsd->vz_active = zone_status_get(zone) < ZONE_IS_SHUTTING_DOWN;
mutex_enter(&vmm_zsd_lock);
list_insert_tail(&vmm_zsd_list, zsd);
@@ -134,7 +148,11 @@ vmm_zsd_shutdown(zoneid_t zid, void *data)
vmm_softc_t *sc;
mutex_enter(&zsd->vz_lock);
- ASSERT(zsd->vz_active);
+
+ /*
+ * This may already be B_FALSE. See comment in vmm_zsd_create(). If it
+ * is already B_FALSE we will take a quick trip through the empty list.
+ */
zsd->vz_active = B_FALSE;
for (sc = list_head(&zsd->vz_vmms); sc != NULL;