[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH] fix the failure of nodedev-reattach caused by the variables from nodedev-attach



At 2011-7-1 18:24, Guannan Ren write:
the "virsh nodedev-reattch" command could return successfully, but the pci device is still
bound to pci-stub driver. The reason is noddev-reattach trys to use the variables set by
nodedev-dettach commands. Becuase these variables is not persistent, this is not we expected.
the patch try to fix it.

I do not agree with this patch. You should read this mail:
https://www.redhat.com/archives/libvir-list/2011-April/msg00315.html

This patch will cause regression about hotpluging host pci device.

I think the problem is that: the init value of these variables is wrong.
We can fix this bug by modifing pciGetDevice() or its caller.


---
  src/util/pci.c |   74 +++++++++++++++++++------------------------------------
  1 files changed, 26 insertions(+), 48 deletions(-)

diff --git a/src/util/pci.c b/src/util/pci.c
index 46a3a83..d345c3e 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -67,9 +67,6 @@ struct _pciDevice {
      unsigned      managed : 1;

      /* used by reattach function */
-    unsigned      unbind_from_stub : 1;
-    unsigned      remove_slot : 1;
-    unsigned      reprobe : 1;
  };

  struct _pciDeviceList {
@@ -882,14 +879,23 @@ pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
      if (pciDriverDir(&drvdir, driver)<  0)
          goto cleanup;

-    if (!dev->unbind_from_stub)
-        goto remove_slot;
-
-    /* If the device is bound to stub, unbind it.
-     */
      if (pciDeviceFile(&path, dev->name, "driver")<  0)
          goto cleanup;

+    /* If the device is bound to a driver instead of pci-stub, do nothing.
+     */
+    if (virFileExists(path)&&  ! virFileLinkPointsTo(path, drvdir)){
+        result = 0;
+        goto cleanup;
+    }
+
+    /* If the device is not bound to any driver, reprobe it.
+     */
+    if (!virFileExists(path))
+        goto reprobe;
+
+    /* If the device is bound to stub, unbind it.
+     */
      if (virFileExists(drvdir)&&  virFileLinkPointsTo(path, drvdir)) {
          if (pciDriverFile(&path, driver, "unbind")<  0) {
              goto cleanup;
@@ -902,11 +908,6 @@ pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
              goto cleanup;
          }
      }
-    dev->unbind_from_stub = 0;
-
-remove_slot:
-    if (!dev->remove_slot)
-        goto reprobe;

      /* Xen's pciback.ko wants you to use remove_slot on the specific device */
      if (pciDriverFile(&path, driver, "remove_slot")<  0) {
@@ -919,14 +920,8 @@ remove_slot:
                               dev->name, driver);
          goto cleanup;
      }
-    dev->remove_slot = 0;

  reprobe:
-    if (!dev->reprobe) {
-        result = 0;
-        goto cleanup;
-    }
-
      /* Trigger a re-probe of the device is not in the stub's dynamic
       * ID table. If the stub is available, but 'remove_id' isn't
       * available, then re-probing would just cause the device to be
@@ -935,6 +930,12 @@ reprobe:
      if (pciDriverFile(&path, driver, "remove_id")<  0) {
          goto cleanup;
      }
+
+    /* If the device is still in stub's dynamic ID table,remove it,
+     * otherwise, ignore the error.
+     */
+    if (virFileExists(path)&&  virFileWriteStr(path, dev->name, 0)<  0){
+    }

      if (!virFileExists(drvdir) || virFileExists(path)) {
          if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0)<  0) {
@@ -948,11 +949,6 @@ reprobe:
      result = 0;

  cleanup:
-    /* do not do it again */
-    dev->unbind_from_stub = 0;
-    dev->remove_slot = 0;
-    dev->reprobe = 0;
-
      VIR_FREE(drvdir);
      VIR_FREE(path);

@@ -966,7 +962,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
      int result = -1;
      char *drvdir = NULL;
      char *path = NULL;
-    int reprobe = 0;

      /* check whether the device is already bound to a driver */
      if (pciDriverDir(&drvdir, driver)<  0 ||
@@ -980,7 +975,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
              result = 0;
              goto cleanup;
          }
-        reprobe = 1;
      }

      /* Add the PCI device ID to the stub's dynamic ID table;
@@ -1011,8 +1005,7 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
      }

      if (virFileLinkPointsTo(path, drvdir)) {
-        dev->unbind_from_stub = 1;
-        dev->remove_slot = 1;
+        result = 0;
          goto remove_id;
      }

@@ -1022,7 +1015,7 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
       * your root filesystem.
       */
      if (pciDeviceFile(&path, dev->name, "driver/unbind")<  0) {
-        goto cleanup;
+        goto remove_id;
      }

      if (virFileExists(path)) {
@@ -1030,9 +1023,8 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
              virReportSystemError(errno,
                                   _("Failed to unbind PCI device '%s'"),
                                   dev->name);
-            goto cleanup;
+            goto remove_id;
          }
-        dev->reprobe = reprobe;
      }

      /* If the device isn't already bound to pci-stub, try binding it now.
@@ -1054,7 +1046,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
                                   dev->name, driver);
              goto remove_id;
          }
-        dev->remove_slot = 1;

          if (pciDriverFile(&path, driver, "bind")<  0) {
              goto remove_id;
@@ -1066,20 +1057,15 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
                                   dev->name, driver);
              goto remove_id;
          }
-        dev->unbind_from_stub = 1;
      }

+    result = 0;
  remove_id:
      /* If 'remove_id' exists, remove the device id from pci-stub's dynamic
       * ID table so that 'drivers_probe' works below.
       */
      if (pciDriverFile(&path, driver, "remove_id")<  0) {
-        /* We do not remove PCI ID from pci-stub, and we cannot reprobe it */
-        if (dev->reprobe) {
-            VIR_WARN("Could not remove PCI ID '%s' from %s, and the device "
-                     "cannot be probed again.", dev->id, driver);
-        }
-        dev->reprobe = 0;
+        result = -1;
          goto cleanup;
      }

@@ -1087,18 +1073,10 @@ remove_id:
          virReportSystemError(errno,
                               _("Failed to remove PCI ID '%s' from %s"),
                               dev->id, driver);
-
-        /* remove PCI ID from pci-stub failed, and we cannot reprobe it */
-        if (dev->reprobe) {
-            VIR_WARN("Failed to remove PCI ID '%s' from %s, and the device "
-                     "cannot be probed again.", dev->id, driver);
-        }
-        dev->reprobe = 0;
+        result = -1;
          goto cleanup;
      }

-    result = 0;
-
  cleanup:
      VIR_FREE(drvdir);
      VIR_FREE(path);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]