https://bugzilla.redhat.com/show_bug.cgi?id=1045124
When loading modules, libvirt does not honor the modprobe blacklist.
By adding a "-b" to the modprobe command libvirt will fail to load a
module if it's on the blacklist
Check if the failure to load a driver was due to it being on the blacklist
using the output of a "modprobe -c" searching for "blacklist
<driver_Name>"
where driver_Name is possibly a modified string of the input driver changing
all '-' into '_' since that's what modprobe does.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/util/virpci.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 6 deletions(-)
diff --git a/src/util/virpci.c b/src/util/virpci.c
index e2d222e..18b85f2 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -979,6 +979,10 @@ virPCIProbeStubDriver(const char *driver)
{
char *drvpath = NULL;
bool probed = false;
+ size_t i;
+ char *drvblklst = NULL;
+ char *outbuf = NULL;
+ virCommandPtr cmd = NULL;
recheck:
if (virPCIDriverDir(&drvpath, driver) == 0 && virFileExists(drvpath)) {
@@ -990,18 +994,49 @@ recheck:
VIR_FREE(drvpath);
if (!probed) {
- const char *const probecmd[] = { MODPROBE, driver, NULL };
+ cmd = virCommandNewArgList(MODPROBE, "-b", driver, NULL);
probed = true;
- if (virRun(probecmd, NULL) < 0) {
+ if (virCommandRun(cmd, NULL) < 0) {
char ebuf[1024];
VIR_WARN("failed to load driver %s: %s", driver,
virStrerror(errno, ebuf, sizeof(ebuf)));
- return -1;
+ goto cleanup;
}
+ virCommandFree(cmd);
+ cmd = NULL;
goto recheck;
}
+ /* All error path code - purpose is to determine whether the failure
+ * occurs because device is on blacklist in order to add an error
+ * message to help detect why load failed
+ */
+ if (virAsprintfQuiet(&drvblklst, "blacklist %s", driver) < 0)
+ goto cleanup;
+
+ /* Although driver may have dash, 'modprobe -c' adjusts to use underscore
*/
+ for (i = 0; i < drvblklst[i]; i++)
+ if (drvblklst[i] == '-')
+ drvblklst[i] = '_';
+
+ cmd = virCommandNewArgList(MODPROBE, "-c", NULL);
+ virCommandSetOutputBuffer(cmd, &outbuf);
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ /* Find driver on blacklist? */
+ if (strstr(outbuf, drvblklst)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to load PCI stub module %s: "
+ "administratively prohibited"),
+ driver);
+ }
+
+cleanup:
+ virCommandFree(cmd);
+ VIR_FREE(drvblklst);
+ VIR_FREE(outbuf);
return -1;
}
This is getting complex enough that I think we ought introduce
a src/util/virkmod.{c,h} and have some helper APIs in there
for loading and unload modules. eg virKModLoad, virKModUnload
etc
Regards,
Daniel
--
|: