Exemple #1
0
int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
                            const char *mac, libxl_device_nic *nic)
{
    libxl_device_nic *nics;
    int nb, rc, i;
    libxl_mac mac_n;

    rc = libxl__parse_mac(mac, mac_n);
    if (rc)
        return rc;

    nics = libxl_device_nic_list(ctx, domid, &nb);
    if (!nics)
        return ERROR_FAIL;

    memset(nic, 0, sizeof (libxl_device_nic));

    rc = ERROR_INVAL;
    for (i = 0; i < nb; ++i) {
        if (!libxl__compare_macs(&mac_n, &nics[i].mac)) {
            *nic = nics[i];
            rc = 0;
            i++; /* Do not dispose this NIC on exit path */
            break;
        }
        libxl_device_nic_dispose(&nics[i]);
    }

    for (; i<nb; i++)
        libxl_device_nic_dispose(&nics[i]);

    free(nics);
    return rc;
}
Exemple #2
0
// libxl internal in libxl__device_nic_add()
int hyperxl_nic_add(libxl_ctx* ctx, uint32_t domid, hyperxl_nic_config* config) {

    libxl_device_nic nic;
    libxl_mac mac;
    int i, ret = -1;

    libxl_device_nic_init(&nic);
    nic.backend_domid = 0;
    nic.mtu = 1492;
    nic.model = strdup("e1000");
    nic.ip = strdup(config->ip);
    nic.bridge = strdup(config->bridge);
    nic.nictype = LIBXL_NIC_TYPE_VIF_IOEMU;
    nic.ifname = strdup(config->ifname);
    nic.gatewaydev = strdup(config->gatewaydev);
    if (config->mac != NULL) {
        for (i=0; i<6; i++) {
            mac[i] = (uint8_t)(*(config->mac + i));
        }
        libxl_mac_copy(ctx, &nic.mac, &mac);
    }

    if( libxl_device_nic_add(ctx, domid, &nic, 0) ) {
        goto cleanup;
    }

    ret = 0;

cleanup:
    libxl_device_nic_dispose(&nic);
    return ret;
}
Exemple #3
0
static int
libxlMakeNicList(virDomainDefPtr def,  libxl_domain_config *d_config)
{
    virDomainNetDefPtr *l_nics = def->nets;
    int nnics = def->nnets;
    libxl_device_nic *x_nics;
    size_t i;

    if (VIR_ALLOC_N(x_nics, nnics) < 0)
        return -1;

    for (i = 0; i < nnics; i++) {
        if (libxlMakeNic(def, l_nics[i], &x_nics[i]))
            goto error;
        /*
         * The devid (at least right now) will not get initialized by
         * libxl in the setup case but is required for starting the
         * device-model.
         */
        if (x_nics[i].devid < 0)
            x_nics[i].devid = i;
    }

    d_config->nics = x_nics;
    d_config->num_nics = nnics;

    return 0;

error:
    for (i = 0; i < nnics; i++)
        libxl_device_nic_dispose(&x_nics[i]);
    VIR_FREE(x_nics);
    return -1;
}
Exemple #4
0
static void devices_teardown_cb(libxl__egc *egc,
                                libxl__multidev *multidev,
                                int rc)
{
    int i;

    STATE_AO_GC(multidev->ao);

    /* Convenience aliases */
    libxl__checkpoint_devices_state *const cds =
                            CONTAINER_OF(multidev, *cds, multidev);

    /* clean nic */
    for (i = 0; i < cds->num_nics; i++)
        libxl_device_nic_dispose(&cds->nics[i]);
    free(cds->nics);
    cds->nics = NULL;
    cds->num_nics = 0;

    /* clean disk */
    for (i = 0; i < cds->num_disks; i++)
        libxl_device_disk_dispose(&cds->disks[i]);
    free(cds->disks);
    cds->disks = NULL;
    cds->num_disks = 0;

    cds->callback(egc, cds, rc);
}
Exemple #5
0
void libxl_domain_config_dispose(libxl_domain_config *d_config)
{
    int i;

    for (i=0; i<d_config->num_disks; i++)
        libxl_device_disk_dispose(&d_config->disks[i]);
    free(d_config->disks);

    for (i=0; i<d_config->num_nics; i++)
        libxl_device_nic_dispose(&d_config->nics[i]);
    free(d_config->nics);

    for (i=0; i<d_config->num_pcidevs; i++)
        libxl_device_pci_dispose(&d_config->pcidevs[i]);
    free(d_config->pcidevs);

    for (i=0; i<d_config->num_vfbs; i++)
        libxl_device_vfb_dispose(&d_config->vfbs[i]);
    free(d_config->vfbs);

    for (i=0; i<d_config->num_vkbs; i++)
        libxl_device_vkb_dispose(&d_config->vkbs[i]);
    free(d_config->vkbs);

    libxl_domain_create_info_dispose(&d_config->c_info);
    libxl_domain_build_info_dispose(&d_config->b_info);
}
static void devices_teardown_cb(libxl__egc *egc,
                                libxl__multidev *multidev,
                                int rc)
{
    int i;

    STATE_AO_GC(multidev->ao);

    /* Convenience aliases */
    libxl__remus_devices_state *const rds =
                            CONTAINER_OF(multidev, *rds, multidev);

    /* clean nic */
    for (i = 0; i < rds->num_nics; i++)
        libxl_device_nic_dispose(&rds->nics[i]);
    free(rds->nics);
    rds->nics = NULL;
    rds->num_nics = 0;

    /* clean disk */
    for (i = 0; i < rds->num_disks; i++)
        libxl_device_disk_dispose(&rds->disks[i]);
    free(rds->disks);
    rds->disks = NULL;
    rds->num_disks = 0;

    cleanup_device_subkind(rds);

    rds->callback(egc, rds, rc);
}
Exemple #7
0
static int
libxlMakeNicList(virDomainDefPtr def,  libxl_domain_config *d_config)
{
    virDomainNetDefPtr *l_nics = def->nets;
    size_t nnics = def->nnets;
    libxl_device_nic *x_nics;
    size_t i, nvnics = 0;

    if (VIR_ALLOC_N(x_nics, nnics) < 0)
        return -1;

    for (i = 0; i < nnics; i++) {
        if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
            continue;

        if (libxlMakeNic(def, l_nics[i], &x_nics[nvnics]))
            goto error;
        /*
         * The devid (at least right now) will not get initialized by
         * libxl in the setup case but is required for starting the
         * device-model.
         */
        if (x_nics[nvnics].devid < 0)
            x_nics[nvnics].devid = nvnics;

        nvnics++;
    }

    VIR_SHRINK_N(x_nics, nnics, nnics - nvnics);
    d_config->nics = x_nics;
    d_config->num_nics = nnics;

    return 0;

 error:
    for (i = 0; i < nnics; i++)
        libxl_device_nic_dispose(&x_nics[i]);
    VIR_FREE(x_nics);
    return -1;
}
Exemple #8
0
int hyperxl_nic_remove(libxl_ctx* ctx, uint32_t domid, const char* mac) {
    libxl_device_nic nic;
    int ret = -1;

    libxl_device_nic_init(&nic);
    if(libxl_mac_to_device_nic(ctx, domid, mac, &nic)) {
        char* msg = "failed to get device from mac";
        hyperxl_log_cgo(msg, strlen(msg));
        goto cleanup;
    }

    if(libxl_device_nic_remove(ctx, domid, &nic, 0)) {
        char* msg = "failed to remove nic from domain";
        hyperxl_log_cgo(msg, strlen(msg));
        goto cleanup;
    }
    ret = 0;

cleanup:
    libxl_device_nic_dispose(&nic);
    return ret;
}
Exemple #9
0
libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx, uint32_t domid, int *num)
{
    GC_INIT(ctx);
    libxl_device_nic *nics = NULL;
    int rc;

    *num = 0;

    rc = libxl__append_nic_list(gc, domid, &nics, num);
    if (rc) goto out_err;

    GC_FREE;
    return nics;

out_err:
    LOG(ERROR, "Unable to list nics");
    while (*num) {
        (*num)--;
        libxl_device_nic_dispose(&nics[*num]);
    }
    free(nics);
    return NULL;
}
Exemple #10
0
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;
}