[libvirt] [PATCH 12/21] Move code for low level QEMU monitor interaction into separate file

Daniel P. Berrange berrange at redhat.com
Fri Oct 23 13:05:41 UTC 2009


The qemu_driver.c code should not contain any code that interacts
with the QEMU monitor at a low level. A previous commit moved all
the command invocations out. This change moves out the code which
actually opens the monitor device.

* src/qemu/qemu_driver.c: Remove qemudOpenMonitor & methods called
  from it.
* src/Makefile.am: Add qemu_monitor.{c,h}
* src/qemu/qemu_monitor.h: Add qemuMonitorOpen()
* src/qemu/qemu_monitor.c: All code for opening the monitor
---
 po/POTFILES.in          |    1 +
 src/Makefile.am         |    1 +
 src/qemu/qemu_driver.c  |  306 ++++++----------------------------------------
 src/qemu/qemu_monitor.c |  268 +++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor.h |   37 ++++++
 5 files changed, 347 insertions(+), 266 deletions(-)
 create mode 100644 src/qemu/qemu_monitor.c
 create mode 100644 src/qemu/qemu_monitor.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1a12a39..5b9a364 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -26,6 +26,7 @@ src/openvz/openvz_driver.c
 src/phyp/phyp_driver.c
 src/qemu/qemu_conf.c
 src/qemu/qemu_driver.c
+src/qemu/qemu_monitor.c
 src/qemu/qemu_monitor_text.c
 src/remote/remote_driver.c
 src/secret/secret_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e27ea7..9ed9bc3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -181,6 +181,7 @@ VBOX_DRIVER_EXTRA_DIST = vbox/vbox_tmpl.c vbox/README
 
 QEMU_DRIVER_SOURCES =						\
 		qemu/qemu_conf.c qemu/qemu_conf.h		\
+		qemu/qemu_monitor.c qemu/qemu_monitor.h		\
 		qemu/qemu_monitor_text.c			\
 		qemu/qemu_monitor_text.h			\
 		qemu/qemu_driver.c qemu/qemu_driver.h
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1bb82eb..b36839b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -55,6 +55,7 @@
 #include "datatypes.h"
 #include "qemu_driver.h"
 #include "qemu_conf.h"
+#include "qemu_monitor.h"
 #include "qemu_monitor_text.h"
 #include "c-ctype.h"
 #include "event.h"
@@ -298,11 +299,24 @@ cleanup:
     return rc;
 }
 
+static int
+qemuConnectMonitor(virDomainObjPtr vm, int reconnect)
+{
+    int rc;
+    if ((rc = qemuMonitorOpen(vm, reconnect)) != 0) {
+        VIR_ERROR(_("Failed to connect monitor for %s: %d\n"),
+                  vm->def->name, rc);
+        return -1;
+    }
 
-static int qemudOpenMonitor(virConnectPtr conn,
-                            virDomainObjPtr vm,
-                            int reconnect);
+    if ((vm->monitorWatch = virEventAddHandle(vm->monitor,
+                                              VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR,
+                                              qemudDispatchVMEvent,
+                                              vm, NULL)) < 0)
+        return -1;
 
+    return 0;
+}
 
 /*
  * Open an existing VM's monitor, re-detect VCPU threads
@@ -311,17 +325,13 @@ static int qemudOpenMonitor(virConnectPtr conn,
 static void
 qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaque)
 {
-    int rc;
     virDomainObjPtr obj = payload;
     struct qemud_driver *driver = opaque;
 
     virDomainObjLock(obj);
 
-    if ((rc = qemudOpenMonitor(NULL, obj, 1)) != 0) {
-        VIR_ERROR(_("Failed to reconnect monitor for %s: %d\n"),
-                  obj->def->name, rc);
+    if (qemuConnectMonitor(obj, 1) < 0)
         goto error;
-    }
 
     if (qemuUpdateActivePciHostdevs(driver, obj->def) < 0) {
         goto error;
@@ -755,89 +765,10 @@ qemudShutdown(void) {
     return 0;
 }
 
-/* Return -1 for error, 1 to continue reading and 0 for success */
-typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
-                                      virDomainObjPtr vm,
-                                      const char *output,
-                                      int fd);
-
-/*
- * Returns -1 for error, 0 on end-of-file, 1 for success
- */
-static int
-qemudReadMonitorOutput(virConnectPtr conn,
-                       virDomainObjPtr vm,
-                       int fd,
-                       char *buf,
-                       size_t buflen,
-                       qemudHandlerMonitorOutput func,
-                       const char *what,
-                       int timeout)
-{
-    size_t got = 0;
-    buf[0] = '\0';
-    timeout *= 1000; /* poll wants milli seconds */
-
-    /* Consume & discard the initial greeting */
-    while (got < (buflen-1)) {
-        ssize_t ret;
-
-        ret = read(fd, buf+got, buflen-got-1);
-
-        if (ret < 0) {
-            struct pollfd pfd = { .fd = fd, .events = POLLIN };
-            if (errno == EINTR)
-                continue;
-
-            if (errno != EAGAIN) {
-                virReportSystemError(conn, errno,
-                                     _("Failure while reading %s startup output"),
-                                     what);
-                return -1;
-            }
-
-            ret = poll(&pfd, 1, timeout);
-            if (ret == 0) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("Timed out while reading %s startup output"), what);
-                return -1;
-            } else if (ret == -1) {
-                if (errno != EINTR) {
-                    virReportSystemError(conn, errno,
-                                         _("Failure while reading %s startup output"),
-                                         what);
-                    return -1;
-                }
-            } else {
-                /* Make sure we continue loop & read any further data
-                   available before dealing with EOF */
-                if (pfd.revents & (POLLIN | POLLHUP))
-                    continue;
-
-                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 _("Failure while reading %s startup output"), what);
-                return -1;
-            }
-        } else if (ret == 0) {
-            return 0;
-        } else {
-            got += ret;
-            buf[got] = '\0';
-            ret = func(conn, vm, buf, fd);
-            if (ret == -1)
-                return -1;
-            if (ret == 1)
-                continue;
-            return 1;
-        }
-    }
-
-    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                     _("Out of space while reading %s startup output"), what);
-    return -1;
-
-}
-
+typedef int qemuLogHandleOutput(virConnectPtr conn,
+                                virDomainObjPtr vm,
+                                const char *output,
+                                int fd);
 
 /*
  * Returns -1 for error, 0 on success
@@ -848,7 +779,7 @@ qemudReadLogOutput(virConnectPtr conn,
                    int fd,
                    char *buf,
                    size_t buflen,
-                   qemudHandlerMonitorOutput func,
+                   qemuLogHandleOutput func,
                    const char *what,
                    int timeout)
 {
@@ -903,177 +834,20 @@ qemudReadLogOutput(virConnectPtr conn,
     return -1;
 }
 
-static int
-qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
-                        virDomainObjPtr vm,
-                        const char *output,
-                        int fd)
-{
-    if (strstr(output, "(qemu) ") == NULL)
-        return 1; /* keep reading */
-
-    vm->monitor = fd;
-
-    return 0;
-}
-
-static int
-qemudOpenMonitorCommon(virConnectPtr conn,
-                       virDomainObjPtr vm,
-                       int monfd,
-                       int reconnect)
-{
-    char buf[1024];
-    int ret;
-
-    if (virSetCloseExec(monfd) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("Unable to set monitor close-on-exec flag"));
-        return -1;
-    }
-    if (virSetNonBlock(monfd) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("Unable to put monitor into non-blocking mode"));
-        return -1;
-    }
-
-    if (!reconnect) {
-        if (qemudReadMonitorOutput(conn,
-                                   vm, monfd,
-                                   buf, sizeof(buf),
-                                   qemudCheckMonitorPrompt,
-                                   "monitor", 10) <= 0)
-            ret = -1;
-        else
-            ret = 0;
-    } else {
-        vm->monitor = monfd;
-        ret = 0;
-    }
-
-    if (ret != 0)
-        return ret;
 
-    if ((vm->monitorWatch = virEventAddHandle(vm->monitor,
-                                              VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR,
-                                              qemudDispatchVMEvent,
-                                              vm, NULL)) < 0)
-        return -1;
-
-    return 0;
-}
-
-static int
-qemudOpenMonitorUnix(virConnectPtr conn,
-                     virDomainObjPtr vm,
-                     const char *monitor,
-                     int reconnect)
-{
-    struct sockaddr_un addr;
-    int monfd;
-    int timeout = 3; /* In seconds */
-    int ret, i = 0;
-
-    if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
-        virReportSystemError(conn, errno,
-                             "%s", _("failed to create socket"));
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    if (virStrcpyStatic(addr.sun_path, monitor) == NULL) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Monitor path %s too big for destination"), monitor);
-        goto error;
-    }
-
-    do {
-        ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));
-
-        if (ret == 0)
-            break;
-
-        if (errno == ENOENT || errno == ECONNREFUSED) {
-            /* ENOENT       : Socket may not have shown up yet
-             * ECONNREFUSED : Leftover socket hasn't been removed yet */
-            continue;
-        }
-
-        virReportSystemError(conn, errno, "%s",
-                             _("failed to connect to monitor socket"));
-        goto error;
-
-    } while ((++i <= timeout*5) && (usleep(.2 * 1000000) <= 0));
-
-    if (ret != 0) {
-        virReportSystemError(conn, errno, "%s",
-                             _("monitor socket did not show up."));
-        goto error;
-    }
-
-    if (qemudOpenMonitorCommon(conn, vm, monfd, reconnect) < 0)
-        goto error;
-
-    return 0;
-
-error:
-    close(monfd);
-    return -1;
-}
-
-static int
-qemudOpenMonitorPty(virConnectPtr conn,
-                    virDomainObjPtr vm,
-                    const char *monitor,
-                    int reconnect)
-{
-    int monfd;
-
-    if ((monfd = open(monitor, O_RDWR)) < 0) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("Unable to open monitor path %s"), monitor);
-        return -1;
-    }
-
-    if (qemudOpenMonitorCommon(conn, vm, monfd, reconnect) < 0)
-        goto error;
-
-    return 0;
-
-error:
-    close(monfd);
-    return -1;
-}
-
-static int
-qemudOpenMonitor(virConnectPtr conn,
-                 virDomainObjPtr vm,
-                 int reconnect)
-{
-    switch (vm->monitor_chr->type) {
-    case VIR_DOMAIN_CHR_TYPE_UNIX:
-        return qemudOpenMonitorUnix(conn, vm,
-                                    vm->monitor_chr->data.nix.path,
-                                    reconnect);
-    case VIR_DOMAIN_CHR_TYPE_PTY:
-        return qemudOpenMonitorPty(conn, vm,
-                                   vm->monitor_chr->data.file.path,
-                                   reconnect);
-    default:
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("unable to handle monitor type: %s"),
-                         virDomainChrTypeToString(vm->monitor_chr->type));
-        return -1;
-    }
-}
-
-/* Returns -1 for error, 0 success, 1 continue reading */
+/*
+ * Look at a chunk of data from the QEMU stdout logs and try to
+ * find a TTY device, as indicated by a line like
+ *
+ * char device redirected to /dev/pts/3
+ *
+ * Returns -1 for error, 0 success, 1 continue reading
+ */
 static int
-qemudExtractMonitorPath(virConnectPtr conn,
-                        const char *haystack,
-                        size_t *offset,
-                        char **path)
+qemudExtractTTYPath(virConnectPtr conn,
+                    const char *haystack,
+                    size_t *offset,
+                    char **path)
 {
     static const char needle[] = "char device redirected to";
     char *tmp, *dev;
@@ -1131,8 +905,8 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
     for (i = 0 ; i < vm->def->nserials ; i++) {
         virDomainChrDefPtr chr = vm->def->serials[i];
         if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
-            if ((ret = qemudExtractMonitorPath(conn, output, &offset,
-                                               &chr->data.file.path)) != 0)
+            if ((ret = qemudExtractTTYPath(conn, output, &offset,
+                                           &chr->data.file.path)) != 0)
                 return ret;
         }
     }
@@ -1141,8 +915,8 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
     for (i = 0 ; i < vm->def->nparallels ; i++) {
         virDomainChrDefPtr chr = vm->def->parallels[i];
         if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
-            if ((ret = qemudExtractMonitorPath(conn, output, &offset,
-                                               &chr->data.file.path)) != 0)
+            if ((ret = qemudExtractTTYPath(conn, output, &offset,
+                                           &chr->data.file.path)) != 0)
                 return ret;
         }
     }
@@ -1179,7 +953,7 @@ qemudWaitForMonitor(virConnectPtr conn,
         return -1;
     }
 
-    if (qemudOpenMonitor(conn, vm, 0) < 0)
+    if (qemuConnectMonitor(vm, 0) < 0)
         return -1;
 
     return 0;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
new file mode 100644
index 0000000..ab1a98c
--- /dev/null
+++ b/src/qemu/qemu_monitor.c
@@ -0,0 +1,268 @@
+/*
+ * qemu_monitor.c: interaction with QEMU monitor console
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange at redhat.com>
+ */
+
+#include <config.h>
+
+#include <poll.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "qemu_monitor.h"
+#include "qemu_conf.h"
+#include "event.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+/* Return -1 for error, 1 to continue reading and 0 for success */
+typedef int qemuMonitorHandleOutput(virDomainObjPtr vm,
+                                    const char *output,
+                                    int fd);
+
+/*
+ * Returns -1 for error, 0 on end-of-file, 1 for success
+ */
+static int
+qemuMonitorReadOutput(virDomainObjPtr vm,
+                      int fd,
+                      char *buf,
+                      size_t buflen,
+                      qemuMonitorHandleOutput func,
+                      const char *what,
+                      int timeout)
+{
+    size_t got = 0;
+    buf[0] = '\0';
+    timeout *= 1000; /* poll wants milli seconds */
+
+    /* Consume & discard the initial greeting */
+    while (got < (buflen-1)) {
+        ssize_t ret;
+
+        ret = read(fd, buf+got, buflen-got-1);
+
+        if (ret < 0) {
+            struct pollfd pfd = { .fd = fd, .events = POLLIN };
+            if (errno == EINTR)
+                continue;
+
+            if (errno != EAGAIN) {
+                virReportSystemError(NULL, errno,
+                                     _("Failure while reading %s startup output"),
+                                     what);
+                return -1;
+            }
+
+            ret = poll(&pfd, 1, timeout);
+            if (ret == 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("Timed out while reading %s startup output"), what);
+                return -1;
+            } else if (ret == -1) {
+                if (errno != EINTR) {
+                    virReportSystemError(NULL, errno,
+                                         _("Failure while reading %s startup output"),
+                                         what);
+                    return -1;
+                }
+            } else {
+                /* Make sure we continue loop & read any further data
+                   available before dealing with EOF */
+                if (pfd.revents & (POLLIN | POLLHUP))
+                    continue;
+
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("Failure while reading %s startup output"), what);
+                return -1;
+            }
+        } else if (ret == 0) {
+            return 0;
+        } else {
+            got += ret;
+            buf[got] = '\0';
+            ret = func(vm, buf, fd);
+            if (ret == -1)
+                return -1;
+            if (ret == 1)
+                continue;
+            return 1;
+        }
+    }
+
+    qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                     _("Out of space while reading %s startup output"), what);
+    return -1;
+
+}
+
+static int
+qemuMonitorCheckPrompt(virDomainObjPtr vm,
+                       const char *output,
+                       int fd)
+{
+    if (strstr(output, "(qemu) ") == NULL)
+        return 1; /* keep reading */
+
+    vm->monitor = fd;
+
+    return 0;
+}
+
+static int
+qemuMonitorOpenCommon(virDomainObjPtr vm,
+                      int monfd,
+                      int reconnect)
+{
+    char buf[1024];
+    int ret;
+
+    if (virSetCloseExec(monfd) < 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         "%s", _("Unable to set monitor close-on-exec flag"));
+        return -1;
+    }
+    if (virSetNonBlock(monfd) < 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         "%s", _("Unable to put monitor into non-blocking mode"));
+        return -1;
+    }
+
+    if (!reconnect) {
+        if (qemuMonitorReadOutput(vm, monfd,
+                                  buf, sizeof(buf),
+                                  qemuMonitorCheckPrompt,
+                                  "monitor", 10) <= 0)
+            ret = -1;
+        else
+            ret = 0;
+    } else {
+        vm->monitor = monfd;
+        ret = 0;
+    }
+
+    if (ret != 0)
+        return ret;
+
+    return 0;
+}
+
+static int
+qemuMonitorOpenUnix(virDomainObjPtr vm,
+                    const char *monitor,
+                    int reconnect)
+{
+    struct sockaddr_un addr;
+    int monfd;
+    int timeout = 3; /* In seconds */
+    int ret, i = 0;
+
+    if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+        virReportSystemError(NULL, errno,
+                             "%s", _("failed to create socket"));
+        return -1;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    if (virStrcpyStatic(addr.sun_path, monitor) == NULL) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Monitor path %s too big for destination"), monitor);
+        goto error;
+    }
+
+    do {
+        ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr));
+
+        if (ret == 0)
+            break;
+
+        if (errno == ENOENT || errno == ECONNREFUSED) {
+            /* ENOENT       : Socket may not have shown up yet
+             * ECONNREFUSED : Leftover socket hasn't been removed yet */
+            continue;
+        }
+
+        virReportSystemError(NULL, errno, "%s",
+                             _("failed to connect to monitor socket"));
+        goto error;
+
+    } while ((++i <= timeout*5) && (usleep(.2 * 1000000) <= 0));
+
+    if (ret != 0) {
+        virReportSystemError(NULL, errno, "%s",
+                             _("monitor socket did not show up."));
+        goto error;
+    }
+
+    if (qemuMonitorOpenCommon(vm, monfd, reconnect) < 0)
+        goto error;
+
+    return 0;
+
+error:
+    close(monfd);
+    return -1;
+}
+
+static int
+qemuMonitorOpenPty(virDomainObjPtr vm,
+                   const char *monitor,
+                   int reconnect)
+{
+    int monfd;
+
+    if ((monfd = open(monitor, O_RDWR)) < 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Unable to open monitor path %s"), monitor);
+        return -1;
+    }
+
+    if (qemuMonitorOpenCommon(vm, monfd, reconnect) < 0)
+        goto error;
+
+    return 0;
+
+error:
+    close(monfd);
+    return -1;
+}
+
+int
+qemuMonitorOpen(virDomainObjPtr vm,
+                int reconnect)
+{
+    switch (vm->monitor_chr->type) {
+    case VIR_DOMAIN_CHR_TYPE_UNIX:
+        return qemuMonitorOpenUnix(vm, vm->monitor_chr->data.nix.path,
+                                   reconnect);
+    case VIR_DOMAIN_CHR_TYPE_PTY:
+        return qemuMonitorOpenPty(vm, vm->monitor_chr->data.file.path,
+                                  reconnect);
+    default:
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("unable to handle monitor type: %s"),
+                         virDomainChrTypeToString(vm->monitor_chr->type));
+        return -1;
+    }
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
new file mode 100644
index 0000000..bdeafe0
--- /dev/null
+++ b/src/qemu/qemu_monitor.h
@@ -0,0 +1,37 @@
+/*
+ * qemu_monitor.h: interaction with QEMU monitor console
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange at redhat.com>
+ */
+
+
+#ifndef QEMU_MONITOR_H
+#define QEMU_MONITOR_H
+
+#include "internal.h"
+
+#include "domain_conf.h"
+
+int qemuMonitorOpen(virDomainObjPtr vm,
+                    int reconnect);
+
+
+
+#endif /* QEMU_MONITOR_H */
-- 
1.6.2.5




More information about the libvir-list mailing list