From 847fc9945eafbb55816bc2a04b890b559dfe146d Mon Sep 17 00:00:00 2001
From: MATSUDA Daiki <matsudadik@intellilink.co.jp>
Date: Thu, 23 Aug 2012 12:29:23 +0900
Subject: [PATCH] agent: add virDrvDomainQemuAgentCommand prototype for
 drivers.

Add virDrvDomainQemuAgentCommand prototype for drivers.
Add virDomainQemuAgentCommand() for virDrvDomainQemuAgentCommand.

Signed-off-by: MATSUDA Daiki <matsudadik@intellilink.co.jp>
---
 include/libvirt/libvirt-qemu.h |  3 ++
 python/generator.py            |  1 +
 src/driver.h                   |  4 +++
 src/libvirt-qemu.c             | 54 ++++++++++++++++++++++++++++++++++
 src/libvirt_qemu.syms          |  5 ++++
 5 files changed, 67 insertions(+)

diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h
index 93386ca0b7..d7f8703f7c 100644
--- a/include/libvirt/libvirt-qemu.h
+++ b/include/libvirt/libvirt-qemu.h
@@ -51,6 +51,9 @@ typedef enum {
     VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT = 0,
 } virDomainQemuAgentCommandTimeoutValues;
 
+char *virDomainQemuAgentCommand(virDomainPtr domain, const char *cmd,
+                                int timeout, unsigned int flags);
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/python/generator.py b/python/generator.py
index 1f8719532d..7beb361256 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -431,6 +431,7 @@ skip_impl = (
 
 qemu_skip_impl = (
     'virDomainQemuMonitorCommand',
+    'virDomainQemuAgentCommand',
 )
 
 
diff --git a/src/driver.h b/src/driver.h
index 5fa2d36570..ccb01dc8c0 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -701,6 +701,9 @@ typedef int
 typedef int
     (*virDrvDomainQemuMonitorCommand)(virDomainPtr domain, const char *cmd,
                                       char **result, unsigned int flags);
+typedef char *
+    (*virDrvDomainQemuAgentCommand)(virDomainPtr domain, const char *cmd,
+                                    int timeout, unsigned int flags);
 
 /* Choice of unsigned int rather than pid_t is intentional.  */
 typedef virDomainPtr
@@ -1064,6 +1067,7 @@ struct _virDriver {
     virDrvDomainGetDiskErrors           domainGetDiskErrors;
     virDrvDomainSetMetadata             domainSetMetadata;
     virDrvDomainGetMetadata             domainGetMetadata;
+    virDrvDomainQemuAgentCommand        qemuDomainArbitraryAgentCommand;
 };
 
 typedef int
diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c
index 78480bbf45..7a45242543 100644
--- a/src/libvirt-qemu.c
+++ b/src/libvirt-qemu.c
@@ -185,3 +185,57 @@ error:
     virDispatchError(conn);
     return NULL;
 }
+
+/**
+ * virDomainQemuAgentCommand:
+ * @domain: a domain object
+ * @cmd: the guest agent command string
+ * @timeout: timeout seconds
+ * @flags: execution flags
+ *
+ * Execute an arbitrary Guest Agent command.
+ *
+ * Issue @cmd to the guest agent running in @domain.
+ * @timeout must be -2, -1, 0 or positive.
+ * VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK(-2): meaning to block forever waiting for
+ * a result.
+ * VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT(-1): use default timeout value.
+ * VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT(0): does not wait.
+ * positive value: wait for @timeout seconds
+ *
+ * Returns strings if success, NULL in failure.
+ */
+char *
+virDomainQemuAgentCommand(virDomainPtr domain,
+                          const char *cmd,
+                          int timeout,
+                          unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DEBUG("domain=%p, cmd=%s, timeout=%d, flags=%x",
+              domain, cmd, timeout, flags);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return NULL;
+    }
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        return NULL;
+    }
+
+    conn = domain->conn;
+
+    if (conn->driver->qemuDomainArbitraryAgentCommand) {
+        return conn->driver->qemuDomainArbitraryAgentCommand(domain, cmd,
+                                                             timeout, flags);
+    }
+
+    virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+    /* Copy to connection error object for back compatibility */
+    virDispatchError(conn);
+    return NULL;
+}
diff --git a/src/libvirt_qemu.syms b/src/libvirt_qemu.syms
index 8447730fd0..6e11509972 100644
--- a/src/libvirt_qemu.syms
+++ b/src/libvirt_qemu.syms
@@ -19,3 +19,8 @@ LIBVIRT_QEMU_0.9.4 {
     global:
         virDomainQemuAttach;
 } LIBVIRT_QEMU_0.8.3;
+
+LIBVIRT_QEMU_0.10.1 {
+    global:
+        virDomainQemuAgentCommand;
+} LIBVIRT_QEMU_0.9.4;