[libvirt] [PATCH 9/9] qemu_hotplug: Support interface type of vhost-user hotplug
John Ferlan
jferlan at redhat.com
Thu Sep 22 23:02:44 UTC 2016
On 08/16/2016 11:41 AM, Michal Privoznik wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1366108
>
> So far, the hotplug of vhost-user "worked" by pure chance. Well,
> qemu would error on our commands, but nevertheless. Now that we
> have everything prepare, We should support hotplugging og
prepared, we ... of
> vhost-user. Firstly, we need to plug in chardev (through which
> qemu talks to OpenVSwitch), then netdev and only after that we
> can plug in the virtio-net-pci device.
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
> src/qemu/qemu_hotplug.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 45 insertions(+), 4 deletions(-)
>
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index feb1f44..0bcb411 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -933,6 +933,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> virDomainCCWAddressSetPtr ccwaddrs = NULL;
> size_t i;
> + char *charDevAlias = NULL;
>
> /* preallocate new slot for device */
> if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
> @@ -954,11 +955,11 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
> case VIR_DOMAIN_NET_TYPE_DIRECT:
> case VIR_DOMAIN_NET_TYPE_BRIDGE:
> case VIR_DOMAIN_NET_TYPE_HOSTDEV:
> + case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> /* These types are supported. */
> break;
>
> case VIR_DOMAIN_NET_TYPE_USER:
> - case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> case VIR_DOMAIN_NET_TYPE_SERVER:
> case VIR_DOMAIN_NET_TYPE_CLIENT:
> case VIR_DOMAIN_NET_TYPE_MCAST:
> @@ -1148,6 +1149,26 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
> goto cleanup;
> }
>
> + if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
> + if (!qemuDomainSupportsNetdev(vm->def, priv->qemuCaps, net)) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("Netdev support unavailable"));
"%s", on previous line
"vhost-user hot-plug not support by this version of qemu"
> + goto cleanup;
> + }
> +
> + if (virAsprintf(&charDevAlias, "char%s", net->info.alias) < 0)
> + goto cleanup;
> +
> + qemuDomainObjEnterMonitor(driver, vm);
> + if (qemuMonitorAttachCharDev(priv->mon, charDevAlias, net->data.vhostuser) < 0) {
> + ignore_value(qemuDomainObjExitMonitor(driver, vm));
> + virDomainAuditNet(vm, NULL, net, "attach", false);
> + goto cleanup;
> + }
> + if (qemuDomainObjExitMonitor(driver, vm) < 0)
> + goto cleanup;
> + }
> +
> qemuDomainObjEnterMonitor(driver, vm);
> if (qemuDomainSupportsNetdev(vm->def, priv->qemuCaps, net)) {
> if (qemuMonitorAddNetdev(priv->mon, netstr,
> @@ -1268,6 +1289,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
> }
> VIR_FREE(vhostfd);
> VIR_FREE(vhostfdName);
> + VIR_FREE(charDevAlias);
> virObjectUnref(cfg);
> virDomainCCWAddressSetFree(ccwaddrs);
>
> @@ -1283,6 +1305,9 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
> if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
> goto cleanup;
> qemuDomainObjEnterMonitor(driver, vm);
> + if (charDevAlias &&
> + qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0)
> + VIR_WARN("Failed to remove associated chardev %s", charDevAlias);
> if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
> VIR_WARN("Failed to remove network backend for netdev %s",
> netdev_name);
> @@ -3309,10 +3334,12 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
> virNetDevVPortProfilePtr vport;
> virObjectEventPtr event;
> char *hostnet_name = NULL;
> + char *charDevAlias = NULL;
> size_t i;
> int ret = -1;
> + int actualType = virDomainNetGetActualType(net);
>
> - if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
> + if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
> /* this function handles all hostdev and netdev cleanup */
> ret = qemuDomainRemoveHostDevice(driver, vm,
> virDomainNetGetActualHostdev(net));
> @@ -3322,9 +3349,11 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
> VIR_DEBUG("Removing network interface %s from domain %p %s",
> net->info.alias, vm, vm->def->name);
>
> - if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
> + if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0 ||
> + virAsprintf(&charDevAlias, "char%s", net->info.alias) < 0)
Part of me wonders if this should be
||
(actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
Since it's only necessary for vhost-user, but it does seem excessive.
Then again no more excessive than allocating something we don't use. IDC
either way, but I'd be remiss if I didn't point it out.
> goto cleanup;
>
> +
> qemuDomainObjEnterMonitor(driver, vm);
> if (qemuDomainSupportsNetdev(vm->def, priv->qemuCaps, net)) {
> if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
> @@ -3347,6 +3376,17 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
> goto cleanup;
> }
> }
> +
> + if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
> + /* vhostuser has a chardev too */
> + if (qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0) {
> + /* well, this is a messy situation. Guest visible PCI device has
> + * been removed, netdev too but chardev not. The best seems to be
> + * to just ignore the error and carry on.
> + */
> + }
> + }
> +
The attach order is:
1. Build 'netstr'
2. If vhost-user, attach char dev
3. Add netdev/hostdev using netstr
But your detach order is
1. Remove netdev/hostdev
2. Remove vhost-user chardev
See anything wrong with that dependency-wise?
Look at the failure code for Attach - it'll remove CharDev before Netdev
So the question is - if you did this in the right order, then would that
messy situation not exist?
John
> if (qemuDomainObjExitMonitor(driver, vm) < 0)
> goto cleanup;
>
> @@ -3371,7 +3411,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
> &net->mac));
> }
>
> - if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
> + if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
> net->ifname, &net->mac,
> virDomainNetGetActualDirectDev(net),
> @@ -3397,6 +3437,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
>
> cleanup:
> virObjectUnref(cfg);
> + VIR_FREE(charDevAlias);
> VIR_FREE(hostnet_name);
> return ret;
> }
>
More information about the libvir-list
mailing list