All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: agl@linux.vnet.ibm.com, stefanha@linux.vnet.ibm.com,
	Jes.Sorensen@redhat.com, marcel.mittelstaedt@de.ibm.com,
	mdroth@linux.vnet.ibm.com, markus_mueller@de.ibm.com,
	aliguori@linux.vnet.ibm.com, ryanh@us.ibm.com,
	abeekhof@redhat.com
Subject: [Qemu-devel] [RFC][PATCH v6 03/23] Make qemu timers available for tools
Date: Mon, 17 Jan 2011 07:14:57 -0600	[thread overview]
Message-ID: <1295270117-24760-4-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1295270117-24760-1-git-send-email-mdroth@linux.vnet.ibm.com>

To be able to use qemu_mod_timer() and friends to register timeout
events for virtagent's qemu-va tool, we need to do the following:

Move several blocks of code out of cpus.c that handle initialization
of qemu's io_thread_fd and working with it via
qemu_notify_event()/qemu_event_read()/etc, and make them accessible
as backend functions to both the emulator code and qemu-tool.c via
wrapper functions within cpus.c and qemu-tool.c, respectively. These
have been added to qemu-ioh.c, where similar treatment was given to
qemu_set_fd_handler() and friends.

Some of these wrapper functions lack declarations when being
built into tools, so we add those via qemu-tool.h, which can be included
by a tool to access them. With these changes we can drive timers in a
tool linking it against qemu-timer.o and then implementing something
similar to the main i/o loop in vl.c:

init_clocks();
configure_alarms("dynticks");
if (init_timer_alarm() < 0) {
    errx(EXIT_FAILURE, "could not initialize alarm timer");
}

while (running) {
    //do work
    qemu_run_all_timers();
}

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 cpus.c      |   83 +++++++---------------------------------------------
 qemu-ioh.c  |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-ioh.h  |    9 ++++++
 qemu-tool.c |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 qemu-tool.h |   26 ++++++++++++++++
 5 files changed, 229 insertions(+), 74 deletions(-)
 create mode 100644 qemu-tool.h

diff --git a/cpus.c b/cpus.c
index 0309189..2f1adf6 100644
--- a/cpus.c
+++ b/cpus.c
@@ -163,90 +163,24 @@ static int io_thread_fd = -1;
 
 static void qemu_event_increment(void)
 {
-    /* Write 8 bytes to be compatible with eventfd.  */
-    static const uint64_t val = 1;
-    ssize_t ret;
-
-    if (io_thread_fd == -1)
-        return;
-
-    do {
-        ret = write(io_thread_fd, &val, sizeof(val));
-    } while (ret < 0 && errno == EINTR);
-
-    /* EAGAIN is fine, a read must be pending.  */
-    if (ret < 0 && errno != EAGAIN) {
-        fprintf(stderr, "qemu_event_increment: write() filed: %s\n",
-                strerror(errno));
-        exit (1);
-    }
-}
-
-static void qemu_event_read(void *opaque)
-{
-    int fd = (unsigned long)opaque;
-    ssize_t len;
-    char buffer[512];
-
-    /* Drain the notify pipe.  For eventfd, only 8 bytes will be read.  */
-    do {
-        len = read(fd, buffer, sizeof(buffer));
-    } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
+    return iothread_event_increment(&io_thread_fd);
 }
 
 static int qemu_event_init(void)
 {
-    int err;
-    int fds[2];
-
-    err = qemu_eventfd(fds);
-    if (err == -1)
-        return -errno;
-
-    err = fcntl_setfl(fds[0], O_NONBLOCK);
-    if (err < 0)
-        goto fail;
-
-    err = fcntl_setfl(fds[1], O_NONBLOCK);
-    if (err < 0)
-        goto fail;
-
-    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
-                         (void *)(unsigned long)fds[0]);
-
-    io_thread_fd = fds[1];
-    return 0;
-
-fail:
-    close(fds[0]);
-    close(fds[1]);
-    return err;
+    return iothread_event_init(&io_thread_fd);
 }
 #else
 HANDLE qemu_event_handle;
 
-static void dummy_event_handler(void *opaque)
-{
-}
-
 static int qemu_event_init(void)
 {
-    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
-    if (!qemu_event_handle) {
-        fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
-        return -1;
-    }
-    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
-    return 0;
+    return win32_event_init(&qemu_event_handle);
 }
 
 static void qemu_event_increment(void)
 {
-    if (!SetEvent(qemu_event_handle)) {
-        fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
-                GetLastError());
-        exit (1);
-    }
+    win32_event_increment(&qemu_event_handle);
 }
 #endif
 
@@ -296,11 +230,10 @@ void qemu_cpu_kick(void *env)
     return;
 }
 
-void qemu_notify_event(void)
+static void qemu_stop_all_vcpus(void)
 {
     CPUState *env = cpu_single_env;
 
-    qemu_event_increment ();
     if (env) {
         cpu_exit(env);
     }
@@ -309,6 +242,12 @@ void qemu_notify_event(void)
     }
 }
 
+void qemu_notify_event(void)
+{
+    qemu_event_increment();
+    qemu_stop_all_vcpus();
+}
+
 void qemu_mutex_lock_iothread(void) {}
 void qemu_mutex_unlock_iothread(void) {}
 
diff --git a/qemu-ioh.c b/qemu-ioh.c
index cc71470..001e7a2 100644
--- a/qemu-ioh.c
+++ b/qemu-ioh.c
@@ -22,7 +22,11 @@
  * THE SOFTWARE.
  */
 #include "qemu-ioh.h"
+#include "qemu-char.h"
 #include "qlist.h"
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
 
 /* XXX: fd_read_poll should be suppressed, but an API change is
    necessary in the character devices to suppress fd_can_read(). */
@@ -113,3 +117,92 @@ void qemu_process_fd_handlers2(void *ioh_record_list, const fd_set *rfds,
         }
     }
 }
+
+#ifndef _WIN32
+void iothread_event_increment(int *io_thread_fd)
+{
+    /* Write 8 bytes to be compatible with eventfd.  */
+    static const uint64_t val = 1;
+    ssize_t ret;
+
+    if (*io_thread_fd == -1)
+        return;
+
+    do {
+        ret = write(*io_thread_fd, &val, sizeof(val));
+    } while (ret < 0 && errno == EINTR);
+
+    /* EAGAIN is fine, a read must be pending.  */
+    if (ret < 0 && errno != EAGAIN) {
+        fprintf(stderr, "qemu_event_increment: write() filed: %s\n",
+                strerror(errno));
+        exit (1);
+    }
+}
+
+static void qemu_event_read(void *opaque)
+{
+    int fd = (unsigned long)opaque;
+    ssize_t len;
+    char buffer[512];
+
+    /* Drain the notify pipe.  For eventfd, only 8 bytes will be read.  */
+    do {
+        len = read(fd, buffer, sizeof(buffer));
+    } while (len == -1 && errno == EINTR);
+}
+
+
+int iothread_event_init(int *io_thread_fd)
+{
+    int err;
+    int fds[2];
+
+    err = qemu_eventfd(fds);
+    if (err == -1)
+        return -errno;
+
+    err = fcntl_setfl(fds[0], O_NONBLOCK);
+    if (err < 0)
+        goto fail;
+
+    err = fcntl_setfl(fds[1], O_NONBLOCK);
+    if (err < 0)
+        goto fail;
+
+    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
+                         (void *)(unsigned long)fds[0]);
+
+    *io_thread_fd = fds[1];
+    return 0;
+
+fail:
+    close(fds[0]);
+    close(fds[1]);
+    return err;
+}
+#else
+static void dummy_event_handler(void *opaque)
+{
+}
+
+int win32_event_init(HANDLE *qemu_event_handle)
+{
+    *qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (!qemu_event_handle) {
+        fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
+        return -1;
+    }
+    qemu_add_wait_object(*qemu_event_handle, dummy_event_handler, NULL);
+    return 0;
+}
+
+void win32_event_increment(HANDLE *qemu_event_handle)
+{
+    if (!SetEvent(*qemu_event_handle)) {
+        fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
+                GetLastError());
+        exit (1);
+    }
+}
+#endif
diff --git a/qemu-ioh.h b/qemu-ioh.h
index 7c6e833..2c714a9 100644
--- a/qemu-ioh.h
+++ b/qemu-ioh.h
@@ -31,4 +31,13 @@ void qemu_get_fdset2(void *ioh_record_list, int *nfds, fd_set *rfds,
 void qemu_process_fd_handlers2(void *ioh_record_list, const fd_set *rfds,
                                const fd_set *wfds, const fd_set *xfds);
 
+
+#ifndef _WIN32
+void iothread_event_increment(int *io_thread_fd);
+int iothread_event_init(int *io_thread_fd);
+#else
+int win32_event_init(HANDLE *qemu_event_handle);
+void win32_event_increment(HANDLE *qemu_event_handle);
+#endif
+
 #endif
diff --git a/qemu-tool.c b/qemu-tool.c
index 78d3532..027ea31 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu-common.h"
+#include "qemu-tool.h"
 #include "monitor.h"
 #include "qemu-timer.h"
 #include "qemu-log.h"
@@ -19,12 +20,11 @@
 
 #include <sys/time.h>
 
-QEMUClock *rt_clock;
+QEMUClock *rtc_clock;
 
 FILE *logfile;
 static QLIST_HEAD(, IOHandlerRecord) io_handlers =
     QLIST_HEAD_INITIALIZER(io_handlers);
-
 struct QEMUBH
 {
     QEMUBHFunc *cb;
@@ -134,3 +134,91 @@ void qemu_process_fd_handlers(const fd_set *rfds, const fd_set *wfds,
 {
     return qemu_process_fd_handlers2(&io_handlers, rfds, wfds, xfds);
 }
+
+#ifndef _WIN32
+static int io_thread_fd = -1;
+
+void qemu_event_increment(void)
+{
+    return iothread_event_increment(&io_thread_fd);
+}
+
+int qemu_event_init(void)
+{
+    return iothread_event_init(&io_thread_fd);
+}
+#else
+HANDLE qemu_event_handle;
+
+int qemu_event_init(void)
+{
+    return win32_event_init(&qemu_event_handle);
+}
+
+void qemu_event_increment(void)
+{
+    win32_event_increment(&qemu_event_handle);
+}
+#endif
+
+void qemu_notify_event(void)
+{
+    qemu_event_increment ();
+}
+
+/*
+ * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
+ */
+int qemu_eventfd(int fds[2])
+{
+#ifdef CONFIG_EVENTFD
+    int ret;
+
+    ret = eventfd(0, 0);
+    if (ret >= 0) {
+        fds[0] = ret;
+        qemu_set_cloexec(ret);
+        if ((fds[1] = dup(ret)) == -1) {
+            close(ret);
+            return -1;
+        }
+        qemu_set_cloexec(fds[1]);
+        return 0;
+    }
+
+    if (errno != ENOSYS) {
+        return -1;
+    }
+#endif
+
+    return qemu_pipe(fds);
+}
+
+void qemu_put_be64(QEMUFile *f, uint64_t v)
+{
+}
+
+uint64_t qemu_get_be64(QEMUFile *f)
+{
+    return 0;
+}
+
+const VMStateInfo vmstate_info_int64;
+int use_icount = 0;
+int vm_running = 1;
+int64_t qemu_icount;
+
+int vmstate_register(DeviceState *dev, int instance_id,
+                     const VMStateDescription *vmsd, void *opaque)
+{
+    return 0;
+}
+int64_t cpu_get_icount(void) {
+    return 0;
+}
+
+VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
+                                                     void *opaque)
+{
+    return NULL;
+}
diff --git a/qemu-tool.h b/qemu-tool.h
new file mode 100644
index 0000000..fd693cf
--- /dev/null
+++ b/qemu-tool.h
@@ -0,0 +1,26 @@
+#ifndef QEMU_TOOL_H
+#define QEMU_TOOL_H
+
+#include "qemu-common.h"
+
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
+typedef void VMStateDescription;
+typedef int VMStateInfo;
+
+#ifndef _WIN32
+void qemu_event_increment(void);
+int qemu_event_init(void);
+#else
+int qemu_event_init(void);
+void qemu_event_increment(void);
+#endif
+
+void qemu_put_be64(QEMUFile *f, uint64_t v);
+uint64_t qemu_get_be64(QEMUFile *f);
+int vmstate_register(DeviceState *dev, int instance_id,
+                     const VMStateDescription *vmsd, void *opaque);
+
+#endif
-- 
1.7.0.4

  parent reply	other threads:[~2011-01-17 13:16 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-17 13:14 [Qemu-devel] [RFC][PATCH v6 00/23] virtagent: host/guest RPC communication agent Michael Roth
2011-01-17 13:14 ` [Qemu-devel] [RFC][PATCH v6 01/23] Move code related to fd handlers into utility functions Michael Roth
2011-01-17 13:56   ` Gerd Hoffmann
2011-01-17 13:14 ` [Qemu-devel] [RFC][PATCH v6 02/23] Add qemu_set_fd_handler() wrappers to qemu-tools.c Michael Roth
2011-01-17 13:14 ` Michael Roth [this message]
2011-01-21 16:30   ` [Qemu-devel] Re: [RFC][PATCH v6 03/23] Make qemu timers available for tools Jes Sorensen
2011-01-21 17:26     ` Michael Roth
2011-01-24  7:56       ` Jes Sorensen
2011-01-17 13:14 ` [Qemu-devel] [RFC][PATCH v6 04/23] virtagent: common code for managing client/server rpc jobs Michael Roth
2011-01-17 13:14 ` [Qemu-devel] [RFC][PATCH v6 05/23] virtagent: transport definitions read/send callback functions Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 06/23] virtagent: base client definitions Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 07/23] virtagent: base server definitions Michael Roth
2011-01-21 16:38   ` [Qemu-devel] " Jes Sorensen
2011-01-21 17:55     ` Michael Roth
2011-01-24 10:16       ` Jes Sorensen
2011-01-24 16:51         ` Michael Roth
2011-01-24 17:04           ` Jes Sorensen
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 08/23] virtagent: add va.getfile RPC Michael Roth
2011-01-21 16:40   ` [Qemu-devel] " Jes Sorensen
2011-01-21 17:20     ` Daniel P. Berrange
2011-01-21 18:23       ` Michael Roth
2011-01-24 22:08         ` Richard W.M. Jones
2011-01-24 22:20           ` Richard W.M. Jones
2011-01-24 22:26             ` Anthony Liguori
2011-01-24 22:48               ` Richard W.M. Jones
2011-01-24 23:40                 ` Anthony Liguori
2011-01-25  0:22                   ` Michael Roth
2011-01-25  0:25                     ` Anthony Liguori
2011-01-25  9:21                   ` Richard W.M. Jones
2011-01-25 15:12                     ` Anthony Liguori
2011-01-25 15:43                       ` Richard W.M. Jones
2011-01-26 13:01                         ` Richard W.M. Jones
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 09/23] virtagent: add agent_viewfile qmp/hmp command Michael Roth
2011-01-21 16:41   ` [Qemu-devel] " Jes Sorensen
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 10/23] virtagent: add va.getdmesg RPC Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 11/23] virtagent: add agent_viewdmesg qmp/hmp commands Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 12/23] virtagent: add va.shutdown RPC Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 13/23] virtagent: add agent_shutdown qmp/hmp commands Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 14/23] virtagent: add va.ping RPC Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 15/23] virtagent: add agent_ping qmp/hmp commands Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 16/23] virtagent: add agent_capabilities " Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 17/23] virtagent: add client capabilities init function Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 18/23] virtagent: add va.hello RPC Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 19/23] virtagent: add "hello" notification function for guest agent Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 20/23] virtagent: add va.capabilities RPC Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 21/23] virtagent: add virtagent guest daemon Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 22/23] virtagent: integrate virtagent server/client via chardev Michael Roth
2011-01-17 13:15 ` [Qemu-devel] [RFC][PATCH v6 23/23] virtagent: various bits to build QEMU with virtagent Michael Roth
2011-01-24 10:24   ` [Qemu-devel] " Jes Sorensen
2011-01-17 13:53 ` [Qemu-devel] [RFC][PATCH v6 00/23] virtagent: host/guest RPC communication agent Gerd Hoffmann
2011-01-17 14:53   ` Michael Roth
2011-01-18 14:02     ` Gerd Hoffmann
2011-01-18 14:13       ` Anthony Liguori
2011-01-31 14:41         ` Michael Roth
2011-02-01 22:18           ` Michael Roth
2011-02-14  9:49             ` Gerd Hoffmann
2011-02-16 16:04 ` Jes Sorensen
2011-02-16 17:22   ` Michael Roth
2011-02-17  8:26     ` Jes Sorensen
2011-02-17  9:08       ` Dor Laor
2011-02-17 14:39       ` Michael Roth
2011-02-18 12:45         ` Jes Sorensen
2011-02-18 14:07           ` Anthony Liguori
2011-02-18 14:30             ` Jes Sorensen
2011-02-18 14:57               ` Anthony Liguori
2011-02-21  8:32                 ` Jes Sorensen
2011-02-21 13:36                   ` Michael Roth
2011-02-21 13:38                     ` Jes Sorensen
2011-02-18 15:22             ` Gerd Hoffmann
2011-02-18 15:25               ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1295270117-24760-4-git-send-email-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=Jes.Sorensen@redhat.com \
    --cc=abeekhof@redhat.com \
    --cc=agl@linux.vnet.ibm.com \
    --cc=aliguori@linux.vnet.ibm.com \
    --cc=marcel.mittelstaedt@de.ibm.com \
    --cc=markus_mueller@de.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=ryanh@us.ibm.com \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.