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; }
// 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; }
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; }
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); }
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); }
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; }
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; }
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; }
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; }