This patch is purely re-factoring without any functional changes
to make way for the next patch.
The main thing achieved by the refactoring is that we now have
easier access to the parenthesised string that KVM folks seem
to delight in changing.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
---
src/qemu_conf.c | 92 +++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 72 insertions(+), 20 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 2c1eefc..f6a8390 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -412,6 +412,73 @@ virCapsPtr qemudCapsInit(void) {
return NULL;
}
+/* We parse the output of 'qemu -help' to get the QEMU
+ * version number. The first bit is easy, just parse
+ * 'QEMU PC emulator version x.y.z'.
+ *
+ * With qemu-kvm, however, that is followed by a kvm-XX
+ * string in parenthesis.
+ */
+#define QEMU_VERSION_STR "QEMU PC emulator version "
+#define KVM_VER_PREFIX " (kvm-"
+
+static int qemudParseVersionStr(const char *str,
+ unsigned int *version,
+ unsigned int *kvm_version)
+{
+ unsigned major, minor, micro;
+ const char *p = str;
+
+ *version = *kvm_version = 0;
+
+ if (!STRPREFIX(p, QEMU_VERSION_STR))
+ goto fail;
+
+ p += strlen(QEMU_VERSION_STR);
+
+ major = virParseNumber(&p);
+ if (major == -1 || *p != '.')
+ goto fail;
+
+ ++p;
+
+ minor = virParseNumber(&p);
+ if (major == -1 || *p != '.')
+ goto fail;
+
+ ++p;
+
+ micro = virParseNumber(&p);
+ if (major == -1)
+ goto fail;
+
+ if (STRPREFIX(p, KVM_VER_PREFIX)) {
+ int ret;
+
+ p += strlen(KVM_VER_PREFIX);
+
+ ret = virParseNumber(&p);
+ if (ret == -1)
+ goto fail;
+
+ *kvm_version = ret;
+ }
+
+ *version = (major * 1000 * 1000) + (minor * 1000) + micro;
+
+ qemudDebug("Version %d.%d.%d - cooked version: %d",
+ major, minor, micro, *version);
+ if (*kvm_version)
+ qemudDebug("KVM version %d detected", *kvm_version);
+
+ return 0;
+
+fail:
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse QEMU version number in '%s'"),
+ str);
+ return -1;
+}
int qemudExtractVersionInfo(const char *qemu,
unsigned int *retversion,
@@ -421,7 +488,6 @@ int qemudExtractVersionInfo(const char *qemu,
pid_t child;
int newstdout = -1;
int ret = -1, status;
- unsigned int major, minor, micro;
unsigned int version, kvm_version;
unsigned int flags = 0;
@@ -443,22 +509,11 @@ int qemudExtractVersionInfo(const char *qemu,
goto cleanup2;
}
- if (sscanf(help, "QEMU PC emulator version %u.%u.%u (kvm-%u)",
- &major, &minor, µ, &kvm_version) != 4)
- kvm_version = 0;
+ char *eol = strchr(help, '\n');
+ if (eol) *eol = '\0';
- if (!kvm_version &&
- sscanf(help, "QEMU PC emulator version %u.%u.%u",
- &major, &minor, µ) != 3) {
- char *eol = strchr(help, '\n');
- if (eol) *eol = '\0';
- qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("cannot parse QEMU version number in
'%s'"),
- help);
+ if (qemudParseVersionStr(help, &version, &kvm_version) == -1)
goto cleanup2;
- }
-
- version = (major * 1000 * 1000) + (minor * 1000) + micro;
if (strstr(help, "-no-kqemu"))
flags |= QEMUD_CMD_FLAG_KQEMU;
@@ -512,10 +567,7 @@ int qemudExtractVersionInfo(const char *qemu,
ret = 0;
- qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
- major, minor, micro, version, flags);
- if (kvm_version)
- qemudDebug("KVM version %d detected", kvm_version);
+ qemudDebug("QEMU supported cmdline flags = %d", flags);
cleanup2:
VIR_FREE(help);
--
1.6.0.6