tests: fix segfault in objecteventtest

Test 12 from objecteventtest (createXML add event) segaults on FreeBSD
with bus error.

At some point it calls testNodeDeviceDestroy() from the test driver. And
it fails when it tries to unlock the device in the "out:" label of this
function.

Unlocking fails because the previous step was a call to
virNodeDeviceObjRemove from conf/node_device_conf.c. This function
removes the given device from the device list and cleans up the object,
including destroying of its mutex. However, it does not nullify the pointer
that was given to it.

As a result, we end up in testNodeDeviceDestroy() here:

 out:
    if (obj)
        virNodeDeviceObjUnlock(obj);

And instead of skipping this, we try to do Unlock and fail because of
malformed mutex.

Change virNodeDeviceObjRemove to use double pointer and set pointer to
NULL.
This commit is contained in:
Roman Bogorodskiy 2016-08-24 13:37:27 +03:00
parent 25ee22bdbc
commit 6114807477
5 changed files with 12 additions and 11 deletions

View File

@ -207,22 +207,23 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
}
void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
virNodeDeviceObjPtr dev)
virNodeDeviceObjPtr *dev)
{
size_t i;
virNodeDeviceObjUnlock(dev);
virNodeDeviceObjUnlock(*dev);
for (i = 0; i < devs->count; i++) {
virNodeDeviceObjLock(dev);
if (devs->objs[i] == dev) {
virNodeDeviceObjUnlock(dev);
virNodeDeviceObjLock(*dev);
if (devs->objs[i] == *dev) {
virNodeDeviceObjUnlock(*dev);
virNodeDeviceObjFree(devs->objs[i]);
*dev = NULL;
VIR_DELETE_ELEMENT(devs->objs, i, devs->count);
break;
}
virNodeDeviceObjUnlock(dev);
virNodeDeviceObjUnlock(*dev);
}
}

View File

@ -249,7 +249,7 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
virNodeDeviceDefPtr def);
void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
virNodeDeviceObjPtr dev);
virNodeDeviceObjPtr *dev);
char *virNodeDeviceDefFormat(const virNodeDeviceDef *def);

View File

@ -530,7 +530,7 @@ dev_refresh(const char *udi)
/* Simply "rediscover" device -- incrementally handling changes
* to sub-capabilities (like net.80203) is nasty ... so avoid it.
*/
virNodeDeviceObjRemove(&driver->devs, dev);
virNodeDeviceObjRemove(&driver->devs, &dev);
} else {
VIR_DEBUG("no device named %s", name);
}
@ -560,7 +560,7 @@ device_removed(LibHalContext *ctx ATTRIBUTE_UNUSED,
dev = virNodeDeviceFindByName(&driver->devs, name);
VIR_DEBUG("%s", name);
if (dev)
virNodeDeviceObjRemove(&driver->devs, dev);
virNodeDeviceObjRemove(&driver->devs, &dev);
else
VIR_DEBUG("no device named %s", name);
nodeDeviceUnlock();

View File

@ -1044,7 +1044,7 @@ static int udevRemoveOneDevice(struct udev_device *device)
VIR_DEBUG("Removing device '%s' with sysfs path '%s'",
dev->def->name, name);
virNodeDeviceObjRemove(&driver->devs, dev);
virNodeDeviceObjRemove(&driver->devs, &dev);
ret = 0;
cleanup:

View File

@ -5534,7 +5534,7 @@ testNodeDeviceDestroy(virNodeDevicePtr dev)
0);
virNodeDeviceObjLock(obj);
virNodeDeviceObjRemove(&driver->devs, obj);
virNodeDeviceObjRemove(&driver->devs, &obj);
out:
if (obj)