You need to sign in or sign up before continuing.
提交 a9aafc0a 编写于 作者: C Cédric Bosdonnat

libxl: fix segfault in libxlReconnectDomain

In case of error, libxlReconnectDomain may call
virDomainObjListRemoveLocked. However it has no local reference on
the domain object, leading to segfault. Get a reference to the domain
object at the start of the function and release it at the end to avoid
problems.

This commit also factorizes code between the error and normal ends.
上级 db38eb40
...@@ -373,11 +373,13 @@ libxlReconnectDomain(virDomainObjPtr vm, ...@@ -373,11 +373,13 @@ libxlReconnectDomain(virDomainObjPtr vm,
uint8_t *data = NULL; uint8_t *data = NULL;
virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI; unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI;
int ret = -1;
#ifdef LIBXL_HAVE_PVUSB #ifdef LIBXL_HAVE_PVUSB
hostdev_flags |= VIR_HOSTDEV_SP_USB; hostdev_flags |= VIR_HOSTDEV_SP_USB;
#endif #endif
virObjectRef(vm);
virObjectLock(vm); virObjectLock(vm);
libxl_dominfo_init(&d_info); libxl_dominfo_init(&d_info);
...@@ -385,18 +387,18 @@ libxlReconnectDomain(virDomainObjPtr vm, ...@@ -385,18 +387,18 @@ libxlReconnectDomain(virDomainObjPtr vm,
/* Does domain still exist? */ /* Does domain still exist? */
rc = libxl_domain_info(cfg->ctx, &d_info, vm->def->id); rc = libxl_domain_info(cfg->ctx, &d_info, vm->def->id);
if (rc == ERROR_INVAL) { if (rc == ERROR_INVAL) {
goto out; goto error;
} else if (rc != 0) { } else if (rc != 0) {
VIR_DEBUG("libxl_domain_info failed (code %d), ignoring domain %d", VIR_DEBUG("libxl_domain_info failed (code %d), ignoring domain %d",
rc, vm->def->id); rc, vm->def->id);
goto out; goto error;
} }
/* Is this a domain that was under libvirt control? */ /* Is this a domain that was under libvirt control? */
if (libxl_userdata_retrieve(cfg->ctx, vm->def->id, if (libxl_userdata_retrieve(cfg->ctx, vm->def->id,
"libvirt-xml", &data, &len)) { "libvirt-xml", &data, &len)) {
VIR_DEBUG("libxl_userdata_retrieve failed, ignoring domain %d", vm->def->id); VIR_DEBUG("libxl_userdata_retrieve failed, ignoring domain %d", vm->def->id);
goto out; goto error;
} }
/* Update domid in case it changed (e.g. reboot) while we were gone? */ /* Update domid in case it changed (e.g. reboot) while we were gone? */
...@@ -405,7 +407,7 @@ libxlReconnectDomain(virDomainObjPtr vm, ...@@ -405,7 +407,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
/* Update hostdev state */ /* Update hostdev state */
if (virHostdevUpdateActiveDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, if (virHostdevUpdateActiveDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
vm->def, hostdev_flags) < 0) vm->def, hostdev_flags) < 0)
goto out; goto error;
if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback) if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
driver->inhibitCallback(true, driver->inhibitOpaque); driver->inhibitCallback(true, driver->inhibitOpaque);
...@@ -413,21 +415,25 @@ libxlReconnectDomain(virDomainObjPtr vm, ...@@ -413,21 +415,25 @@ libxlReconnectDomain(virDomainObjPtr vm,
/* Enable domain death events */ /* Enable domain death events */
libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW); libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW);
ret = 0;
cleanup:
libxl_dominfo_dispose(&d_info); libxl_dominfo_dispose(&d_info);
virObjectUnlock(vm); virObjectUnlock(vm);
virObjectUnref(vm);
virObjectUnref(cfg); virObjectUnref(cfg);
return 0; return ret;
out: error:
libxl_dominfo_dispose(&d_info);
libxlDomainCleanup(driver, vm); libxlDomainCleanup(driver, vm);
if (!vm->persistent) if (!vm->persistent) {
virDomainObjListRemoveLocked(driver->domains, vm); virDomainObjListRemoveLocked(driver->domains, vm);
else
virObjectUnlock(vm);
virObjectUnref(cfg);
return -1; /* virDomainObjListRemoveLocked leaves the object unlocked,
* lock it again to factorize more code. */
virObjectLock(vm);
}
goto cleanup;
} }
static void static void
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册