bhyve: don't leak tap devices on failures

On failures, virBhyveProcessStart() does not cleanup network
interfaces that could be created by virBhyveProcessBuildBhyveCmd(),
which results in a leaked tap device.

To fix that, extract network cleanup code to bhyveNetCleanup()
and use it in cleanup stage of virBhyveProcessStart().
This commit is contained in:
Roman Bogorodskiy 2014-03-30 16:23:47 +04:00
parent 4ef09c4690
commit 1d8be34334

View File

@ -63,6 +63,24 @@ bhyveProcessAutoDestroy(virDomainObjPtr vm,
return vm; return vm;
} }
static void
bhyveNetCleanup(virDomainObjPtr vm)
{
size_t i;
for (i = 0; i < vm->def->nnets; i++) {
virDomainNetDefPtr net = vm->def->nets[i];
int actualType = virDomainNetGetActualType(net);
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
ignore_value(virNetDevBridgeRemovePort(
virDomainNetGetActualBridgeName(net),
net->ifname));
ignore_value(virNetDevTapDelete(net->ifname));
}
}
}
int int
virBhyveProcessStart(virConnectPtr conn, virBhyveProcessStart(virConnectPtr conn,
bhyveConnPtr driver, bhyveConnPtr driver,
@ -167,6 +185,8 @@ virBhyveProcessStart(virConnectPtr conn,
ignore_value(virCommandRun(destroy_cmd, NULL)); ignore_value(virCommandRun(destroy_cmd, NULL));
virCommandFree(destroy_cmd); virCommandFree(destroy_cmd);
} }
bhyveNetCleanup(vm);
} }
virCommandFree(load_cmd); virCommandFree(load_cmd);
@ -181,7 +201,6 @@ virBhyveProcessStop(bhyveConnPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainShutoffReason reason ATTRIBUTE_UNUSED) virDomainShutoffReason reason ATTRIBUTE_UNUSED)
{ {
size_t i;
int ret = -1; int ret = -1;
virCommandPtr cmd = NULL; virCommandPtr cmd = NULL;
@ -203,17 +222,8 @@ virBhyveProcessStop(bhyveConnPtr driver,
vm->def->name, vm->def->name,
(int)vm->pid); (int)vm->pid);
for (i = 0; i < vm->def->nnets; i++) { /* Cleanup network interfaces */
virDomainNetDefPtr net = vm->def->nets[i]; bhyveNetCleanup(vm);
int actualType = virDomainNetGetActualType(net);
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
ignore_value(virNetDevBridgeRemovePort(
virDomainNetGetActualBridgeName(net),
net->ifname));
ignore_value(virNetDevTapDelete(net->ifname));
}
}
/* No matter if shutdown was successful or not, we /* No matter if shutdown was successful or not, we
* need to unload the VM */ * need to unload the VM */