示例#1
0
文件: libxl_dm.c 项目: jsgf/xen
static const char *libxl_tapif_script(libxl__gc *gc)
{
#ifdef __linux__
    return libxl__strdup(gc, "no");
#else
    return libxl__sprintf(gc, "%s/qemu-ifup", libxl__xen_script_dir_path());
#endif
}
示例#2
0
int init_subkind_drbd_disk(libxl__remus_devices_state *rds)
{
    STATE_AO_GC(rds->ao);

    rds->drbd_probe_script = GCSPRINTF("%s/block-drbd-probe",
                                       libxl__xen_script_dir_path());

    return 0;
}
示例#3
0
int init_subkind_nic(libxl__checkpoint_devices_state *cds)
{
    int rc, ret;
    libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds);
    libxl__remus_state *rs = cds->concrete_data;

    STATE_AO_GC(cds->ao);

    rs->nlsock = nl_socket_alloc();
    if (!rs->nlsock) {
        LOGD(ERROR, dss->domid, "cannot allocate nl socket");
        rc = ERROR_FAIL;
        goto out;
    }

    ret = nl_connect(rs->nlsock, NETLINK_ROUTE);
    if (ret) {
        LOGD(ERROR, dss->domid, "failed to open netlink socket: %s",
             nl_geterror(ret));
        rc = ERROR_FAIL;
        goto out;
    }

    /* get list of all qdiscs installed on network devs. */
    ret = rtnl_qdisc_alloc_cache(rs->nlsock, &rs->qdisc_cache);
    if (ret) {
        LOGD(ERROR, dss->domid, "failed to allocate qdisc cache: %s",
             nl_geterror(ret));
        rc = ERROR_FAIL;
        goto out;
    }

    if (dss->remus->netbufscript) {
        rs->netbufscript = libxl__strdup(gc, dss->remus->netbufscript);
    } else {
        rs->netbufscript = GCSPRINTF("%s/remus-netbuf-setup",
                                     libxl__xen_script_dir_path());
    }

    rc = 0;

out:
    return rc;
}
示例#4
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;
}
示例#5
0
void libxl__colo_save_setup(libxl__egc *egc, libxl__colo_save_state *css)
{
    libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css);

    /* Convenience aliases */
    libxl__checkpoint_devices_state *const cds = &dss->cds;
    libxl__srm_save_autogen_callbacks *const callbacks =
        &dss->sws.shs.callbacks.save.a;

    STATE_AO_GC(dss->ao);

    if (dss->type != LIBXL_DOMAIN_TYPE_HVM) {
        LOGD(ERROR, dss->domid, "COLO only supports hvm now");
        goto out;
    }

    css->send_fd = dss->fd;
    css->recv_fd = dss->recv_fd;
    css->svm_running = false;
    css->paused = true;
    css->qdisk_setuped = false;
    css->qdisk_used = false;
    libxl__ev_child_init(&css->child);
    css->cps.is_userspace_proxy =
        libxl_defbool_val(dss->remus->userspace_colo_proxy);

    if (dss->remus->netbufscript)
        css->colo_proxy_script = libxl__strdup(gc, dss->remus->netbufscript);
    else
        css->colo_proxy_script = GCSPRINTF("%s/colo-proxy-setup",
                                           libxl__xen_script_dir_path());

    cds->ops = colo_ops;
    cds->callback = colo_save_setup_done;
    cds->ao = ao;
    cds->domid = dss->domid;
    cds->concrete_data = css;

    /* If enable userspace proxy mode, we don't need VIF */
    if (css->cps.is_userspace_proxy) {
        cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VBD);

        /* Use this args we can connect to qemu colo-compare */
        cds->nics = libxl__device_list(gc, &libxl__nic_devtype,
                                       cds->domid, &cds->num_nics);
        if (cds->num_nics > 0) {
            css->cps.checkpoint_host = cds->nics[0].colo_checkpoint_host;
            css->cps.checkpoint_port = cds->nics[0].colo_checkpoint_port;
        }
    } else {
        cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VIF) |
                                 (1 << LIBXL__DEVICE_KIND_VBD);
    }

    css->srs.ao = ao;
    css->srs.fd = css->recv_fd;
    css->srs.back_channel = true;
    libxl__stream_read_start(egc, &css->srs);
    css->cps.ao = ao;
    if (colo_proxy_setup(&css->cps)) {
        LOGD(ERROR, cds->domid, "COLO: failed to setup colo proxy for guest");
        goto out;
    }

    if (init_device_subkind(cds))
        goto out;

    callbacks->suspend = libxl__colo_save_domain_suspend_callback;
    callbacks->checkpoint = libxl__colo_save_domain_checkpoint_callback;
    callbacks->postcopy = libxl__colo_save_domain_resume_callback;
    callbacks->wait_checkpoint = libxl__colo_save_domain_wait_checkpoint_callback;

    libxl__checkpoint_devices_setup(egc, &dss->cds);

    return;

out:
    dss->callback(egc, dss, ERROR_FAIL);
}
示例#6
0
文件: libxl_nic.c 项目: TressaOrg/xen
int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
                                 uint32_t domid, bool hotplug)
{
    int rc;

    if (!nic->mtu)
        nic->mtu = 1492;
    if (!nic->model) {
        nic->model = strdup("rtl8139");
        if (!nic->model) return ERROR_NOMEM;
    }
    if (libxl__mac_is_default(&nic->mac)) {
        const uint8_t *r;
        libxl_uuid uuid;

        libxl_uuid_generate(&uuid);
        r = libxl_uuid_bytearray(&uuid);

        nic->mac[0] = 0x00;
        nic->mac[1] = 0x16;
        nic->mac[2] = 0x3e;
        nic->mac[3] = r[0] & 0x7f;
        nic->mac[4] = r[1];
        nic->mac[5] = r[2];
    }
    if (!nic->bridge) {
        nic->bridge = strdup("xenbr0");
        if (!nic->bridge) return ERROR_NOMEM;
    }
    if ( !nic->script && asprintf(&nic->script, "%s/vif-bridge",
                                  libxl__xen_script_dir_path()) < 0 )
        return ERROR_FAIL;

    rc = libxl__resolve_domid(gc, nic->backend_domname, &nic->backend_domid);
    if (rc < 0) return rc;

    switch (libxl__domain_type(gc, domid)) {
    case LIBXL_DOMAIN_TYPE_HVM:
        if (!nic->nictype) {
            if (hotplug ||
                (libxl__device_model_version_running(gc, domid) ==
                 LIBXL_DEVICE_MODEL_VERSION_NONE))
                nic->nictype = LIBXL_NIC_TYPE_VIF;
            else
                nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
        }
        break;
    case LIBXL_DOMAIN_TYPE_PV:
        if (nic->nictype == LIBXL_NIC_TYPE_VIF_IOEMU) {
            LOG(ERROR, "trying to create PV guest with an emulated interface");
            return ERROR_INVAL;
        }
        nic->nictype = LIBXL_NIC_TYPE_VIF;
        break;
    case LIBXL_DOMAIN_TYPE_INVALID:
        return ERROR_FAIL;
    default:
        abort();
    }

    return rc;
}
示例#7
0
文件: libxl_nic.c 项目: TressaOrg/xen
static void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
                                  libxl_device_nic *nic,
                                  libxl__ao_device *aodev)
{
    STATE_AO_GC(aodev->ao);
    flexarray_t *front;
    flexarray_t *back;
    libxl__device *device;
    int rc;
    xs_transaction_t t = XBT_NULL;
    libxl_domain_config d_config;
    libxl_device_nic nic_saved;
    libxl__domain_userdata_lock *lock = NULL;

    libxl_domain_config_init(&d_config);
    libxl_device_nic_init(&nic_saved);
    libxl_device_nic_copy(CTX, &nic_saved, nic);

    rc = libxl__device_nic_setdefault(gc, nic, domid, aodev->update_json);
    if (rc) goto out;

    front = flexarray_make(gc, 16, 1);
    back = flexarray_make(gc, 18, 1);

    if (nic->devid == -1) {
        if ((nic->devid = libxl__device_nextid(gc, domid, "vif")) < 0) {
            rc = ERROR_FAIL;
            goto out;
        }
    }

    libxl__update_config_nic(gc, &nic_saved, nic);

    GCNEW(device);
    rc = libxl__device_from_nic(gc, domid, nic, device);
    if ( rc != 0 ) goto out;

    flexarray_append(back, "frontend-id");
    flexarray_append(back, GCSPRINTF("%d", domid));
    flexarray_append(back, "online");
    flexarray_append(back, "1");
    flexarray_append(back, "state");
    flexarray_append(back, GCSPRINTF("%d", XenbusStateInitialising));
    if (nic->script)
        flexarray_append_pair(back, "script",
                              libxl__abs_path(gc, nic->script,
                                              libxl__xen_script_dir_path()));

    if (nic->ifname) {
        flexarray_append(back, "vifname");
        flexarray_append(back, nic->ifname);
    }

    if (nic->coloft_forwarddev) {
        flexarray_append(back, "forwarddev");
        flexarray_append(back, nic->coloft_forwarddev);
    }

    flexarray_append(back, "mac");
    flexarray_append(back,GCSPRINTF(LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
    if (nic->ip) {
        flexarray_append(back, "ip");
        flexarray_append(back, libxl__strdup(gc, nic->ip));
    }
    if (nic->gatewaydev) {
        flexarray_append(back, "gatewaydev");
        flexarray_append(back, libxl__strdup(gc, nic->gatewaydev));
    }

    if (nic->rate_interval_usecs > 0) {
        flexarray_append(back, "rate");
        flexarray_append(back, GCSPRINTF("%"PRIu64",%"PRIu32"",
                            nic->rate_bytes_per_interval,
                            nic->rate_interval_usecs));
    }

    flexarray_append(back, "bridge");
    flexarray_append(back, libxl__strdup(gc, nic->bridge));
    flexarray_append(back, "handle");
    flexarray_append(back, GCSPRINTF("%d", nic->devid));
    flexarray_append(back, "type");
    flexarray_append(back, libxl__strdup(gc,
                                     libxl_nic_type_to_string(nic->nictype)));

    flexarray_append(front, "backend-id");
    flexarray_append(front, GCSPRINTF("%d", nic->backend_domid));
    flexarray_append(front, "state");
    flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
    flexarray_append(front, "handle");
    flexarray_append(front, GCSPRINTF("%d", nic->devid));
    flexarray_append(front, "mac");
    flexarray_append(front, GCSPRINTF(
                                    LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));

    if (aodev->update_json) {
        lock = libxl__lock_domain_userdata(gc, domid);
        if (!lock) {
            rc = ERROR_LOCK_FAIL;
            goto out;
        }

        rc = libxl__get_domain_configuration(gc, domid, &d_config);
        if (rc) goto out;

        DEVICE_ADD(nic, nics, domid, &nic_saved, COMPARE_DEVID, &d_config);

        rc = libxl__dm_check_start(gc, &d_config, domid);
        if (rc) goto out;
    }

    for (;;) {
        rc = libxl__xs_transaction_start(gc, &t);
        if (rc) goto out;

        rc = libxl__device_exists(gc, t, device);
        if (rc < 0) goto out;
        if (rc == 1) {              /* already exists in xenstore */
            LOG(ERROR, "device already exists in xenstore");
            aodev->action = LIBXL__DEVICE_ACTION_ADD; /* for error message */
            rc = ERROR_DEVICE_EXISTS;
            goto out;
        }

        if (aodev->update_json) {
            rc = libxl__set_domain_configuration(gc, domid, &d_config);
            if (rc) goto out;
        }

        libxl__device_generic_add(gc, t, device,
                                  libxl__xs_kvs_of_flexarray(gc, back,
                                                             back->count),
                                  libxl__xs_kvs_of_flexarray(gc, front,
                                                             front->count),
                                  NULL);

        rc = libxl__xs_transaction_commit(gc, &t);
        if (!rc) break;
        if (rc < 0) goto out;
    }

    aodev->dev = device;
    aodev->action = LIBXL__DEVICE_ACTION_ADD;
    libxl__wait_device_connection(egc, aodev);

    rc = 0;
out:
    libxl__xs_transaction_abort(gc, &t);
    if (lock) libxl__unlock_domain_userdata(lock);
    libxl_device_nic_dispose(&nic_saved);
    libxl_domain_config_dispose(&d_config);
    aodev->rc = rc;
    if (rc) aodev->callback(egc, aodev);
    return;
}