5c27b6
From c15fbdd1e0b82b8ce257685896d0b16358ee45f8 Mon Sep 17 00:00:00 2001
5c27b6
Message-Id: <c15fbdd1e0b82b8ce257685896d0b16358ee45f8@dist-git>
5c27b6
From: Laine Stump <laine@laine.org>
5c27b6
Date: Thu, 13 Apr 2017 14:29:26 -0400
5c27b6
Subject: [PATCH] util: new function virPCIDeviceRebind()
5c27b6
5c27b6
This function unbinds a device from its driver, then immediately
5c27b6
rebinds it to its driver again. The code for this new function is just
5c27b6
the 2nd half of virPCIDeviceBindWithDriverOverride(), so that
5c27b6
function's 2nd half is replaced with a call to virPCIDeviceRebind().
5c27b6
5c27b6
Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
5c27b6
Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4)
5c27b6
5c27b6
(cherry picked from commit 251d179bf2c10c7d7fb594c68f1aac56a9b0d932)
5c27b6
5c27b6
Conflicts:
5c27b6
 src/util/virpci.c - virPCIDeviceBindWithDriverOverride()
5c27b6
   which calls the new function, doesn't exist yet on this branch.
5c27b6
---
5c27b6
 src/libvirt_private.syms |  1 +
5c27b6
 src/util/virpci.c        | 25 +++++++++++++++++++++++++
5c27b6
 src/util/virpci.h        |  1 +
5c27b6
 3 files changed, 27 insertions(+)
5c27b6
5c27b6
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
5c27b6
index b9ea1cfe9..b9e85449b 100644
5c27b6
--- a/src/libvirt_private.syms
5c27b6
+++ b/src/libvirt_private.syms
5c27b6
@@ -2113,6 +2113,7 @@ virPCIDeviceListSteal;
5c27b6
 virPCIDeviceListStealIndex;
5c27b6
 virPCIDeviceNew;
5c27b6
 virPCIDeviceReattach;
5c27b6
+virPCIDeviceRebind;
5c27b6
 virPCIDeviceReset;
5c27b6
 virPCIDeviceSetManaged;
5c27b6
 virPCIDeviceSetRemoveSlot;
5c27b6
diff --git a/src/util/virpci.c b/src/util/virpci.c
5c27b6
index 7d9c81167..de90a82c2 100644
5c27b6
--- a/src/util/virpci.c
5c27b6
+++ b/src/util/virpci.c
5c27b6
@@ -1089,6 +1089,31 @@ virPCIDeviceUnbind(virPCIDevicePtr dev)
5c27b6
     return ret;
5c27b6
 }
5c27b6
 
5c27b6
+
5c27b6
+/**
5c27b6
+ * virPCIDeviceRebind:
5c27b6
+ *  @dev: virPCIDevice object describing the device to rebind
5c27b6
+ *
5c27b6
+ * unbind a device from its driver, then immediately rebind it.
5c27b6
+ *
5c27b6
+ * Returns 0 on success, -1 on failure
5c27b6
+ */
5c27b6
+int virPCIDeviceRebind(virPCIDevicePtr dev)
5c27b6
+{
5c27b6
+    if (virPCIDeviceUnbind(dev) < 0)
5c27b6
+        return -1;
5c27b6
+
5c27b6
+    if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) {
5c27b6
+        virReportSystemError(errno,
5c27b6
+                             _("Failed to trigger a probe for PCI device '%s'"),
5c27b6
+                             dev->name);
5c27b6
+        return -1;
5c27b6
+    }
5c27b6
+
5c27b6
+    return 0;
5c27b6
+}
5c27b6
+
5c27b6
+
5c27b6
 static int
5c27b6
 virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
5c27b6
 {
5c27b6
diff --git a/src/util/virpci.h b/src/util/virpci.h
5c27b6
index c3cb2d679..afd85502c 100644
5c27b6
--- a/src/util/virpci.h
5c27b6
+++ b/src/util/virpci.h
5c27b6
@@ -224,6 +224,7 @@ int virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
5c27b6
                                  char **pfname, int *vf_index);
5c27b6
 
5c27b6
 int virPCIDeviceUnbind(virPCIDevicePtr dev);
5c27b6
+int virPCIDeviceRebind(virPCIDevicePtr dev);
5c27b6
 int virPCIDeviceGetDriverPathAndName(virPCIDevicePtr dev,
5c27b6
                                      char **path,
5c27b6
                                      char **name);
5c27b6
-- 
5c27b6
2.12.2
5c27b6