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; }
/* Set up event channel used to signal a guest to suspend itself */ static int setup_suspend_evtchn(checkpoint_state* s) { int port; port = xs_suspend_evtchn_port(s->domid); if (port < 0) { s->errstr = "failed to read suspend event channel"; return -1; } s->suspend_evtchn = xc_suspend_evtchn_init(s->xch, s->xce, s->domid, port); if (s->suspend_evtchn < 0) { s->errstr = "failed to bind suspend event channel"; return -1; } fprintf(stderr, "bound to suspend event channel %u:%d as %d\n", s->domid, port, s->suspend_evtchn); return 0; }