mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
libxl: support hotplug of <interface>
Add code to support attach/detaching a network device. Signed-off-by: Chunyan Liu <cyliu@suse.com>
This commit is contained in:
parent
232cf2a45c
commit
b0d2454023
@ -482,8 +482,16 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
||||
STRNEQ(def->os.type, "hvm"))
|
||||
dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
|
||||
|
||||
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
||||
virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV ||
|
||||
(dev->type == VIR_DOMAIN_DEVICE_NET &&
|
||||
dev->data.net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
|
||||
|
||||
virDomainHostdevDefPtr hostdev;
|
||||
|
||||
if (dev->type == VIR_DOMAIN_DEVICE_NET)
|
||||
hostdev = &(dev->data.net)->data.hostdev.def;
|
||||
else
|
||||
hostdev = dev->data.hostdev;
|
||||
|
||||
/* forbid capabilities mode hostdev in this kind of hypervisor */
|
||||
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) {
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "viraccessapicheck.h"
|
||||
#include "viratomic.h"
|
||||
#include "virhostdev.h"
|
||||
#include "network/bridge_driver.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_LIBXL
|
||||
|
||||
@ -2674,10 +2675,8 @@ static int
|
||||
libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
virDomainObjPtr vm,
|
||||
virDomainDeviceDefPtr dev)
|
||||
virDomainHostdevDefPtr hostdev)
|
||||
{
|
||||
virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("hostdev mode '%s' not supported"),
|
||||
@ -2755,6 +2754,60 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
virDomainObjPtr vm,
|
||||
virDomainNetDefPtr net)
|
||||
{
|
||||
int actualType;
|
||||
libxl_device_nic nic;
|
||||
int ret = -1;
|
||||
|
||||
/* preallocate new slot for device */
|
||||
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
|
||||
return -1;
|
||||
|
||||
/* If appropriate, grab a physical device from the configured
|
||||
* network's pool of devices, or resolve bridge device name
|
||||
* to the one defined in the network definition.
|
||||
*/
|
||||
if (networkAllocateActualDevice(vm->def, net) < 0)
|
||||
return -1;
|
||||
|
||||
actualType = virDomainNetGetActualType(net);
|
||||
|
||||
if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
||||
/* This is really a "smart hostdev", so it should be attached
|
||||
* as a hostdev (the hostdev code will reach over into the
|
||||
* netdev-specific code as appropriate), then also added to
|
||||
* the nets list (see out:) if successful.
|
||||
*/
|
||||
ret = libxlDomainAttachHostDevice(driver, priv, vm,
|
||||
virDomainNetGetActualHostdev(net));
|
||||
goto out;
|
||||
}
|
||||
|
||||
libxl_device_nic_init(&nic);
|
||||
if (libxlMakeNic(vm->def, net, &nic) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (libxl_device_nic_add(priv->ctx, vm->def->id, &nic, 0)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("libxenlight failed to attach network device"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
libxl_device_nic_dispose(&nic);
|
||||
out:
|
||||
if (!ret)
|
||||
vm->def->nets[vm->def->nnets++] = net;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
@ -2770,8 +2823,16 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
|
||||
dev->data.disk = NULL;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
ret = libxlDomainAttachNetDevice(driver, priv, vm,
|
||||
dev->data.net);
|
||||
if (!ret)
|
||||
dev->data.net = NULL;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||
ret = libxlDomainAttachHostDevice(driver, priv, vm, dev);
|
||||
ret = libxlDomainAttachHostDevice(driver, priv, vm,
|
||||
dev->data.hostdev);
|
||||
if (!ret)
|
||||
dev->data.hostdev = NULL;
|
||||
break;
|
||||
@ -2790,6 +2851,7 @@ static int
|
||||
libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
|
||||
{
|
||||
virDomainDiskDefPtr disk;
|
||||
virDomainNetDefPtr net;
|
||||
virDomainHostdevDefPtr hostdev;
|
||||
virDomainHostdevDefPtr found;
|
||||
|
||||
@ -2806,6 +2868,14 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
|
||||
/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
|
||||
dev->data.disk = NULL;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
net = dev->data.net;
|
||||
if (virDomainNetInsert(vmdef, net))
|
||||
return -1;
|
||||
dev->data.net = NULL;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||
hostdev = dev->data.hostdev;
|
||||
|
||||
@ -2928,9 +2998,8 @@ static int
|
||||
libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
virDomainObjPtr vm,
|
||||
virDomainDeviceDefPtr dev)
|
||||
virDomainHostdevDefPtr hostdev)
|
||||
{
|
||||
virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
||||
@ -2953,6 +3022,53 @@ libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
virDomainObjPtr vm,
|
||||
virDomainNetDefPtr net)
|
||||
{
|
||||
int detachidx;
|
||||
virDomainNetDefPtr detach = NULL;
|
||||
libxl_device_nic nic;
|
||||
char mac[VIR_MAC_STRING_BUFLEN];
|
||||
int ret = -1;
|
||||
|
||||
if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0)
|
||||
return -1;
|
||||
|
||||
detach = vm->def->nets[detachidx];
|
||||
|
||||
if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
||||
/* This is really a "smart hostdev", so it should be attached as a
|
||||
* hostdev, then also removed from nets list (see out:) if successful.
|
||||
*/
|
||||
ret = libxlDomainDetachHostDevice(driver, priv, vm,
|
||||
virDomainNetGetActualHostdev(detach));
|
||||
goto out;
|
||||
}
|
||||
|
||||
libxl_device_nic_init(&nic);
|
||||
if (libxl_mac_to_device_nic(priv->ctx, vm->def->id,
|
||||
virMacAddrFormat(&detach->mac, mac), &nic))
|
||||
goto cleanup;
|
||||
|
||||
if (libxl_device_nic_remove(priv->ctx, vm->def->id, &nic, 0)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("libxenlight failed to detach network device"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
libxl_device_nic_dispose(&nic);
|
||||
out:
|
||||
if (!ret)
|
||||
virDomainNetRemove(vm->def, detachidx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
|
||||
libxlDomainObjPrivatePtr priv,
|
||||
@ -2966,8 +3082,14 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
|
||||
ret = libxlDomainDetachDeviceDiskLive(priv, vm, dev);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
ret = libxlDomainDetachNetDevice(driver, priv, vm,
|
||||
dev->data.net);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||
ret = libxlDomainDetachHostDevice(driver, priv, vm, dev);
|
||||
ret = libxlDomainDetachHostDevice(driver, priv, vm,
|
||||
dev->data.hostdev);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2986,6 +3108,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
|
||||
{
|
||||
virDomainDiskDefPtr disk, detach;
|
||||
virDomainHostdevDefPtr hostdev, det_hostdev;
|
||||
virDomainNetDefPtr net;
|
||||
int idx;
|
||||
|
||||
switch (dev->type) {
|
||||
@ -2999,6 +3122,15 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
|
||||
virDomainDiskDefFree(detach);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
net = dev->data.net;
|
||||
if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
|
||||
return -1;
|
||||
|
||||
/* this is guaranteed to succeed */
|
||||
virDomainNetDefFree(virDomainNetRemove(vmdef, idx));
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_HOSTDEV: {
|
||||
hostdev = dev->data.hostdev;
|
||||
if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user