int libvchan_is_open(libvchan_t *ctrl) { int ret; struct evtchn_status evst; ret = libxenvchan_is_open(ctrl->xenvchan); if (ret == 2) { if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain)) return VCHAN_DISCONNECTED; return VCHAN_WAITING; } if (!ret) return VCHAN_DISCONNECTED; /* slow check in case of domain destroy */ evst.port = ctrl->xenvchan->event_port; evst.dom = DOMID_SELF; if (xc_evtchn_status(ctrl->xc_handle, &evst)) { perror("xc_evtchn_status"); return VCHAN_DISCONNECTED; } if (evst.status != EVTCHNSTAT_interdomain) { if (!ctrl->xenvchan->is_server) ctrl->xenvchan->ring->srv_live = 0; return VCHAN_DISCONNECTED; } return VCHAN_CONNECTED; }
int main(int argc, char **argv) { xc_interface *xch; int domid, port, rc; xc_evtchn_status_t status; domid = (argc > 1) ? strtol(argv[1], NULL, 10) : 0; xch = xc_interface_open(0,0,0); if ( !xch ) errx(1, "failed to open control interface"); for ( port = 0; ; port++ ) { status.dom = domid; status.port = port; rc = xc_evtchn_status(xch, &status); if ( rc < 0 ) break; if ( status.status == EVTCHNSTAT_closed ) continue; printf("%4d: VCPU %u: ", port, status.vcpu); switch ( status.status ) { case EVTCHNSTAT_unbound: printf("Interdomain (Waiting connection) - Remote Domain %u", status.u.unbound.dom); break; case EVTCHNSTAT_interdomain: printf("Interdomain (Connected) - Remote Domain %u, Port %u", status.u.interdomain.dom, status.u.interdomain.port); break; case EVTCHNSTAT_pirq: printf("Physical IRQ %u", status.u.pirq); break; case EVTCHNSTAT_virq: printf("Virtual IRQ %u", status.u.virq); break; case EVTCHNSTAT_ipi: printf("IPI"); break; default: printf("Unknown"); break; } printf("\n"); } xc_interface_close(xch); return 0; }
int libvchan__check_domain_alive(xc_interface *xc_handle, int dom) { struct evtchn_status evst; int ret; /* check if domain still alive */ evst.dom = dom; /* xc_evtchn_status will return different error depending on * existence of "source" domain: * ESRCH - domain don't exists * EINVAL/EPERM - domain exsts but port is invalid / cannot check * its status */ evst.port = -1; ret = xc_evtchn_status(xc_handle, &evst); if (ret == -1 && errno == ESRCH) { return 0; } return 1; }