Both live and config. Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx> --- src/libxl/libxl_driver.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 7b50853..ae0d4f7 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3417,6 +3417,111 @@ cleanup: } static int +libxlDomainAttachDeviceNetLive(libxlDriverPrivatePtr driver, + libxlDomainObjPrivatePtr priv, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + virDomainNetDefPtr l_net = dev->data.net; + libxl_device_nic x_nic; + char mac[VIR_MAC_STRING_BUFLEN]; + int ret = -1; + + switch (dev->data.net->type) { + case VIR_DOMAIN_NET_TYPE_ETHERNET: + case VIR_DOMAIN_NET_TYPE_BRIDGE: + /* -2 means "multiple matches" so then fail also */ + if (virDomainNetFindIdx(vm->def, dev->data.net) != -1) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("device matching mac address %s already exists"), + virMacAddrFormat(&dev->data.net->mac, mac)); + goto cleanup; + } + + if (libxlMakeNic(driver, l_net, &x_nic) < 0) + goto cleanup; + + if ((ret = libxl_device_nic_add(priv->ctx, vm->def->id, + &x_nic, NULL)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight failed to attach net '%s'"), + virMacAddrFormat(&dev->data.net->mac, mac)); + goto cleanup; + } + + virDomainNetInsert(vm->def, l_net); + + break; + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("net device type '%s' cannot be hotplugged"), + virDomainNetTypeToString(l_net->type)); + break; + } + +cleanup: + return ret; +} + +static int +libxlDomainDetachDeviceNetLive(libxlDriverPrivatePtr driver, + libxlDomainObjPrivatePtr priv, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + virDomainNetDefPtr l_net = NULL; + libxl_device_nic x_nic; + char mac[VIR_MAC_STRING_BUFLEN]; + int i; + int ret = -1; + + switch (dev->data.net->type) { + case VIR_DOMAIN_NET_TYPE_ETHERNET: + case VIR_DOMAIN_NET_TYPE_BRIDGE: + if ((i = virDomainNetFindIdx(vm->def, dev->data.net)) < 0) { + if (i == -2) { + + virReportError(VIR_ERR_OPERATION_FAILED, + _("multiple devices matching mac address %s found"), + virMacAddrFormat(&dev->data.net->mac, mac)); + } + else { + virReportError(VIR_ERR_OPERATION_FAILED, + _("network device %s not found"), + virMacAddrFormat(&dev->data.net->mac, mac)); + } + goto cleanup; + } + + l_net = vm->def->nets[i]; + + if (libxlMakeNic(driver, l_net, &x_nic) < 0) + goto cleanup; + + if ((ret = libxl_device_nic_remove(priv->ctx, vm->def->id, + &x_nic, NULL)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight failed to detach nic '%d'"), + i); + goto cleanup; + } + + virDomainNetRemove(vm->def, i); + virDomainNetDefFree(l_net); + + break; + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("net device type '%s' cannot hot unplugged"), + virDomainNetTypeToString(dev->data.net->type)); + break; + } + +cleanup: + return ret; +} + +static int libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver, libxlDomainObjPrivatePtr priv, virDomainObjPtr vm, virDomainDeviceDefPtr dev) @@ -3430,6 +3535,12 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver, dev->data.disk = NULL; break; + case VIR_DOMAIN_DEVICE_NET: + ret = libxlDomainAttachDeviceNetLive(driver, priv, vm, dev); + if (!ret) + dev->data.net = NULL; + break; + default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%s' cannot be attached"), @@ -3444,6 +3555,8 @@ static int libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk; + virDomainNetDefPtr net; + char mac[VIR_MAC_STRING_BUFLEN]; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: @@ -3461,6 +3574,22 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) dev->data.disk = NULL; break; + case VIR_DOMAIN_DEVICE_NET: + net = dev->data.net; + if (virDomainNetFindIdx(vmdef, net) >= 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("net device with mac %s already exists."), + virMacAddrFormat(&net->mac, mac)); + return -1; + } + if (virDomainNetInsert(vmdef, net)) { + virReportOOMError(); + return -1; + } + /* vmdef has the pointer. Generic codes for vmdef will do all jobs */ + dev->data.net = NULL; + break; + default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent attach of device is not supported")); @@ -3482,6 +3611,10 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver, ret = libxlDomainDetachDeviceDiskLive(driver, priv, vm, dev); break; + case VIR_DOMAIN_DEVICE_NET: + ret = libxlDomainDetachDeviceNetLive(driver, priv, vm, dev); + break; + default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("device type '%s' cannot be detached"), @@ -3495,20 +3628,45 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver, static int libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { - virDomainDiskDefPtr disk, detach; + virDomainDiskDefPtr disk, disk_detach; + virDomainNetDefPtr net, net_detach; + char mac[VIR_MAC_STRING_BUFLEN]; + int net_idx; int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: disk = dev->data.disk; - if (!(detach = virDomainDiskRemoveByName(vmdef, disk->dst))) { + if (!(disk_detach = virDomainDiskRemoveByName(vmdef, disk->dst))) { virReportError(VIR_ERR_INVALID_ARG, _("no target device %s"), disk->dst); break; } - virDomainDiskDefFree(detach); + virDomainDiskDefFree(disk_detach); + ret = 0; + break; + + case VIR_DOMAIN_DEVICE_NET: + net = dev->data.net; + if ((net_idx = virDomainNetFindIdx(vmdef, net)) < 0) { + if (net_idx == -2) { + + virReportError(VIR_ERR_OPERATION_FAILED, + _("multiple devices matching mac address %s found"), + virMacAddrFormat(&dev->data.net->mac, mac)); + } + else { + virReportError(VIR_ERR_OPERATION_FAILED, + _("network device %s not found"), + virMacAddrFormat(&dev->data.net->mac, mac)); + } + return -1; + } + net_detach = virDomainNetRemove(vmdef, net_idx); + virDomainNetDefFree(net_detach); ret = 0; break; + default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("persistent detach of device is not supported")); -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list