Esempio n. 1
0
void libxl__colo_restore_setup(libxl__egc *egc,
                               libxl__colo_restore_state *crs)
{
    libxl__domain_create_state *dcs = CONTAINER_OF(crs, *dcs, crs);
    libxl__colo_restore_checkpoint_state *crcs;
    int rc = ERROR_FAIL;

    /* Convenience aliases */
    libxl__srm_restore_autogen_callbacks *const callbacks =
        &dcs->srs.shs.callbacks.restore.a;
    const int domid = crs->domid;

    STATE_AO_GC(crs->ao);

    GCNEW(crcs);
    crs->crcs = crcs;
    crcs->crs = crs;
    crs->qdisk_setuped = false;
    crs->qdisk_used = false;
    if (dcs->colo_proxy_script)
        crs->colo_proxy_script = libxl__strdup(gc, dcs->colo_proxy_script);
    else
        crs->colo_proxy_script = GCSPRINTF("%s/colo-proxy-setup",
                                           libxl__xen_script_dir_path());

    /* setup dsps */
    crcs->dsps.ao = ao;
    crcs->dsps.domid = domid;
    if (init_dsps(&crcs->dsps))
        goto out;

    callbacks->postcopy = libxl__colo_restore_domain_resume_callback;
    callbacks->wait_checkpoint = libxl__colo_restore_domain_wait_checkpoint_callback;
    callbacks->suspend = libxl__colo_restore_domain_suspend_callback;
    callbacks->checkpoint = libxl__colo_restore_domain_checkpoint_callback;

    /*
     * Secondary vm is running in colo mode, so we need to call
     * libxl__xc_domain_restore_done() to create secondary vm.
     * But we will exit in domain_create_cb(). So replace the
     * callback here.
     */
    crs->saved_cb = dcs->callback;
    dcs->callback = libxl__colo_domain_create_cb;
    crcs->state_file = GCSPRINTF(LIBXL_DEVICE_MODEL_RESTORE_FILE".%d", domid);
    crcs->status = LIBXL_COLO_SETUPED;

    libxl__logdirty_init(&crcs->lds);
    crcs->lds.ao = ao;

    crcs->sws.fd = crs->send_back_fd;
    crcs->sws.ao = ao;
    crcs->sws.back_channel = true;

    dcs->cds.concrete_data = crs;

    libxl__stream_write_start(egc, &crcs->sws);

    rc = 0;

out:
    crs->callback(egc, crs, rc);
    return;
}
Esempio n. 2
0
void libxl__domain_save(libxl__egc *egc, libxl__domain_save_state *dss)
{
    STATE_AO_GC(dss->ao);
    int rc, ret;

    /* Convenience aliases */
    const uint32_t domid = dss->domid;
    const libxl_domain_type type = dss->type;
    const int live = dss->live;
    const int debug = dss->debug;
    const libxl_domain_remus_info *const r_info = dss->remus;
    libxl__srm_save_autogen_callbacks *const callbacks =
        &dss->sws.shs.callbacks.save.a;
    unsigned int nr_vnodes = 0, nr_vmemranges = 0, nr_vcpus = 0;
    libxl__domain_suspend_state *dsps = &dss->dsps;

    if (dss->checkpointed_stream != LIBXL_CHECKPOINTED_STREAM_NONE && !r_info) {
        LOG(ERROR, "Migration stream is checkpointed, but there's no "
                   "checkpoint info!");
        rc = ERROR_INVAL;
        goto out;
    }

    dss->rc = 0;
    libxl__logdirty_init(&dss->logdirty);
    dss->logdirty.ao = ao;

    dsps->ao = ao;
    dsps->domid = domid;
    rc = libxl__domain_suspend_init(egc, dsps, type);
    if (rc) goto out;

    switch (type) {
    case LIBXL_DOMAIN_TYPE_HVM: {
        dss->hvm = 1;
        break;
    }
    case LIBXL_DOMAIN_TYPE_PV:
        dss->hvm = 0;
        break;
    default:
        abort();
    }

    dss->xcflags = (live ? XCFLAGS_LIVE : 0)
          | (debug ? XCFLAGS_DEBUG : 0)
          | (dss->hvm ? XCFLAGS_HVM : 0);

    /* Disallow saving a guest with vNUMA configured because migration
     * stream does not preserve node information.
     *
     * Reject any domain which has vnuma enabled, even if the
     * configuration is empty. Only domains which have no vnuma
     * configuration at all are supported.
     */
    ret = xc_domain_getvnuma(CTX->xch, domid, &nr_vnodes, &nr_vmemranges,
                             &nr_vcpus, NULL, NULL, NULL);
    if (ret != -1 || errno != EOPNOTSUPP) {
        LOG(ERROR, "Cannot save a guest with vNUMA configured");
        rc = ERROR_FAIL;
        goto out;
    }

    if (dss->checkpointed_stream == LIBXL_CHECKPOINTED_STREAM_REMUS) {
        if (libxl_defbool_val(r_info->compression))
            dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS;
    }

    if (dss->checkpointed_stream == LIBXL_CHECKPOINTED_STREAM_NONE)
        callbacks->suspend = libxl__domain_suspend_callback;

    callbacks->switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty;

    dss->sws.ao  = dss->ao;
    dss->sws.dss = dss;
    dss->sws.fd  = dss->fd;
    dss->sws.back_channel = false;
    dss->sws.completion_callback = stream_done;

    libxl__stream_write_start(egc, &dss->sws);
    return;

 out:
    domain_save_done(egc, dss, rc);
}