forked from altcloud/fence-virt
Add capabilities to virt-serial
- detect existing (running) domains for registration of vmchannel (serial) sockets - detect domains being stopped so we can unregister the socket(s) for that domain - ran through Lindent for indentation consistency Signed-off-by: Lon Hohberger <lon@users.sourceforge.net>
This commit is contained in:
parent
21627e26aa
commit
5a21922728
@ -4,6 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/poll.h>
|
||||
@ -28,314 +29,437 @@ void *h_opaque = NULL;
|
||||
#define TIMEOUT_MS 1000
|
||||
int t_active = 0;
|
||||
int t_timeout = -1;
|
||||
int dom_active = 0;
|
||||
virEventTimeoutCallback t_cb = NULL;
|
||||
virFreeCallback t_ff = NULL;
|
||||
void *t_opaque = NULL;
|
||||
|
||||
virDomainPtr mojaDomain = NULL;
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
const char *eventToString(int event);
|
||||
int myDomainEventCallback1 (virConnectPtr conn, virDomainPtr dom,
|
||||
int event, int detail, void *opaque);
|
||||
int myEventAddHandleFunc (int fd, int event,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff);
|
||||
int myDomainEventCallback1(virConnectPtr conn, virDomainPtr dom,
|
||||
int event, int detail, void *opaque);
|
||||
int myEventAddHandleFunc(int fd, int event,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque, virFreeCallback ff);
|
||||
void myEventUpdateHandleFunc(int watch, int event);
|
||||
int myEventRemoveHandleFunc(int watch);
|
||||
int myEventRemoveHandleFunc(int watch);
|
||||
|
||||
int myEventAddTimeoutFunc(int timeout,
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff);
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque, virFreeCallback ff);
|
||||
void myEventUpdateTimeoutFunc(int timer, int timout);
|
||||
int myEventRemoveTimeoutFunc(int timer);
|
||||
static int registerDomain(virDomainPtr mojaDomain);
|
||||
|
||||
int myEventHandleTypeToPollEvent(virEventHandleType events);
|
||||
virEventHandleType myPollEventToEventHandleType(int events);
|
||||
|
||||
void usage(const char *pname);
|
||||
|
||||
int myDomainEventCallback1 (virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
int event,
|
||||
int detail,
|
||||
void *opaque)
|
||||
struct domain_info {
|
||||
virDomainPtr dom;
|
||||
virDomainEventType event;
|
||||
};
|
||||
|
||||
int
|
||||
myDomainEventCallback1(virConnectPtr conn,
|
||||
virDomainPtr dom, int event, int detail, void *opaque)
|
||||
{
|
||||
if (event == VIR_DOMAIN_EVENT_STARTED) {
|
||||
virDomainRef(dom);
|
||||
mojaDomain = dom;
|
||||
struct domain_info *dinfo = (struct domain_info *) opaque;
|
||||
|
||||
dom_active = 1;
|
||||
}
|
||||
if (event == VIR_DOMAIN_EVENT_STARTED ||
|
||||
event == VIR_DOMAIN_EVENT_STOPPED) {
|
||||
virDomainRef(dom);
|
||||
dinfo->dom = dom;
|
||||
dinfo->event = event;
|
||||
} else {
|
||||
dinfo->event = VIR_DOMAIN_EVENT_UNDEFINED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myFreeFunc(void *opaque)
|
||||
static void
|
||||
myFreeFunc(void *opaque)
|
||||
{
|
||||
char *str = opaque;
|
||||
printf("%s: Freeing [%s]\n", __func__, str);
|
||||
free(str);
|
||||
char *str = opaque;
|
||||
printf("%s: Freeing [%s]\n", __func__, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
|
||||
/* EventImpl Functions */
|
||||
int myEventHandleTypeToPollEvent(virEventHandleType events)
|
||||
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;
|
||||
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
|
||||
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;
|
||||
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, int event,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff)
|
||||
int
|
||||
myEventAddHandleFunc(int fd, int event,
|
||||
virEventHandleCallback cb,
|
||||
void *opaque, virFreeCallback ff)
|
||||
{
|
||||
DEBUG("Add handle %d %d %p %p", fd, event, cb, opaque);
|
||||
h_fd = fd;
|
||||
h_event = myEventHandleTypeToPollEvent(event);
|
||||
h_cb = cb;
|
||||
h_ff = ff;
|
||||
h_opaque = opaque;
|
||||
return 0;
|
||||
DEBUG("Add handle %d %d %p %p", fd, event, cb, opaque);
|
||||
h_fd = fd;
|
||||
h_event = myEventHandleTypeToPollEvent(event);
|
||||
h_cb = cb;
|
||||
h_ff = ff;
|
||||
h_opaque = opaque;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void myEventUpdateHandleFunc(int fd, int event)
|
||||
void
|
||||
myEventUpdateHandleFunc(int fd, int event)
|
||||
{
|
||||
DEBUG("Updated Handle %d %d", fd, event);
|
||||
h_event = myEventHandleTypeToPollEvent(event);
|
||||
return;
|
||||
DEBUG("Updated Handle %d %d", fd, event);
|
||||
h_event = myEventHandleTypeToPollEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
int myEventRemoveHandleFunc(int fd)
|
||||
int
|
||||
myEventRemoveHandleFunc(int fd)
|
||||
{
|
||||
DEBUG("Removed Handle %d", fd);
|
||||
h_fd = 0;
|
||||
if (h_ff)
|
||||
(h_ff)(h_opaque);
|
||||
return 0;
|
||||
DEBUG("Removed Handle %d", fd);
|
||||
h_fd = 0;
|
||||
if (h_ff)
|
||||
(h_ff) (h_opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int myEventAddTimeoutFunc(int timeout,
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque,
|
||||
virFreeCallback ff)
|
||||
int
|
||||
myEventAddTimeoutFunc(int timeout,
|
||||
virEventTimeoutCallback cb,
|
||||
void *opaque, virFreeCallback ff)
|
||||
{
|
||||
DEBUG("Adding Timeout %d %p %p", timeout, cb, opaque);
|
||||
t_active = 1;
|
||||
t_timeout = timeout;
|
||||
t_cb = cb;
|
||||
t_ff = ff;
|
||||
t_opaque = opaque;
|
||||
return 0;
|
||||
DEBUG("Adding Timeout %d %p %p", timeout, cb, opaque);
|
||||
t_active = 1;
|
||||
t_timeout = timeout;
|
||||
t_cb = cb;
|
||||
t_ff = ff;
|
||||
t_opaque = opaque;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void myEventUpdateTimeoutFunc(int timer, int timeout)
|
||||
void
|
||||
myEventUpdateTimeoutFunc(int timer, int timeout)
|
||||
{
|
||||
/*DEBUG("Timeout updated %d %d", timer, timeout);*/
|
||||
t_timeout = timeout;
|
||||
/*DEBUG("Timeout updated %d %d", timer, timeout); */
|
||||
t_timeout = timeout;
|
||||
}
|
||||
|
||||
int myEventRemoveTimeoutFunc(int timer)
|
||||
int
|
||||
myEventRemoveTimeoutFunc(int timer)
|
||||
{
|
||||
DEBUG("Timeout removed %d", timer);
|
||||
t_active = 0;
|
||||
if (t_ff)
|
||||
(t_ff)(t_opaque);
|
||||
return 0;
|
||||
DEBUG("Timeout removed %d", timer);
|
||||
t_active = 0;
|
||||
if (t_ff)
|
||||
(t_ff) (t_opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* main test functions */
|
||||
|
||||
void usage(const char *pname)
|
||||
void
|
||||
usage(const char *pname)
|
||||
{
|
||||
printf("%s uri\n", pname);
|
||||
printf("%s uri\n", pname);
|
||||
}
|
||||
|
||||
int run = 1;
|
||||
|
||||
static void stop(int sig)
|
||||
static void
|
||||
stop(int sig)
|
||||
{
|
||||
printf("Exiting on signal %d\n", sig);
|
||||
run = 0;
|
||||
printf("Exiting on signal %d\n", sig);
|
||||
run = 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static int
|
||||
domainStarted(virDomainPtr mojaDomain)
|
||||
{
|
||||
int sts;
|
||||
int callback1ret = -1;
|
||||
int callback2ret = -1;
|
||||
struct sigaction action_stop = {
|
||||
.sa_handler = stop
|
||||
};
|
||||
char dom_uuid[42];
|
||||
char *xml;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur, devices, child, serial;
|
||||
xmlAttrPtr attr, attr_mode, attr_path;
|
||||
|
||||
if(argc > 1 && STREQ(argv[1],"--help")) {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (!mojaDomain)
|
||||
return -1;
|
||||
|
||||
virEventRegisterImpl( myEventAddHandleFunc,
|
||||
myEventUpdateHandleFunc,
|
||||
myEventRemoveHandleFunc,
|
||||
myEventAddTimeoutFunc,
|
||||
myEventUpdateTimeoutFunc,
|
||||
myEventRemoveTimeoutFunc);
|
||||
printf("NAME: %s\n", virDomainGetName(mojaDomain));
|
||||
virDomainGetUUIDString(mojaDomain, dom_uuid);
|
||||
printf("UUID: %s\n", dom_uuid);
|
||||
|
||||
virConnectPtr dconn = NULL;
|
||||
dconn = virConnectOpen (argv[1] ? argv[1] : NULL);
|
||||
if (!dconn) {
|
||||
printf("error opening\n");
|
||||
return -1;
|
||||
}
|
||||
xml = virDomainGetXMLDesc(mojaDomain, 0);
|
||||
// printf("%s\n", xml);
|
||||
|
||||
sigaction(SIGTERM, &action_stop, NULL);
|
||||
sigaction(SIGINT, &action_stop, NULL);
|
||||
// @todo: free mojaDomain
|
||||
|
||||
DEBUG0("Registering domain event cbs");
|
||||
// parseXML output
|
||||
doc = xmlParseMemory(xml, strlen(xml));
|
||||
cur = xmlDocGetRootElement(doc);
|
||||
|
||||
/* Add 2 callbacks to prove this works with more than just one */
|
||||
callback1ret = virConnectDomainEventRegister(dconn, myDomainEventCallback1,
|
||||
strdup("callback 1"), myFreeFunc);
|
||||
if (cur == NULL) {
|
||||
fprintf(stderr, "Empty doc\n");
|
||||
xmlFreeDoc(doc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((callback1ret == 0)) {
|
||||
while(run) {
|
||||
struct pollfd pfd = { .fd = h_fd,
|
||||
.events = h_event,
|
||||
.revents = 0};
|
||||
if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
|
||||
printf("no domain?\n");
|
||||
xmlFreeDoc(doc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sts = poll(&pfd, 1, TIMEOUT_MS);
|
||||
devices = cur->xmlChildrenNode;
|
||||
for (devices = cur->xmlChildrenNode; devices != NULL;
|
||||
devices = devices->next) {
|
||||
if (xmlStrcmp(devices->name, (const xmlChar *) "devices")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mojaDomain && dom_active) {
|
||||
printf("NAME: %s\n", virDomainGetName(mojaDomain));
|
||||
dom_active = 0;
|
||||
|
||||
printf("%s\n", virDomainGetXMLDesc(mojaDomain, 0));
|
||||
char *xml = virDomainGetXMLDesc(mojaDomain, 0);
|
||||
|
||||
// @todo: free mojaDomain
|
||||
for (child = devices->xmlChildrenNode; child != NULL;
|
||||
child = child->next) {
|
||||
if (xmlStrcmp(child->name, (const xmlChar *) "serial")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parseXML output
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur;
|
||||
attr = xmlHasProp(child, "type");
|
||||
if (attr == NULL)
|
||||
continue;
|
||||
|
||||
doc = xmlParseMemory(xml, strlen(xml));
|
||||
cur = xmlDocGetRootElement(doc);
|
||||
|
||||
if (cur == NULL) {
|
||||
fprintf(stderr, "Empty doc\n");
|
||||
xmlFreeDoc(doc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
|
||||
xmlNodePtr devices = cur->xmlChildrenNode;
|
||||
if (xmlStrcmp
|
||||
(attr->children->content,
|
||||
(const xmlChar *) "unix")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (devices != NULL) {
|
||||
if (!xmlStrcmp(devices->name, (const xmlChar *) "devices")) {
|
||||
xmlNodePtr child = devices->xmlChildrenNode;
|
||||
while (child != NULL) {
|
||||
if (!xmlStrcmp(child->name, (const xmlChar *) "serial")) {
|
||||
xmlAttrPtr attr = xmlHasProp(child, "type");
|
||||
for (serial = child->xmlChildrenNode; serial != NULL;
|
||||
serial = serial->next) {
|
||||
if (xmlStrcmp
|
||||
(serial->name,
|
||||
(const xmlChar *) "source")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attr == NULL) continue;
|
||||
attr_mode = xmlHasProp(serial, "mode");
|
||||
attr_path = xmlHasProp(serial, "path");
|
||||
|
||||
if (!xmlStrcmp(attr->children->content, (const xmlChar *) "unix")) {
|
||||
xmlNodePtr serial = child->xmlChildrenNode;
|
||||
while (serial != NULL) {
|
||||
if (!xmlStrcmp(serial->name, (const xmlChar *) "source")) {
|
||||
xmlAttrPtr attr_mode = xmlHasProp(serial, "mode");
|
||||
xmlAttrPtr attr_path = xmlHasProp(serial, "path");
|
||||
if ((attr_path != NULL) &&
|
||||
(attr_mode != NULL) &&
|
||||
(!xmlStrcmp(attr_mode->children->content,
|
||||
(const xmlChar *) "bind"))) {
|
||||
printf(">> REGISTER >> %s %s\n",
|
||||
dom_uuid,
|
||||
attr_path->children->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((attr_path != NULL) && (attr_mode != NULL) && (!xmlStrcmp(attr_mode->children->content, (const xmlChar *) "bind"))) {
|
||||
printf(">> IFILE >> %s\n", attr_path->children->content);
|
||||
}
|
||||
}
|
||||
|
||||
serial = serial->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
devices = devices->next;
|
||||
}
|
||||
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 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(0,
|
||||
h_fd,
|
||||
myPollEventToEventHandleType(pfd.revents & h_event),
|
||||
h_opaque);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
DEBUG0("Deregistering event handlers");
|
||||
virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
|
||||
|
||||
}
|
||||
|
||||
DEBUG0("Closing connection");
|
||||
if( dconn && virConnectClose(dconn)<0 ) {
|
||||
printf("error closing\n");
|
||||
}
|
||||
|
||||
printf("done\n");
|
||||
return 0;
|
||||
xmlFreeDoc(doc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
registerExisting(virConnectPtr vp)
|
||||
{
|
||||
int *d_ids = NULL;
|
||||
int d_count, x;
|
||||
virDomainPtr dom;
|
||||
virDomainInfo d_info;
|
||||
|
||||
errno = EINVAL;
|
||||
if (!vp)
|
||||
return NULL;
|
||||
|
||||
d_count = virConnectNumOfDomains(vp);
|
||||
if (d_count <= 0) {
|
||||
if (d_count == 0) {
|
||||
/* Successful, but no domains running */
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
d_ids = malloc(sizeof (int) * d_count);
|
||||
if (!d_ids)
|
||||
goto out_fail;
|
||||
|
||||
if (virConnectListDomains(vp, d_ids, d_count) < 0)
|
||||
goto out_fail;
|
||||
|
||||
/* Ok, we have the domain IDs - let's get their names and states */
|
||||
for (x = 0; x < d_count; x++) {
|
||||
dom = virDomainLookupByID(vp, d_ids[x]);
|
||||
if (!dom) {
|
||||
/* XXX doom */
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (virDomainGetInfo(dom, &d_info) < 0) {
|
||||
/* XXX no info for the domain?!! */
|
||||
virDomainFree(dom);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (d_info.state != VIR_DOMAIN_SHUTOFF &&
|
||||
d_info.state != VIR_DOMAIN_CRASHED)
|
||||
domainStarted(dom);
|
||||
|
||||
virDomainFree(dom);
|
||||
}
|
||||
|
||||
out_fail:
|
||||
free(d_ids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
domainStopped(virDomainPtr mojaDomain)
|
||||
{
|
||||
char dom_uuid[42];
|
||||
char *xml;
|
||||
|
||||
if (!mojaDomain)
|
||||
return -1;
|
||||
|
||||
printf("NAME: %s\n", virDomainGetName(mojaDomain));
|
||||
virDomainGetUUIDString(mojaDomain, dom_uuid);
|
||||
printf("UUID: %s\n", dom_uuid);
|
||||
|
||||
printf(">> UNREGISTER >> %s\n", dom_uuid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
virConnectPtr dconn = NULL;
|
||||
struct domain_info dinfo;
|
||||
struct sigaction action_stop = {.sa_handler = stop };
|
||||
|
||||
int sts;
|
||||
int callback1ret = -1;
|
||||
int callback2ret = -1;
|
||||
|
||||
if (argc > 1 && STREQ(argv[1], "--help")) {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virEventRegisterImpl(myEventAddHandleFunc,
|
||||
myEventUpdateHandleFunc,
|
||||
myEventRemoveHandleFunc,
|
||||
myEventAddTimeoutFunc,
|
||||
myEventUpdateTimeoutFunc,
|
||||
myEventRemoveTimeoutFunc);
|
||||
|
||||
dconn = virConnectOpen(argv[1] ? argv[1] : NULL);
|
||||
if (!dconn) {
|
||||
printf("error opening\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sigaction(SIGTERM, &action_stop, NULL);
|
||||
sigaction(SIGINT, &action_stop, NULL);
|
||||
|
||||
DEBUG0("Registering domain event cbs");
|
||||
|
||||
registerExisting(dconn);
|
||||
|
||||
/* Add 2 callbacks to prove this works with more than just one */
|
||||
memset(&dinfo, 0, sizeof (dinfo));
|
||||
dinfo.event = VIR_DOMAIN_EVENT_UNDEFINED;
|
||||
callback1ret =
|
||||
virConnectDomainEventRegister(dconn, myDomainEventCallback1,
|
||||
&dinfo, NULL);
|
||||
|
||||
if ((callback1ret == 0)) {
|
||||
while (run) {
|
||||
struct pollfd pfd = {.fd = h_fd,
|
||||
.events = h_event,
|
||||
.revents = 0
|
||||
};
|
||||
|
||||
if (dinfo.event == VIR_DOMAIN_EVENT_STARTED) {
|
||||
domainStarted(dinfo.dom);
|
||||
virDomainFree(dinfo.dom);
|
||||
dinfo.dom = NULL;
|
||||
dinfo.event = VIR_DOMAIN_EVENT_UNDEFINED;
|
||||
} else if (dinfo.event == VIR_DOMAIN_EVENT_STOPPED) {
|
||||
domainStopped(dinfo.dom);
|
||||
virDomainFree(dinfo.dom);
|
||||
dinfo.dom = NULL;
|
||||
dinfo.event = VIR_DOMAIN_EVENT_UNDEFINED;
|
||||
}
|
||||
|
||||
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(0,
|
||||
h_fd,
|
||||
myPollEventToEventHandleType(pfd.
|
||||
revents &
|
||||
h_event),
|
||||
h_opaque);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DEBUG0("Deregistering event handlers");
|
||||
virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
|
||||
|
||||
}
|
||||
|
||||
DEBUG0("Closing connection");
|
||||
if (dconn && virConnectClose(dconn) < 0) {
|
||||
printf("error closing\n");
|
||||
}
|
||||
|
||||
printf("done\n");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user