提交 bd6b0a05 编写于 作者: D D. Herrendoerfer 提交者: Laine Stump

qemu,util: on restart of libvirt restart vepa callbacks

When libvirtd is restarted, also restart the netlink event
message callbacks for existing VEPA connections and send
a message to lldpad for these existing links, so it learns
the new libvirtd pid.
Signed-off-by: ND. Herrendoerfer <d.herrendoerfer@herrendoerfer.name>
上级 2067e31b
......@@ -415,6 +415,35 @@ cleanup:
virDomainObjUnlock(vm);
}
static void qemuDomainNetsRestart(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
int i;
virDomainObjPtr vm = (virDomainObjPtr)payload;
virDomainDefPtr def = vm->def;
virDomainObjLock(vm);
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT &&
virDomainNetGetActualDirectMode(net) == VIR_NETDEV_MACVLAN_MODE_VEPA) {
VIR_DEBUG("VEPA mode device %s active in domain %s. Reassociating.",
net->ifname, def->name);
ignore_value(virNetDevMacVLanRestartWithVPortProfile(net->ifname,
net->mac,
virDomainNetGetActualDirectDev(net),
def->uuid,
virDomainNetGetActualVirtPortProfile(net),
VIR_NETDEV_VPORT_PROFILE_OP_CREATE));
}
}
virDomainObjUnlock(vm);
}
/**
* qemudStartup:
*
......@@ -665,6 +694,8 @@ qemudStartup(int privileged) {
NULL, NULL) < 0)
goto error;
virHashForEach(qemu_driver->domains.objs, qemuDomainNetsRestart, NULL);
conn = virConnectOpen(qemu_driver->privileged ?
"qemu:///system" :
"qemu:///session");
......
......@@ -754,6 +754,50 @@ virNetDevMacVLanVPortProfileDestroyCallback(int watch ATTRIBUTE_UNUSED,
virNetlinkCallbackDataFree((virNetlinkCallbackDataPtr)opaque);
}
static int
virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
const unsigned char *macaddress,
const char *linkdev,
const unsigned char *vmuuid,
virNetDevVPortProfilePtr virtPortProfile,
enum virNetDevVPortProfileOp vmOp)
{
virNetlinkCallbackDataPtr calld = NULL;
if (virtPortProfile && virNetlinkEventServiceIsRunning()) {
if (VIR_ALLOC(calld) < 0)
goto memory_error;
if ((calld->cr_ifname = strdup(ifname)) == NULL)
goto memory_error;
if (VIR_ALLOC(calld->virtPortProfile) < 0)
goto memory_error;
memcpy(calld->virtPortProfile, virtPortProfile, sizeof(*virtPortProfile));
if (VIR_ALLOC_N(calld->macaddress, VIR_MAC_BUFLEN) < 0)
goto memory_error;
memcpy(calld->macaddress, macaddress, VIR_MAC_BUFLEN);
if ((calld->linkdev = strdup(linkdev)) == NULL)
goto memory_error;
if (VIR_ALLOC_N(calld->vmuuid, VIR_UUID_BUFLEN) < 0)
goto memory_error;
memcpy(calld->vmuuid, vmuuid, VIR_UUID_BUFLEN);
calld->vmOp = vmOp;
if (virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback,
virNetDevMacVLanVPortProfileDestroyCallback,
calld, macaddress) < 0)
goto error;
}
return 0;
memory_error:
virReportOOMError();
error:
virNetlinkCallbackDataFree(calld);
return -1;
}
/**
* virNetDevMacVLanCreateWithVPortProfile:
......@@ -795,7 +839,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
int retries, do_retry = 0;
uint32_t macvtapMode;
const char *cr_ifname;
virNetlinkCallbackDataPtr calld = NULL;
int ret;
int vf = -1;
......@@ -902,36 +945,12 @@ create_name:
goto disassociate_exit;
}
if (virtPortProfile && virNetlinkEventServiceIsRunning()) {
if (VIR_ALLOC(calld) < 0)
goto memory_error;
if ((calld->cr_ifname = strdup(cr_ifname)) == NULL)
goto memory_error;
if (VIR_ALLOC(calld->virtPortProfile) < 0)
goto memory_error;
memcpy(calld->virtPortProfile, virtPortProfile, sizeof(*virtPortProfile));
if (VIR_ALLOC_N(calld->macaddress, VIR_MAC_BUFLEN) < 0)
goto memory_error;
memcpy(calld->macaddress, macaddress, VIR_MAC_BUFLEN);
if ((calld->linkdev = strdup(linkdev)) == NULL)
goto memory_error;
if (VIR_ALLOC_N(calld->vmuuid, VIR_UUID_BUFLEN) < 0)
goto memory_error;
memcpy(calld->vmuuid, vmuuid, VIR_UUID_BUFLEN);
calld->vmOp = vmOp;
virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback,
virNetDevMacVLanVPortProfileDestroyCallback,
calld, macaddress);
}
if (virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, macaddress,
linkdev, vmuuid, virtPortProfile, vmOp) < 0 )
goto disassociate_exit;
return rc;
memory_error:
virReportOOMError();
virNetlinkCallbackDataFree(calld);
disassociate_exit:
ignore_value(virNetDevVPortProfileDisassociate(cr_ifname,
virtPortProfile,
......@@ -988,6 +1007,48 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
return ret;
}
/**
* virNetDevMacVLanRestartWithVPortProfile:
* Register a port profile callback handler for a VM that
* is already running
* .
* @cr_ifname: Interface name that the macvtap has.
* @macaddress: The MAC address for the macvtap device
* @linkdev: The interface name of the NIC to connect to the external bridge
* @vmuuid: The UUID of the VM the macvtap belongs to
* @virtPortProfile: pointer to object holding the virtual port profile data
* @vmOp: Operation to use during setup of the association
*
* Returns 0; returns -1 on error.
*/
int virNetDevMacVLanRestartWithVPortProfile(const char *cr_ifname,
const unsigned char *macaddress,
const char *linkdev,
const unsigned char *vmuuid,
virNetDevVPortProfilePtr virtPortProfile,
enum virNetDevVPortProfileOp vmOp)
{
int rc = 0;
rc = virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, macaddress,
linkdev, vmuuid,
virtPortProfile, vmOp);
if (rc < 0)
goto error;
ignore_value(virNetDevVPortProfileAssociate(cr_ifname,
virtPortProfile,
macaddress,
linkdev,
-1,
vmuuid,
vmOp, true));
error:
return rc;
}
#else /* ! WITH_MACVTAP */
int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED,
const char *type ATTRIBUTE_UNUSED,
......@@ -1037,4 +1098,16 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED,
_("Cannot create macvlan devices on this platform"));
return -1;
}
int virNetDevMacVLanRestartWithVPortProfile(const char *cr_ifname ATTRIBUTE_UNUSED,
const unsigned char *macaddress ATTRIBUTE_UNUSED,
const char *linkdev ATTRIBUTE_UNUSED,
const unsigned char *vmuuid ATTRIBUTE_UNUSED,
virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED,
enum virNetDevVPortProfileOp vmOp ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Cannot create macvlan devices on this platform"));
return -1;
}
#endif /* ! WITH_MACVTAP */
......@@ -75,4 +75,13 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(6) ATTRIBUTE_RETURN_CHECK;
int virNetDevMacVLanRestartWithVPortProfile(const char *cr_ifname,
const unsigned char *macaddress,
const char *linkdev,
const unsigned char *vmuuid,
virNetDevVPortProfilePtr virtPortProfile,
enum virNetDevVPortProfileOp vmOp)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
#endif /* __UTIL_MACVTAP_H__ */
......@@ -428,8 +428,11 @@ virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
int i, r, ret = -1;
virNetlinkEventSrvPrivatePtr srv = server;
if (handleCB == NULL)
if (handleCB == NULL) {
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Invalid NULL callback provided"));
return -1;
}
virNetlinkEventServerLock(srv);
......@@ -449,6 +452,7 @@ virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
srv->handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT);
if (VIR_RESIZE_N(srv->handles, srv->handlesAlloc,
srv->handlesCount, NETLINK_EVENT_ALLOC_EXTENT) < 0) {
virReportOOMError();
goto error;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册