[libvirt] [PATCH v2 5/8] Qemu arbitrary monitor commands.

Chris Lalancette clalance at redhat.com
Wed Apr 28 20:20:50 UTC 2010


Implement the qemu driver's virDomainQemuMonitorCommand
and hook it into the API entry point.

Changes since v1:
 - Rename the (external) qemuMonitorCommand to qemuDomainMonitorCommand
 - Add virCheckFlags to qemuDomainMonitorCommand

Signed-off-by: Chris Lalancette <clalance at redhat.com>
---
 src/qemu/qemu_driver.c       |   42 +++++++++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_monitor.c      |   13 +++++++++++++
 src/qemu/qemu_monitor.h      |    2 ++
 src/qemu/qemu_monitor_json.c |   28 ++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |    4 ++++
 src/qemu/qemu_monitor_text.c |   21 +++++++++++++++++++++
 src/qemu/qemu_monitor_text.h |    3 +++
 7 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c720103..d4e4de5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11550,6 +11550,46 @@ cleanup:
     return ret;
 }
 
+static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
+                                    char **result, unsigned int flags ATTRIBUTE_UNUSED)
+{
+    struct qemud_driver *driver = domain->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv;
+
+    virCheckFlags(0, -1);
+
+    VIR_WARN(_("Qemu monitor command '%s' executed; libvirt results may be unpredictable!"), cmd);
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(domain->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    if (!virDomainObjIsActive(vm)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID,
+                        "%s", _("domain is not running"));
+        goto cleanup;
+   }
+
+    priv = vm->privateData;
+    qemuDomainObjEnterMonitorWithDriver(driver, vm);
+    ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result);
+    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
+
 static virDriver qemuDriver = {
     VIR_DRV_QEMU,
     "QEMU",
@@ -11647,7 +11687,7 @@ static virDriver qemuDriver = {
     qemuDomainSnapshotCurrent, /* domainSnapshotCurrent */
     qemuDomainRevertToSnapshot, /* domainRevertToSnapshot */
     qemuDomainSnapshotDelete, /* domainSnapshotDelete */
-    NULL, /* qemuDomainMonitorCommand */
+    qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
 };
 
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 5e83afc..0e1aa8b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1568,3 +1568,16 @@ int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
         ret = qemuMonitorTextDeleteSnapshot(mon, name);
     return ret;
 }
+
+int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply)
+{
+    int ret;
+
+    DEBUG("mon=%p, cmd=%s, reply=%p", mon, cmd, reply);
+
+    if (mon->json)
+        ret = qemuMonitorJSONArbitraryCommand(mon, cmd, reply);
+    else
+        ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply);
+    return ret;
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index ec848a8..3a6ffab 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -358,4 +358,6 @@ int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply);
+
 #endif /* QEMU_MONITOR_H */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 09a3562..9317659 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2174,3 +2174,31 @@ int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name)
     virJSONValueFree(reply);
     return ret;
 }
+
+int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
+                                    const char *cmd_str,
+                                    char **reply_str)
+{
+    virJSONValuePtr cmd = NULL;
+    virJSONValuePtr reply = NULL;
+    int ret = -1;
+
+    cmd = virJSONValueFromString(cmd_str);
+    if (!cmd)
+        return -1;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+
+    *reply_str = virJSONValueToString(reply);
+    if (!(*reply_str))
+        goto cleanup;
+
+    ret = 0;
+
+cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+
+    return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 07fa587..7977537 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -187,4 +187,8 @@ int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
+                                    const char *cmd_str,
+                                    char **reply_str);
+
 #endif /* QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 3f917bf..3d7f3ef 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -2481,3 +2481,24 @@ cleanup:
     VIR_FREE(reply);
     return ret;
 }
+
+int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
+                                    char **reply)
+{
+    char *safecmd = NULL;
+    int ret;
+
+    if (!(safecmd = qemuMonitorEscapeArg(cmd))) {
+        virReportOOMError();
+        return -1;
+    }
+
+    ret = qemuMonitorCommand(mon, safecmd, reply);
+    if (ret != 0)
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("failed to run cmd '%s'"), safecmd);
+
+    VIR_FREE(safecmd);
+
+    return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 23c3a45..9bea584 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -186,4 +186,7 @@ int qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
+                                    char **reply);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.6.1




More information about the libvir-list mailing list