From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com, mdroth@linux.vnet.ibm.com, quintela@redhat.com
Subject: [Qemu-devel] [PATCH v2 06/10] qemu-file: add QEMUFile<->visitor lookup routines
Date: Thu, 27 Oct 2011 12:06:29 -0500 [thread overview]
Message-ID: <1319735193-4718-7-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1319735193-4718-1-git-send-email-mdroth@linux.vnet.ibm.com>
This interface is to allow switching between Visitor-based and direct
QEMUFile usage to serialize/de-serialize fields. Once we're passed the
transitionary stages and all requisite interfaces are converted to
accepting Visitor objects, we can drop this dual approach and begin
utilizing non-QEMUFile-based Visitors.
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
hw/hw.h | 7 ++++
qemu-file.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 110 insertions(+), 1 deletions(-)
diff --git a/hw/hw.h b/hw/hw.h
index a793974..5c0eb65 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -10,6 +10,13 @@
#include "ioport.h"
#include "irq.h"
+#include "qemu-queue.h"
+#include "qapi/qapi-visit-core.h"
+#include "qapi/qemu-file-output-visitor.h"
+#include "qapi/qemu-file-input-visitor.h"
+
+Visitor *qemu_file_get_visitor(QEMUFile *f);
+QEMUFile *qemu_file_from_visitor(Visitor *v);
/* VM Load/Save */
diff --git a/qemu-file.c b/qemu-file.c
index a4aee9a..cdfe8a3 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -25,6 +25,8 @@
#include "qemu-common.h"
#include "qemu_socket.h"
#include "hw/hw.h"
+#include "qapi/qemu-file-output-visitor.h"
+#include "qapi/qemu-file-input-visitor.h"
#define IO_BUF_SIZE 32768
@@ -59,6 +61,94 @@ typedef struct QEMUFileSocket
QEMUFile *file;
} QEMUFileSocket;
+/* TODO: temporary mechanism to support existing function signatures by
+ * creating a 1-to-1 mapping between QEMUFile's and the actual Visitor type.
+ * In the case of QemuFileOutputVisitor/QemuFileInputVisitor, the QEMUFile
+ * arg corresponds to the handle used by the visitor for reads/writes. For
+ * other visitors, the QEMUFile will serve purely as a key.
+ *
+ * Once all interfaces are converted to using Visitor directly, we will
+ * remove this lookup logic and pass the Visitor to the registered save/load
+ * functions directly.
+ */
+
+/* Clean up a *Visitor object associated with the QEMUFile */
+typedef int (QEMUFileVisitorCleanupFunc)(void *opaque);
+
+typedef struct VisitorNode {
+ void *opaque;
+ Visitor *visitor;
+ QEMUFile *file;
+ QEMUFileVisitorCleanupFunc *cleanup;
+ QTAILQ_ENTRY(VisitorNode) entry;
+} VisitorNode;
+
+static QTAILQ_HEAD(, VisitorNode) qemu_file_visitors =
+ QTAILQ_HEAD_INITIALIZER(qemu_file_visitors);
+
+Visitor *qemu_file_get_visitor(QEMUFile *f)
+{
+ VisitorNode *vnode;
+ QTAILQ_FOREACH(vnode, &qemu_file_visitors, entry) {
+ if (vnode->file == f) {
+ return vnode->visitor;
+ }
+ }
+ /* all QEMUFile instances should have an associated visitor */
+ assert(false);
+}
+
+QEMUFile *qemu_file_from_visitor(Visitor *v)
+{
+ VisitorNode *vnode;
+ QTAILQ_FOREACH(vnode, &qemu_file_visitors, entry) {
+ if (vnode->visitor == v) {
+ return vnode->file;
+ }
+ }
+ return NULL;
+}
+
+static void qemu_file_put_visitor(QEMUFile *f, Visitor *v, void *opaque,
+ QEMUFileVisitorCleanupFunc *cleanup)
+{
+ VisitorNode *vnode = g_malloc0(sizeof(*vnode));
+ vnode->file = f;
+ vnode->visitor = v;
+ vnode->opaque = opaque;
+ vnode->cleanup = cleanup;
+ QTAILQ_INSERT_TAIL(&qemu_file_visitors, vnode, entry);
+}
+
+static void qemu_file_remove_visitor(QEMUFile *f)
+{
+ VisitorNode *vnode;
+ QTAILQ_FOREACH(vnode, &qemu_file_visitors, entry) {
+ if (vnode->file == f) {
+ QTAILQ_REMOVE(&qemu_file_visitors, vnode, entry);
+ if (vnode->cleanup) {
+ vnode->cleanup(vnode->opaque);
+ }
+ g_free(vnode);
+ }
+ }
+}
+
+static int qemu_file_cleanup_output_visitor(void *opaque)
+{
+ QemuFileOutputVisitor *v = opaque;
+ qemu_file_output_visitor_cleanup(v);
+ return 0;
+}
+
+static int qemu_file_cleanup_input_visitor(void *opaque)
+{
+ QemuFileInputVisitor *v = opaque;
+ qemu_file_input_visitor_cleanup(v);
+ return 0;
+}
+
+
static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
QEMUFileSocket *s = opaque;
@@ -177,8 +267,9 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
s = g_malloc0(sizeof(QEMUFileStdio));
s->stdio_file = fdopen(fd, mode);
- if (!s->stdio_file)
+ if (!s->stdio_file) {
goto fail;
+ }
if (mode[0] == 'r') {
s->file = qemu_fopen_ops(s, NULL, stdio_get_buffer, stdio_fclose,
@@ -270,6 +361,16 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
f->get_rate_limit = get_rate_limit;
f->is_write = 0;
+ if (put_buffer) {
+ QemuFileOutputVisitor *ov = qemu_file_output_visitor_new(f);
+ qemu_file_put_visitor(f, qemu_file_output_get_visitor(ov), ov,
+ qemu_file_cleanup_output_visitor);
+ } else {
+ QemuFileInputVisitor *iv = qemu_file_input_visitor_new(f);
+ qemu_file_put_visitor(f, qemu_file_input_get_visitor(iv), iv,
+ qemu_file_cleanup_input_visitor);
+ }
+
return f;
}
@@ -336,6 +437,7 @@ int qemu_fclose(QEMUFile *f)
{
int ret = 0;
qemu_fflush(f);
+ qemu_file_remove_visitor(f);
if (f->close) {
ret = f->close(f->opaque);
}
--
1.7.4.1
next prev parent reply other threads:[~2011-10-27 17:07 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-27 17:06 [Qemu-devel] [PATCH v2 00/10] do savevm/migration save/load via Visitor interface Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 01/10] qapi: add Visitor interfaces for uint*_t and int*_t Michael Roth
2011-12-20 11:12 ` Paolo Bonzini
2011-12-20 11:43 ` Paolo Bonzini
2011-12-20 12:00 ` Paolo Bonzini
2011-12-20 13:50 ` Anthony Liguori
2011-12-20 14:30 ` Paolo Bonzini
2011-12-20 20:22 ` Michael Roth
2011-12-21 12:29 ` Paolo Bonzini
2011-12-20 20:56 ` Anthony Liguori
2011-12-21 12:35 ` Paolo Bonzini
2011-12-21 14:45 ` Anthony Liguori
2011-12-21 15:39 ` Paolo Bonzini
2011-12-21 16:24 ` Anthony Liguori
2011-12-21 16:52 ` Paolo Bonzini
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 02/10] qapi: add QemuFileOutputVisitor Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 03/10] qapi: add QemuFileInputVisitor Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 04/10] savevm: move QEMUFile interfaces into qemu-file.c Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 05/10] qapi: test cases for QEMUFile input/output visitors Michael Roth
2011-10-27 17:06 ` Michael Roth [this message]
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 07/10] trace: qemu_(put|get)_(byte|buffer) events Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 08/10] trace: add trace statements for visitor interface Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 09/10] qapi: add trace statements to qapi-visit-core.c Michael Roth
2011-10-27 17:06 ` [Qemu-devel] [PATCH v2 10/10] vmstate: use visitors Michael Roth
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=1319735193-4718-7-git-send-email-mdroth@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).