Ejemplo n.º 1
0
bool Fence::FenceAwaiter::await_suspend(T awaitingCoroutine) noexcept {
	Scheduler* scheduler = nullptr;
	if constexpr (std::is_base_of_v<SchedulablePromiseTag, std::decay_t<decltype(awaitingCoroutine.promise())>>) {
		scheduler = static_cast<const SchedulablePromiseTag&>(awaitingCoroutine.promise()).m_scheduler;
	}
	return await_suspend(std::experimental::coroutine_handle<>(awaitingCoroutine), scheduler);
}
Ejemplo n.º 2
0
static int suspend_evtchn_init(int xc, int domid)
{
    struct xs_handle *xs;
    char path[128];
    char *portstr;
    unsigned int plen;
    int port;
    int rc;

    si.xce = -1;
    si.suspend_evtchn = -1;

    xs = xs_daemon_open();
    if (!xs) {
        warnx("failed to get xenstore handle");
        return -1;
    }
    sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid);
    portstr = xs_read(xs, XBT_NULL, path, &plen);
    xs_daemon_close(xs);

    if (!portstr || !plen) {
        warnx("could not read suspend event channel");
        return -1;
    }

    port = atoi(portstr);
    free(portstr);

    si.xce = xc_evtchn_open();
    if (si.xce < 0) {
        warnx("failed to open event channel handle");
        goto cleanup;
    }

    si.suspend_evtchn = xc_evtchn_bind_interdomain(si.xce, domid, port);
    if (si.suspend_evtchn < 0) {
        warnx("failed to bind suspend event channel: %d", si.suspend_evtchn);
        goto cleanup;
    }

    rc = xc_domain_subscribe_for_suspend(xc, domid, port);
    if (rc < 0) {
        warnx("failed to subscribe to domain: %d", rc);
        goto cleanup;
    }

    /* event channel is pending immediately after binding */
    await_suspend();

    return 0;

  cleanup:
    suspend_evtchn_release();

    return -1;
}
Ejemplo n.º 3
0
/**
 * Issue a suspend request to a dedicated event channel in the guest, and
 * receive the acknowledgement from the subscribe event channel. */
static int evtchn_suspend(void)
{
    int rc;

    rc = xc_evtchn_notify(si.xce, si.suspend_evtchn);
    if (rc < 0) {
        warnx("failed to notify suspend request channel: %d", rc);
        return 0;
    }

    if (await_suspend() < 0) {
        warnx("suspend failed");
        return 0;
    }

    /* notify xend that it can do device migration */
    printf("suspended\n");
    fflush(stdout);

    return 1;
}