Signed-off-by: Shi Lei <shilei.massclouds(a)gmx.com>
---
src/Makefile.am | 4 +++-
src/util/virkmod.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
src/virt-command.conf | 10 ++++++++++
3 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 src/virt-command.conf
diff --git a/src/Makefile.am b/src/Makefile.am
index 61876cf..e0af476 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -150,7 +150,7 @@ lib_LTLIBRARIES = libvirt.la libvirt-qemu.la libvirt-lxc.la
moddir = $(libdir)/libvirt/connection-driver
confdir = $(sysconfdir)/libvirt
-conf_DATA += libvirt.conf libvirt-admin.conf
+conf_DATA += libvirt.conf libvirt-admin.conf virt-command.conf
augeasdir = $(datadir)/augeas/lenses
@@ -952,6 +952,8 @@ libvirt_nss_la_SOURCES = \
util/virbuffer.h \
util/vircommand.c \
util/vircommand.h \
+ util/virconf.c \
+ util/virconf.h \
util/virerror.c \
util/virerror.h \
util/virfile.c \
diff --git a/src/util/virkmod.c b/src/util/virkmod.c
index 9d0375b..99cce4c 100644
--- a/src/util/virkmod.c
+++ b/src/util/virkmod.c
@@ -24,12 +24,45 @@
#include "virkmod.h"
#include "vircommand.h"
#include "virstring.h"
+#include "virthread.h"
+#include "virconf.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+/*
+ * Kernel module load timeout (milliseconds)
+ * >0, the number of milliseconds before loading expires
+ * =0, waiting indefinitely
+ */
+static int virKModLoadTimeout = 3*1000;
+
+static int virKModOnceInit(void)
+{
+ int timeout = 0;
+ virConfPtr conf = NULL;
+ if (virConfLoadConfig(&conf, "virt-command.conf") < 0)
+ goto cleanup;
+ if (virConfGetValueInt(conf, "kmod_load_timeout", &timeout) <= 0)
+ goto cleanup;
+
+ if (timeout >= 0)
+ virKModLoadTimeout = timeout;
+
+ cleanup:
+ virConfFree(conf);
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virKMod)
static int
doModprobe(const char *opts, const char *module, char **outbuf, char **errbuf)
{
VIR_AUTOPTR(virCommand) cmd = NULL;
+ if (virKModInitialize() < 0)
+ return -1;
+
cmd = virCommandNew(MODPROBE);
if (opts)
virCommandAddArg(cmd, opts);
@@ -40,8 +73,16 @@ doModprobe(const char *opts, const char *module, char **outbuf, char
**errbuf)
if (errbuf)
virCommandSetErrorBuffer(cmd, errbuf);
- if (virCommandRun(cmd, NULL) < 0)
+ if (virKModLoadTimeout > 0)
+ virCommandSetTimeout(cmd, virKModLoadTimeout);
+
+ if (virCommandRun(cmd, NULL) < 0) {
+ if (virCommandGetErr(cmd) == ETIME)
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("%s loading timeout. Check kmod_load_timeout from
virt-command.conf"),
+ module);
return -1;
+ }
return 0;
}
diff --git a/src/virt-command.conf b/src/virt-command.conf
new file mode 100644
index 0000000..d88d24a
--- /dev/null
+++ b/src/virt-command.conf
@@ -0,0 +1,10 @@
+#
+# This can be used to set timeout for kernel module loading internally
+#
+# >0, the number of milliseconds for loading timeout
+# =0, waiting indefinitely until loading finished, i.e. no timeout.
+#
+# The default 3 seconds is adequate since most kernel module loading
+# with microsecond latency or millisecond latency
+#
+# kmod_load_timeout = 3000
--
2.7.4