qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/2] APIs to capture character device data


From: Daniel P. Berrange
Subject: Re: [Qemu-devel] [PATCH 1/2] APIs to capture character device data
Date: Wed, 1 Jul 2009 17:26:51 +0100
User-agent: Mutt/1.4.1i

commit b6d541a02ffa3dbff3f0e6a27d7441ff24481185
Author: Daniel P. Berrange <address@hidden>
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 via email to

[Prev in Thread] Current Thread [Next in Thread]