[Top][All Lists]
[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 :|