qemu: honour fatal errors dealing with qemu slirp helper

Currently all errors from qemuInterfacePrepareSlirp() are completely
ignored by the callers. The intention is that missing qemu-slirp binary
should cause the caller to fallback to the built-in slirp impl.

Many of the possible errors though should indeed be considered fatal.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2020-10-15 12:12:15 +01:00
parent ae23a87d85
commit 99a1cfc438
5 changed files with 29 additions and 15 deletions

View File

@ -1313,9 +1313,12 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_NET_TYPE_USER:
if (!priv->disableSlirp &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
qemuSlirpPtr slirp = qemuInterfacePrepareSlirp(driver, net);
qemuSlirpPtr slirp = NULL;
int rv = qemuInterfacePrepareSlirp(driver, net, &slirp);
if (!slirp)
if (rv == -1)
return -1;
if (rv == 0)
break;
QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;

View File

@ -661,30 +661,39 @@ qemuInterfaceVDPAConnect(virDomainNetDefPtr net)
}
qemuSlirpPtr
/*
* Returns: -1 on error, 0 if slirp isn't available, 1 on succcess
*/
int
qemuInterfacePrepareSlirp(virQEMUDriverPtr driver,
virDomainNetDefPtr net)
virDomainNetDefPtr net,
qemuSlirpPtr *slirpret)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autoptr(qemuSlirp) slirp = NULL;
size_t i;
if (!cfg->slirpHelperName ||
!virFileExists(cfg->slirpHelperName))
return 0; /* fallback to builtin slirp impl */
if (!(slirp = qemuSlirpNewForHelper(cfg->slirpHelperName)))
return NULL;
return -1;
for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET) &&
!qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_IPV4))
return NULL;
return 0;
if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6) &&
!qemuSlirpHasFeature(slirp, QEMU_SLIRP_FEATURE_IPV6))
return NULL;
return 0;
}
return g_steal_pointer(&slirp);
*slirpret = g_steal_pointer(&slirp);
return 1;
}

View File

@ -56,7 +56,8 @@ int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
int *vhostfd,
size_t *vhostfdSize) G_GNUC_NO_INLINE;
qemuSlirpPtr qemuInterfacePrepareSlirp(virQEMUDriverPtr driver,
virDomainNetDefPtr net);
int qemuInterfacePrepareSlirp(virQEMUDriverPtr driver,
virDomainNetDefPtr net,
qemuSlirpPtr *slirp);
int qemuInterfaceVDPAConnect(virDomainNetDefPtr net) G_GNUC_NO_INLINE;

View File

@ -5757,9 +5757,13 @@ qemuProcessNetworkPrepareDevices(virQEMUDriverPtr driver,
} else if (actualType == VIR_DOMAIN_NET_TYPE_USER &&
!priv->disableSlirp &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
qemuSlirpPtr slirp = qemuInterfacePrepareSlirp(driver, net);
qemuSlirpPtr slirp = NULL;
int rv = qemuInterfacePrepareSlirp(driver, net, &slirp);
QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
if (rv == -1)
return -1;
if (rv == 1)
QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
}
}

View File

@ -101,9 +101,6 @@ qemuSlirpNewForHelper(const char *helper)
virJSONValuePtr featuresJSON;
size_t i, nfeatures;
if (!helper)
return NULL;
slirp = qemuSlirpNew();
if (!slirp) {
virReportError(VIR_ERR_INTERNAL_ERROR,