int xc_suspend_evtchn_init(xc_interface *xch, xc_evtchn *xce, int domid, int port) { int rc, suspend_evtchn = -1; if (lock_suspend_event(xch, domid)) return -EINVAL; suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); if (suspend_evtchn < 0) { ERROR("failed to bind suspend event channel: %d", suspend_evtchn); goto cleanup; } rc = xc_domain_subscribe_for_suspend(xch, domid, port); if (rc < 0) { ERROR("failed to subscribe to domain: %d", rc); goto cleanup; } /* event channel is pending immediately after binding */ xc_await_suspend(xch, xce, suspend_evtchn); return suspend_evtchn; cleanup: xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn); return -1; }
int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce, int domid, int port, int *lockfd) { int suspend_evtchn; suspend_evtchn = xc_suspend_evtchn_init_sane(xch, xce, domid, port, lockfd); if (suspend_evtchn < 0) return suspend_evtchn; /* event channel is pending immediately after binding */ xc_await_suspend(xch, xce, suspend_evtchn); return suspend_evtchn; }
static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid, int *evtchn, int *lockfd) { int port, rc, suspend_evtchn = -1; *lockfd = -1; if (!evtchn) return -1; port = xs_suspend_evtchn_port(domid); if (port < 0) { fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid); goto failed; } suspend_evtchn = xc_suspend_evtchn_init_exclusive(xch, xce, domid, port, lockfd); if (suspend_evtchn < 0) { fprintf(stderr, "Suspend evtchn initialization failed\n"); goto failed; } *evtchn = suspend_evtchn; rc = xc_evtchn_notify(xce, suspend_evtchn); if (rc < 0) { fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc); goto failed; } if (xc_await_suspend(xch, xce, suspend_evtchn) < 0) { fprintf(stderr, "Suspend Failed\n"); goto failed; } return 0; failed: if (suspend_evtchn != -1) xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn, lockfd); return -1; }