qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 1/2] APIs to capture character device data
Date: Wed, 1 Jul 2009 17:26:51 +0100	[thread overview]
Message-ID: <20090701162651.GC24296@redhat.com> (raw)
In-Reply-To: <20090701162114.GB24296@redhat.com>

commit b6d541a02ffa3dbff3f0e6a27d7441ff24481185
Author: Daniel P. Berrange <berrange@redhat.com>
Date:   Wed Jul 1 14:21:17 2009 +0100

    Add APIs for capturing data written to character devices, and
    for receiving notification of creation & deletion of character
    devices

diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..bee309c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -106,6 +106,23 @@
 /***********************************************************/
 /* character device */
 
+struct CharCaptureState {
+    struct CharCaptureOps *ops;
+    void *opaque;
+
+    TAILQ_ENTRY(CharCaptureState) next;
+};
+
+struct CharMonitorState {
+    struct CharMonitorOps *ops;
+    void *opaque;
+
+    TAILQ_ENTRY(CharMonitorState) next;
+};
+
+static TAILQ_HEAD(CharMonitorStateHead, CharMonitorState) charmonitors =
+    TAILQ_HEAD_INITIALIZER(charmonitors);
+
 static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
     TAILQ_HEAD_INITIALIZER(chardevs);
 static int initial_reset_issued;
@@ -146,6 +163,13 @@ void qemu_chr_initial_reset(void)
 
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
 {
+    CharCaptureState *cap;
+
+    TAILQ_FOREACH(cap, &s->capture, next) {
+	if (cap->ops->capture)
+	    (*cap->ops->capture)(cap->opaque, buf, len);
+    }
+
     return s->chr_write(s, buf, len);
 }
 
@@ -2215,17 +2239,41 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
     }
 
     if (chr) {
+	CharMonitorState *mon;
+
         if (!chr->filename)
             chr->filename = qemu_strdup(filename);
         chr->init = init;
         chr->label = qemu_strdup(label);
         TAILQ_INSERT_TAIL(&chardevs, chr, next);
+
+	TAILQ_INIT(&chr->capture);
+
+	TAILQ_FOREACH(mon, &charmonitors, next) {
+	    if (mon->ops->opened)
+		(*mon->ops->opened)(chr, mon->opaque);
+	}
     }
     return chr;
 }
 
 void qemu_chr_close(CharDriverState *chr)
 {
+    CharMonitorState *mon;
+    CharCaptureState *cap, *captmp;
+
+    TAILQ_FOREACH_SAFE(cap, &chr->capture, next, captmp) {
+	if (cap->ops->destroy)
+	    (*cap->ops->destroy)(cap->opaque);
+
+	qemu_free(cap);
+    }
+
+    TAILQ_FOREACH(mon, &charmonitors, next) {
+	if (mon->ops->closing)
+	    (*mon->ops->closing)(chr, mon->opaque);
+    }
+
     TAILQ_REMOVE(&chardevs, chr, next);
     if (chr->chr_close)
         chr->chr_close(chr);
@@ -2242,3 +2290,77 @@ void qemu_chr_info(Monitor *mon)
         monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
     }
 }
+
+
+
+CharCaptureState *qemu_chr_add_capture(CharDriverState *s,
+				       struct CharCaptureOps *ops,
+				       void *opaque)
+{
+    CharCaptureState *cap;
+
+    cap = qemu_mallocz(sizeof(*cap));
+
+    cap->ops = ops;
+    cap->opaque = opaque;
+
+    TAILQ_INSERT_TAIL(&s->capture, cap, next);
+
+    return cap;
+}
+
+
+void qemu_chr_del_capture(CharDriverState *s,
+			  CharCaptureState *cap)
+{
+    TAILQ_REMOVE(&s->capture, cap, next);
+
+    qemu_free(cap);
+}
+
+CharMonitorState *qemu_chr_add_monitor(struct CharMonitorOps *ops,
+				       void *opaque)
+{
+    CharMonitorState *mon;
+
+    mon = qemu_mallocz(sizeof(*mon));
+
+    mon->ops = ops;
+    mon->opaque = opaque;
+
+    TAILQ_INSERT_TAIL(&charmonitors, mon, next);
+
+    return mon;
+}
+
+
+void qemu_chr_remove_monitor(CharMonitorState *mon)
+{
+    TAILQ_REMOVE(&charmonitors, mon, next);
+
+    qemu_free(mon);
+}
+
+
+int qemu_chr_iterate(qemu_chr_iterator iter,
+		     void *opaque)
+{
+    CharDriverState *chr;
+
+    TAILQ_FOREACH(chr, &chardevs, next) {
+	if ((*iter)(chr, opaque) < 0)
+	    return -1;
+    }
+    return 0;
+}
+
+CharDriverState *qemu_chr_fetch(const char *label)
+{
+    CharDriverState *chr;
+
+    TAILQ_FOREACH(chr, &chardevs, next) {
+	if (strcmp(chr->label, label) == 0)
+	    return chr;
+    }
+    return NULL;
+}
diff --git a/qemu-char.h b/qemu-char.h
index e1aa8db..94613e7 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -46,6 +46,19 @@ typedef struct {
 
 typedef void IOEventHandler(void *opaque, int event);
 
+struct CharCaptureOps {
+    void (*capture) (void *opaque, const void *buf, int size);
+    void (*destroy) (void *opaque);
+};
+
+struct CharMonitorOps {
+    void (*opened) (CharDriverState *s, void *opaque);
+    void (*closing) (CharDriverState *s, void *opaque);
+};
+
+typedef struct CharMonitorState CharMonitorState;
+typedef struct CharCaptureState CharCaptureState;
+
 struct CharDriverState {
     void (*init)(struct CharDriverState *s);
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
@@ -64,6 +77,8 @@ struct CharDriverState {
     char *label;
     char *filename;
     TAILQ_ENTRY(CharDriverState) next;
+
+    TAILQ_HEAD(CharCaptureStateHead, CharCaptureState) capture;
 };
 
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
@@ -84,6 +99,48 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
 void qemu_chr_accept_input(CharDriverState *s);
 void qemu_chr_info(Monitor *mon);
 
+/*
+ * Register to capture all data written to the character
+ * device.
+ */
+CharCaptureState *qemu_chr_add_capture(CharDriverState *s,
+				       struct CharCaptureOps *ops,
+				       void *opaque);
+
+/*
+ * Unregister a capture register on the character device
+ */
+void qemu_chr_del_capture(CharDriverState *s,
+			  CharCaptureState *c);
+
+
+/*
+ * Register to get notifications of the creation and deletion
+ * of character devices
+ */
+CharMonitorState *qemu_chr_add_monitor(struct CharMonitorOps *ops,
+				       void *opaque);
+/*
+ * Unregister notification of creation and deletion of
+ * character devices
+ */
+void qemu_chr_del_monitor(CharMonitorState *m);
+
+
+/*
+ * Iterate over all existing character devices
+ */
+typedef int (*qemu_chr_iterator)(CharDriverState *s,
+				 void *opaque);
+int qemu_chr_iterate(qemu_chr_iterator iter,
+		     void *opaque);
+
+/*
+ * Fetch a character device based on its assigned label
+ */
+CharDriverState *qemu_chr_fetch(const char *label);
+
+
 extern int term_escape_char;
 
 /* async I/O support */


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

  reply	other threads:[~2009-07-01 16:26 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-01 16:21 [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:26 ` Daniel P. Berrange [this message]
2009-07-01 16:27 ` [Qemu-devel] [PATCH 2/2] VNC char device data stream tunnelling Daniel P. Berrange
2009-07-01 18:44   ` Anthony Liguori
2009-07-01 16:32 ` [Qemu-devel] [PATCH 0/2] Tunnel character device data over VNC (v1) Daniel P. Berrange
2009-07-01 16:42 ` Gerd Hoffmann
2009-07-01 16:50   ` Daniel P. Berrange
2009-07-01 17:30     ` Gerd Hoffmann
2009-07-01 18:50       ` Daniel P. Berrange
2009-07-01 19:27         ` Gerd Hoffmann
2009-07-01 18:51       ` Anthony Liguori
2009-07-01 19:41         ` Gerd Hoffmann
2009-07-01 19:59           ` Anthony Liguori
2009-07-01 20:56             ` Gerd Hoffmann
2009-07-01 21:32               ` Anthony Liguori
2009-07-01 22:46                 ` Gerd Hoffmann
2009-07-02  2:30               ` Jamie Lokier
2009-07-01 21:07             ` Daniel P. Berrange
2009-07-01 18:36 ` Anthony Liguori
2009-07-01 18:44   ` Daniel P. Berrange
2009-07-01 18:47     ` Anthony Liguori
2009-07-01 18:52       ` Daniel P. Berrange
2009-07-01 19:11         ` Anthony Liguori
2009-07-01 19:27           ` Daniel P. Berrange

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=20090701162651.GC24296@redhat.com \
    --to=berrange@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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).