]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virStoragePoolObjListForEach: Grab a reference for pool object
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 24 May 2019 14:35:38 +0000 (16:35 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 22 Aug 2019 15:09:05 +0000 (17:09 +0200)
Turns out there's one callback that might remove a storage pool
during its run: storagePoolUpdateAllState() call
storagePoolUpdateStateCallback() which may call
virStoragePoolUpdateInactive() which in turn may call
virStoragePoolObjRemove(). Problem is that the
UpdateStateCallback() sees a storage pool object with just two
references: one for each hash table holding the object. If the
function ends up calling ObjRemove() then upon removing the
object from hash tables those references are gone and thus any
subsequent call touching the object is invalid.

The solution to this problem is to grab reference for the object
we are running iterator with.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/conf/virstorageobj.c

index 0b83c2d2deb909f6aeda0832abd6a82c05379805..5e64467515edbe23a8bdba44b5e69415096a9f82 100644 (file)
@@ -411,9 +411,13 @@ virStoragePoolObjListForEachCb(void *payload,
     virStoragePoolObjPtr obj = payload;
     struct _virStoragePoolObjListForEachData *data = opaque;
 
+    /* Grab a reference so that we don't rely only on references grabbed by
+     * hash table earlier. Remember, an iterator can remove object from the
+     * hash table. */
+    virObjectRef(obj);
     virObjectLock(obj);
     data->iter(obj, data->opaque);
-    virObjectUnlock(obj);
+    virStoragePoolObjEndAPI(&obj);
 
     return 0;
 }