[PATCH 11/12] Domain Events - test harness Test app, and infrastructure changes for an example dir Makefile.am | 2 configure.in | 3 examples/domain-events/events-c/Makefile.am | 5 examples/domain-events/events-c/event-test.c | 261 +++++++++++++++++++++++++++ libvirt.spec.in | 3 5 files changed, 272 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 073063d..d40a151 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ LCOV = lcov GENHTML = genhtml SUBDIRS = gnulib/lib include src qemud proxy docs gnulib/tests \ - python tests po + python tests po examples/domain-events/events-c ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4 diff --git a/configure.in b/configure.in index 66d271a..b7890d1 100644 --- a/configure.in +++ b/configure.in @@ -1067,7 +1067,8 @@ AC_OUTPUT(Makefile src/Makefile include/Makefile docs/Makefile \ tests/sexpr2xmldata/Makefile \ tests/xmconfigdata/Makefile \ tests/xencapsdata/Makefile \ - tests/virshdata/Makefile tests/confdata/Makefile) + tests/virshdata/Makefile tests/confdata/Makefile \ + examples/domain-events/events-c/Makefile) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Configuration summary]) diff --git a/examples/domain-events/events-c/Makefile.am b/examples/domain-events/events-c/Makefile.am new file mode 100644 index 0000000..3c63ca3 --- /dev/null +++ b/examples/domain-events/events-c/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I@top_srcdir@/include +bin_PROGRAMS = event-test +event_test_CFLAGS = $(WARN_CFLAGS) +event_test_SOURCES = event-test.c +event_test_LDADD = @top_builddir@/src/libvirt.la diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c new file mode 100644 index 0000000..55ed2f7 --- /dev/null +++ b/examples/domain-events/events-c/event-test.c @@ -0,0 +1,261 @@ +#include <config.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/poll.h> +#include <libvirt/libvirt.h> + +#define DEBUG0(fmt) printf("%s:%d :: " fmt "\n", \ + __FUNCTION__, __LINE__) +#define DEBUG(fmt, ...) printf("%s:%d: " fmt "\n", \ + __FUNCTION__, __LINE__, __VA_ARGS__) +#define STREQ(a,b) (strcmp((a),(b)) == 0) + +#ifndef ATTRIBUTE_UNUSED +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) +#endif + +/* handle globals */ +int h_fd = 0; +virEventHandleType h_event = 0; +virEventHandleCallback h_cb = NULL; +void *h_opaque = NULL; + +/* timeout globals */ +#define TIMEOUT_MS 1000 +int t_active = 0; +int t_timeout = -1; +virEventTimeoutCallback t_cb = NULL; +void *t_opaque = NULL; + + +/* Prototypes */ +const char *eventToString(int event); +int myDomainEventCallback1 (virConnectPtr conn, virDomainPtr dom, + int event, void *opaque); +int myDomainEventCallback2 (virConnectPtr conn, virDomainPtr dom, + int event, void *opaque); +int myEventAddHandleFunc (int fd, virEventHandleType event, + virEventHandleCallback cb, void *opaque); +void myEventUpdateHandleFunc(int fd, virEventHandleType event); +int myEventRemoveHandleFunc(int fd); + +int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, + void *opaque); +void myEventUpdateTimeoutFunc(int timer, int timout); +int myEventRemoveTimeoutFunc(int timer); + +int myEventHandleTypeToPollEvent(virEventHandleType events); +virEventHandleType myPollEventToEventHandleType(int events); + +void usage(const char *pname); + +/* Callback functions */ + +const char *eventToString(int event) { + const char *ret = NULL; + switch(event) { + case VIR_DOMAIN_EVENT_ADDED: + ret ="Added"; + break; + case VIR_DOMAIN_EVENT_REMOVED: + ret ="Removed"; + break; + case VIR_DOMAIN_EVENT_STARTED: + ret ="Started"; + break; + case VIR_DOMAIN_EVENT_SUSPENDED: + ret ="Suspended"; + break; + case VIR_DOMAIN_EVENT_RESUMED: + ret ="Resumed"; + break; + case VIR_DOMAIN_EVENT_STOPPED: + ret ="Stopped"; + break; + case VIR_DOMAIN_EVENT_SAVED: + ret ="Saved"; + break; + case VIR_DOMAIN_EVENT_RESTORED: + ret ="Restored"; + break; + default: + ret ="Unknown Event"; + } + return ret; +} + +int myDomainEventCallback1 (virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int event, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) %s\n", __FUNCTION__, virDomainGetName(dom), + virDomainGetID(dom), eventToString(event)); + return 0; +} + +int myDomainEventCallback2 (virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + int event, + void *opaque ATTRIBUTE_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) %s\n", __FUNCTION__, virDomainGetName(dom), + virDomainGetID(dom), eventToString(event)); + return 0; +} + + +/* EventImpl Functions */ +int myEventHandleTypeToPollEvent(virEventHandleType events) +{ + int ret = 0; + if(events & VIR_EVENT_HANDLE_READABLE) + ret |= POLLIN; + if(events & VIR_EVENT_HANDLE_WRITABLE) + ret |= POLLOUT; + if(events & VIR_EVENT_HANDLE_ERROR) + ret |= POLLERR; + if(events & VIR_EVENT_HANDLE_HANGUP) + ret |= POLLHUP; + return ret; +} + +virEventHandleType myPollEventToEventHandleType(int events) +{ + virEventHandleType ret = 0; + if(events & POLLIN) + ret |= VIR_EVENT_HANDLE_READABLE; + if(events & POLLOUT) + ret |= VIR_EVENT_HANDLE_WRITABLE; + if(events & POLLERR) + ret |= VIR_EVENT_HANDLE_ERROR; + if(events & POLLHUP) + ret |= VIR_EVENT_HANDLE_HANGUP; + return ret; +} + +int myEventAddHandleFunc(int fd, virEventHandleType event, + virEventHandleCallback cb, void *opaque) +{ + DEBUG("Add handle %d %d %p %p", fd, event, cb, opaque); + h_fd = fd; + h_event = myEventHandleTypeToPollEvent(event); + h_cb = cb; + h_opaque = opaque; + return 0; +} + +void myEventUpdateHandleFunc(int fd, virEventHandleType event) +{ + DEBUG("Updated Handle %d %d", fd, event); + h_event = myEventHandleTypeToPollEvent(event); + return; +} + +int myEventRemoveHandleFunc(int fd) +{ + DEBUG("Removed Handle %d", fd); + h_fd = 0; + return 0; +} + +int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, + void *opaque) +{ + DEBUG("Adding Timeout %d %p %p", timeout, cb, opaque); + t_active = 1; + t_timeout = timeout; + t_cb = cb; + t_opaque = opaque; + return 0; +} + +void myEventUpdateTimeoutFunc(int timer ATTRIBUTE_UNUSED, int timeout) +{ + /*DEBUG("Timeout updated %d %d", timer, timeout);*/ + t_timeout = timeout; +} + +int myEventRemoveTimeoutFunc(int timer) +{ + DEBUG("Timeout removed %d", timer); + t_active = 0; + return 0; +} + +/* main test functions */ + +void usage(const char *pname) +{ + printf("%s uri\n", pname); +} + +int main(int argc, char **argv) +{ + int run=1; + int sts; + + if(argc > 1 && STREQ(argv[1],"--help")) { + usage(argv[0]); + return -1; + } + virEventRegisterImpl( myEventAddHandleFunc, + myEventUpdateHandleFunc, + myEventRemoveHandleFunc, + myEventAddTimeoutFunc, + myEventUpdateTimeoutFunc, + myEventRemoveTimeoutFunc); + + virConnectPtr dconn = NULL; + dconn = virConnectOpen (argv[1] ? argv[1] : "qemu:///system"); + if (!dconn) { + printf("error opening\n"); + return -1; + } + + DEBUG0("Registering domain event cbs"); + + /* Add 2 callbacks to prove this works with more than just one */ + virConnectDomainEventRegister(dconn, myDomainEventCallback1, NULL); + virConnectDomainEventRegister(dconn, myDomainEventCallback2, NULL); + + while(run) { + struct pollfd pfd = { .fd = h_fd, + .events = h_event, + .revents = 0}; + + sts = poll(&pfd, 1, TIMEOUT_MS); + + /* We are assuming timeout of 0 here - so execute every time */ + if(t_cb && t_active) + t_cb(t_timeout,t_opaque); + + if (sts == 0) { + /* DEBUG0("Poll timeout"); */ + continue; + } + if (sts < 0 ) { + DEBUG0("Poll failed"); + continue; + } + if ( pfd.revents & POLLHUP ) { + DEBUG0("Reset by peer"); + return -1; + } + + if(h_cb) { + h_cb(h_fd, + myPollEventToEventHandleType(pfd.revents & h_event), + h_opaque); + } + + } + + if( dconn && virConnectClose(dconn)<0 ) { + printf("error closing\n"); + } + printf("done\n"); + return 0; +} + diff --git a/libvirt.spec.in b/libvirt.spec.in index cfd4a66..450d907 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -249,6 +249,9 @@ rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-python-%{version} rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf %endif +# We don't want examples in the built rpm +rm -f $RPM_BUILD_ROOT%{_bindir}/event-test + %clean rm -fr %{buildroot}
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list