]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
node_device_udev: Serialize access to pci_get_strings)_
authorwangjian <wangjian161@huawei.com>
Fri, 26 Mar 2021 03:21:16 +0000 (11:21 +0800)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 26 Mar 2021 10:06:21 +0000 (11:06 +0100)
Since the functions provided by libpciaccess are not thread-safe,
when the udev-event and nodedev-init threads of libvirt call the
pci_get_strings function provided by libpaciaccess at the same
time the following can happen:

nodedev-init thread:
nodeStateInitializeEnumerate ->
  udevEnumerateDevices->
    udevProcessDeviceListEntry ->
      udevAddOneDevice ->
        udevGetDeviceDetails->
          udevProcessPCI ->
            udevTranslatePCIIds ->
              pci_get_strings -> (libpciaccess)
                find_device_name ->
                  populate_vendor ->
                    d = realloc( vend->devices, (vend->num_devices + 1), * sizeof( struct pci_device_leaf ) );
                    vend->num_devices++;

udev-event thread:
udevEventHandleThread ->
  udevHandleOneDevice ->
    udevAddOneDevice->
      udevGetDeviceDetails->
        udevProcessPCI ->
          udevTranslatePCIIds ->
            pci_get_strings -> (libpciaccess)
              find_device_name ->
                populate_vendor ->
                  d = realloc( vend->devices, (vend->num_devices + 1), * sizeof( struct pci_device_leaf ) );
                  vend->num_devices++;

Signed-off-by: WangJian <wangjian161@huawei.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/node_device/node_device_udev.c

index 3f288589db3a4a23761f14a46688995fb2859732..3daa5c90adda5301cf8825de39064689e550675c 100644 (file)
@@ -331,6 +331,7 @@ udevGenerateDeviceName(struct udev_device *device,
     return 0;
 }
 
+static virMutex pciaccessMutex = VIR_MUTEX_INITIALIZER;
 
 static int
 udevTranslatePCIIds(unsigned int vendor,
@@ -349,12 +350,14 @@ udevTranslatePCIIds(unsigned int vendor,
     m.device_class_mask = 0;
     m.match_data = 0;
 
-    /* pci_get_strings returns void */
+    /* pci_get_strings returns void and unfortunately is not thread safe. */
+    virMutexLock(&pciaccessMutex);
     pci_get_strings(&m,
                     &device_name,
                     &vendor_name,
                     NULL,
                     NULL);
+    virMutexUnlock(&pciaccessMutex);
 
     *vendor_string = g_strdup(vendor_name);
     *product_string = g_strdup(device_name);