提交 3df907bf 编写于 作者: D Daniel P. Berrangé

nwfilter: remove virt driver callback layer for rebuilding filters

Now that the nwfilter driver keeps a list of bindings that it has
created, there is no need for the complex virt driver callbacks. It is
possible to simply iterate of the list of recorded filter bindings.

This means that rebuilding filters no longer has to acquire any locks on
the virDomainObj objects, as they're never touched.
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
Signed-off-by: NDaniel P. Berrangé <berrange@redhat.com>
上级 57f5621f
......@@ -2819,121 +2819,6 @@ virNWFilterSaveConfig(const char *configDir,
}
int nCallbackDriver;
#define MAX_CALLBACK_DRIVER 10
static virNWFilterCallbackDriverPtr callbackDrvArray[MAX_CALLBACK_DRIVER];
void
virNWFilterRegisterCallbackDriver(virNWFilterCallbackDriverPtr cbd)
{
if (nCallbackDriver < MAX_CALLBACK_DRIVER)
callbackDrvArray[nCallbackDriver++] = cbd;
}
void
virNWFilterUnRegisterCallbackDriver(virNWFilterCallbackDriverPtr cbd)
{
size_t i = 0;
while (i < nCallbackDriver && callbackDrvArray[i] != cbd)
i++;
if (i < nCallbackDriver) {
memmove(&callbackDrvArray[i], &callbackDrvArray[i+1],
(nCallbackDriver - i - 1) * sizeof(callbackDrvArray[i]));
callbackDrvArray[i] = 0;
nCallbackDriver--;
}
}
void
virNWFilterCallbackDriversLock(void)
{
size_t i;
for (i = 0; i < nCallbackDriver; i++)
callbackDrvArray[i]->vmDriverLock();
}
void
virNWFilterCallbackDriversUnlock(void)
{
size_t i;
for (i = 0; i < nCallbackDriver; i++)
callbackDrvArray[i]->vmDriverUnlock();
}
static virDomainObjListIterator virNWFilterDomainFWUpdateCB;
static void *virNWFilterDomainFWUpdateOpaque;
/**
* virNWFilterInstFiltersOnAllVMs:
* Apply all filters on all running VMs. Don't terminate in case of an
* error. This should be called upon reloading of the driver.
*/
int
virNWFilterInstFiltersOnAllVMs(void)
{
size_t i;
struct domUpdateCBStruct cb = {
.opaque = virNWFilterDomainFWUpdateOpaque,
.step = STEP_APPLY_CURRENT,
.skipInterfaces = NULL, /* not needed */
};
for (i = 0; i < nCallbackDriver; i++)
callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
return 0;
}
int
virNWFilterTriggerVMFilterRebuild(void)
{
size_t i;
int ret = 0;
struct domUpdateCBStruct cb = {
.opaque = virNWFilterDomainFWUpdateOpaque,
.step = STEP_APPLY_NEW,
.skipInterfaces = virHashCreate(0, NULL),
};
if (!cb.skipInterfaces)
return -1;
for (i = 0; i < nCallbackDriver; i++) {
if (callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb) < 0)
ret = -1;
}
if (ret < 0) {
cb.step = STEP_TEAR_NEW; /* rollback */
for (i = 0; i < nCallbackDriver; i++)
callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
} else {
cb.step = STEP_TEAR_OLD; /* switch over */
for (i = 0; i < nCallbackDriver; i++)
callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
}
virHashFree(cb.skipInterfaces);
return ret;
}
int
virNWFilterDeleteDef(const char *configDir,
virNWFilterDefPtr def)
......@@ -3204,16 +3089,18 @@ virNWFilterDefFormat(const virNWFilterDef *def)
return NULL;
}
static virNWFilterTriggerRebuildCallback rebuildCallback;
static void *rebuildOpaque;
int
virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB,
virNWFilterConfLayerInit(virNWFilterTriggerRebuildCallback cb,
void *opaque)
{
if (initialized)
return -1;
virNWFilterDomainFWUpdateCB = domUpdateCB;
virNWFilterDomainFWUpdateOpaque = opaque;
rebuildCallback = cb;
rebuildOpaque = opaque;
initialized = true;
......@@ -3233,8 +3120,17 @@ virNWFilterConfLayerShutdown(void)
virRWLockDestroy(&updateLock);
initialized = false;
virNWFilterDomainFWUpdateOpaque = NULL;
virNWFilterDomainFWUpdateCB = NULL;
rebuildCallback = NULL;
rebuildOpaque = NULL;
}
int
virNWFilterTriggerRebuild(void)
{
if (rebuildCallback)
return rebuildCallback(rebuildOpaque);
return 0;
}
......
......@@ -546,20 +546,6 @@ struct _virNWFilterDef {
};
typedef enum {
STEP_APPLY_NEW,
STEP_TEAR_NEW,
STEP_TEAR_OLD,
STEP_APPLY_CURRENT,
} UpdateStep;
struct domUpdateCBStruct {
void *opaque;
UpdateStep step;
virHashTablePtr skipInterfaces;
};
void
virNWFilterRuleDefFree(virNWFilterRuleDefPtr def);
......@@ -567,7 +553,7 @@ void
virNWFilterDefFree(virNWFilterDefPtr def);
int
virNWFilterTriggerVMFilterRebuild(void);
virNWFilterTriggerRebuild(void);
int
virNWFilterDeleteDef(const char *configDir,
......@@ -599,44 +585,15 @@ virNWFilterReadLockFilterUpdates(void);
void
virNWFilterUnlockFilterUpdates(void);
typedef int (*virNWFilterTriggerRebuildCallback)(void *opaque);
int
virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB,
virNWFilterConfLayerInit(virNWFilterTriggerRebuildCallback cb,
void *opaque);
void
virNWFilterConfLayerShutdown(void);
int
virNWFilterInstFiltersOnAllVMs(void);
typedef int
(*virNWFilterRebuild)(virDomainObjListIterator domUpdateCB,
void *data);
typedef void
(*virNWFilterVoidCall)(void);
typedef struct _virNWFilterCallbackDriver virNWFilterCallbackDriver;
typedef virNWFilterCallbackDriver *virNWFilterCallbackDriverPtr;
struct _virNWFilterCallbackDriver {
const char *name;
virNWFilterRebuild vmFilterRebuild;
virNWFilterVoidCall vmDriverLock;
virNWFilterVoidCall vmDriverUnlock;
};
void
virNWFilterRegisterCallbackDriver(virNWFilterCallbackDriverPtr);
void
virNWFilterUnRegisterCallbackDriver(virNWFilterCallbackDriverPtr);
void
virNWFilterCallbackDriversLock(void);
void
virNWFilterCallbackDriversUnlock(void);
char *
virNWFilterPrintTCPFlags(uint8_t flags);
......
......@@ -276,7 +276,7 @@ virNWFilterObjTestUnassignDef(virNWFilterObjPtr obj)
obj->wantRemoved = true;
/* trigger the update on VMs referencing the filter */
if (virNWFilterTriggerVMFilterRebuild() < 0)
if (virNWFilterTriggerRebuild() < 0)
rc = -1;
obj->wantRemoved = false;
......@@ -358,7 +358,7 @@ virNWFilterObjListAssignDef(virNWFilterObjListPtr nwfilters,
obj->newDef = def;
/* trigger the update on VMs referencing the filter */
if (virNWFilterTriggerVMFilterRebuild() < 0) {
if (virNWFilterTriggerRebuild() < 0) {
obj->newDef = NULL;
virNWFilterObjUnlock(obj);
return NULL;
......
......@@ -787,8 +787,6 @@ virDomainNumatuneSpecifiedMaxNode;
# conf/nwfilter_conf.h
virNWFilterCallbackDriversLock;
virNWFilterCallbackDriversUnlock;
virNWFilterChainSuffixTypeToString;
virNWFilterConfLayerInit;
virNWFilterConfLayerShutdown;
......@@ -797,12 +795,10 @@ virNWFilterDefFree;
virNWFilterDefParseFile;
virNWFilterDefParseString;
virNWFilterDeleteDef;
virNWFilterInstFiltersOnAllVMs;
virNWFilterJumpTargetTypeToString;
virNWFilterPrintStateMatchFlags;
virNWFilterPrintTCPFlags;
virNWFilterReadLockFilterUpdates;
virNWFilterRegisterCallbackDriver;
virNWFilterRuleActionTypeToString;
virNWFilterRuleDirectionTypeToString;
virNWFilterRuleIsProtocolEthernet;
......@@ -810,9 +806,8 @@ virNWFilterRuleIsProtocolIPv4;
virNWFilterRuleIsProtocolIPv6;
virNWFilterRuleProtocolTypeToString;
virNWFilterSaveConfig;
virNWFilterTriggerVMFilterRebuild;
virNWFilterTriggerRebuild;
virNWFilterUnlockFilterUpdates;
virNWFilterUnRegisterCallbackDriver;
virNWFilterWriteLockFilterUpdates;
......
......@@ -66,7 +66,6 @@
#include "virfdstream.h"
#include "domain_audit.h"
#include "domain_nwfilter.h"
#include "nwfilter_conf.h"
#include "virinitctl.h"
#include "virnetdev.h"
#include "virnetdevtap.h"
......@@ -95,31 +94,6 @@ static int lxcStateInitialize(bool privileged,
static int lxcStateCleanup(void);
virLXCDriverPtr lxc_driver = NULL;
/* callbacks for nwfilter */
static int
lxcVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(lxc_driver->domains, iter, data);
}
static void
lxcVMDriverLock(void)
{
lxcDriverLock(lxc_driver);
}
static void
lxcVMDriverUnlock(void)
{
lxcDriverUnlock(lxc_driver);
}
static virNWFilterCallbackDriver lxcCallbackDriver = {
.name = "LXC",
.vmFilterRebuild = lxcVMFilterRebuild,
.vmDriverLock = lxcVMDriverLock,
.vmDriverUnlock = lxcVMDriverUnlock,
};
/**
* lxcDomObjFromDomain:
......@@ -1672,7 +1646,6 @@ static int lxcStateInitialize(bool privileged,
NULL, NULL) < 0)
goto cleanup;
virNWFilterRegisterCallbackDriver(&lxcCallbackDriver);
virObjectUnref(caps);
return 0;
......@@ -1744,7 +1717,6 @@ static int lxcStateCleanup(void)
if (lxc_driver == NULL)
return -1;
virNWFilterUnRegisterCallbackDriver(&lxcCallbackDriver);
virObjectUnref(lxc_driver->domains);
virObjectUnref(lxc_driver->domainEventState);
......
......@@ -163,6 +163,15 @@ nwfilterDriverInstallDBusMatches(DBusConnection *sysbus ATTRIBUTE_UNUSED)
#endif /* HAVE_FIREWALLD */
static int
virNWFilterTriggerRebuildImpl(void *opaque)
{
virNWFilterDriverStatePtr nwdriver = opaque;
return virNWFilterBuildAll(nwdriver, true);
}
/**
* nwfilterStateInitialize:
*
......@@ -207,7 +216,7 @@ nwfilterStateInitialize(bool privileged,
if (virNWFilterTechDriversInit(privileged) < 0)
goto err_dhcpsnoop_shutdown;
if (virNWFilterConfLayerInit(virNWFilterDomainFWUpdateCB,
if (virNWFilterConfLayerInit(virNWFilterTriggerRebuildImpl,
driver) < 0)
goto err_techdrivers_shutdown;
......@@ -302,15 +311,14 @@ nwfilterStateReload(void)
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
virNWFilterCallbackDriversLock();
virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->configDir);
virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
nwfilterDriverUnlock();
virNWFilterInstFiltersOnAllVMs();
virNWFilterBuildAll(driver, false);
nwfilterDriverUnlock();
return 0;
}
......@@ -547,7 +555,6 @@ nwfilterDefineXML(virConnectPtr conn,
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
virNWFilterCallbackDriversLock();
if (!(def = virNWFilterDefParseString(xml)))
goto cleanup;
......@@ -572,7 +579,6 @@ nwfilterDefineXML(virConnectPtr conn,
if (obj)
virNWFilterObjUnlock(obj);
virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
nwfilterDriverUnlock();
return nwfilter;
......@@ -588,7 +594,6 @@ nwfilterUndefine(virNWFilterPtr nwfilter)
nwfilterDriverLock();
virNWFilterWriteLockFilterUpdates();
virNWFilterCallbackDriversLock();
if (!(obj = nwfilterObjFromNWFilter(nwfilter->uuid)))
goto cleanup;
......@@ -615,7 +620,6 @@ nwfilterUndefine(virNWFilterPtr nwfilter)
if (obj)
virNWFilterObjUnlock(obj);
virNWFilterCallbackDriversUnlock();
virNWFilterUnlockFilterUpdates();
nwfilterDriverUnlock();
return ret;
......
......@@ -153,9 +153,9 @@ virNWFilterVarHashmapAddStdValues(virHashTablePtr table,
if (!val)
return -1;
if (virHashAddEntry(table,
NWFILTER_STD_VAR_MAC,
val) < 0) {
if (virHashUpdateEntry(table,
NWFILTER_STD_VAR_MAC,
val) < 0) {
virNWFilterVarValueFree(val);
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'MAC' to hashmap"));
......@@ -168,9 +168,9 @@ virNWFilterVarHashmapAddStdValues(virHashTablePtr table,
if (!val)
return -1;
if (virHashAddEntry(table,
NWFILTER_STD_VAR_IP,
val) < 0) {
if (virHashUpdateEntry(table,
NWFILTER_STD_VAR_IP,
val) < 0) {
virNWFilterVarValueFree(val);
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Could not add variable 'IP' to hashmap"));
......@@ -973,68 +973,113 @@ virNWFilterTeardownFilter(virNWFilterBindingDefPtr binding)
return ret;
}
enum {
STEP_APPLY_NEW,
STEP_ROLLBACK,
STEP_SWITCH,
STEP_APPLY_CURRENT,
};
int
virNWFilterDomainFWUpdateCB(virDomainObjPtr obj,
void *data)
static int
virNWFilterBuildOne(virNWFilterDriverStatePtr driver,
virNWFilterBindingDefPtr binding,
virHashTablePtr skipInterfaces,
int step)
{
virDomainDefPtr vm = obj->def;
struct domUpdateCBStruct *cb = data;
size_t i;
bool skipIface;
int ret = 0;
virObjectLock(obj);
if (virDomainObjIsActive(obj)) {
for (i = 0; i < vm->nnets; i++) {
virDomainNetDefPtr net = vm->nets[i];
virNWFilterBindingDefPtr binding;
if ((net->filter) && (net->ifname) &&
(binding = virNWFilterBindingDefForNet(
vm->name, vm->uuid, net))) {
switch (cb->step) {
case STEP_APPLY_NEW:
ret = virNWFilterUpdateInstantiateFilter(cb->opaque,
binding,
&skipIface);
if (ret == 0 && skipIface) {
/* filter tree unchanged -- no update needed */
ret = virHashAddEntry(cb->skipInterfaces,
net->ifname,
(void *)~0);
}
break;
case STEP_TEAR_NEW:
if (!virHashLookup(cb->skipInterfaces, net->ifname))
ret = virNWFilterRollbackUpdateFilter(binding);
break;
case STEP_TEAR_OLD:
if (!virHashLookup(cb->skipInterfaces, net->ifname))
ret = virNWFilterTearOldFilter(binding);
break;
case STEP_APPLY_CURRENT:
ret = virNWFilterInstantiateFilter(cb->opaque,
binding);
if (ret)
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failure while applying current filter on "
"VM %s"), vm->name);
break;
}
virNWFilterBindingDefFree(binding);
if (ret)
break;
}
VIR_DEBUG("Building filter for portdev=%s step=%d", binding->portdevname, step);
switch (step) {
case STEP_APPLY_NEW:
ret = virNWFilterUpdateInstantiateFilter(driver,
binding,
&skipIface);
if (ret == 0 && skipIface) {
/* filter tree unchanged -- no update needed */
ret = virHashAddEntry(skipInterfaces,
binding->portdevname,
(void *)~0);
}
break;
case STEP_ROLLBACK:
if (!virHashLookup(skipInterfaces, binding->portdevname))
ret = virNWFilterRollbackUpdateFilter(binding);
break;
case STEP_SWITCH:
if (!virHashLookup(skipInterfaces, binding->portdevname))
ret = virNWFilterTearOldFilter(binding);
break;
case STEP_APPLY_CURRENT:
ret = virNWFilterInstantiateFilter(driver,
binding);
break;
}
virObjectUnlock(obj);
return ret;
}
struct virNWFilterBuildData {
virNWFilterDriverStatePtr driver;
virHashTablePtr skipInterfaces;
int step;
};
static int
virNWFilterBuildIter(virNWFilterBindingObjPtr binding, void *opaque)
{
struct virNWFilterBuildData *data = opaque;
virNWFilterBindingDefPtr def = virNWFilterBindingObjGetDef(binding);
return virNWFilterBuildOne(data->driver, def,
data->skipInterfaces, data->step);
}
int
virNWFilterBuildAll(virNWFilterDriverStatePtr driver,
bool newFilters)
{
struct virNWFilterBuildData data = {
.driver = driver,
};
int ret = 0;
VIR_DEBUG("Build all filters newFilters=%d", newFilters);
if (newFilters) {
if (!(data.skipInterfaces = virHashCreate(0, NULL)))
return -1;
data.step = STEP_APPLY_NEW;
if (virNWFilterBindingObjListForEach(driver->bindings,
virNWFilterBuildIter,
&data) < 0)
ret = -1;
if (ret == -1) {
data.step = STEP_ROLLBACK;
virNWFilterBindingObjListForEach(driver->bindings,
virNWFilterBuildIter,
&data);
} else {
data.step = STEP_SWITCH;
virNWFilterBindingObjListForEach(driver->bindings,
virNWFilterBuildIter,
&data);
}
virHashFree(data.skipInterfaces);
} else {
data.step = STEP_APPLY_CURRENT;
if (virNWFilterBindingObjListForEach(driver->bindings,
virNWFilterBuildIter,
&data) < 0)
ret = -1;
}
return ret;
}
......
......@@ -54,8 +54,8 @@ int virNWFilterTeardownFilter(virNWFilterBindingDefPtr binding);
virHashTablePtr virNWFilterCreateVarHashmap(const char *macaddr,
const virNWFilterVarValue *value);
int virNWFilterDomainFWUpdateCB(virDomainObjPtr vm,
void *data);
int virNWFilterBuildAll(virNWFilterDriverStatePtr driver,
bool newFilters);
virNWFilterBindingDefPtr virNWFilterBindingDefForNet(const char *vmname,
const unsigned char *vmuuid,
......
......@@ -84,7 +84,6 @@
#include "cpu/cpu.h"
#include "virsysinfo.h"
#include "domain_nwfilter.h"
#include "nwfilter_conf.h"
#include "virhook.h"
#include "virstoragefile.h"
#include "virfile.h"
......@@ -164,28 +163,6 @@ static int qemuARPGetInterfaces(virDomainObjPtr vm,
static virQEMUDriverPtr qemu_driver;
static void
qemuVMDriverLock(void)
{}
static void
qemuVMDriverUnlock(void)
{}
static int
qemuVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(qemu_driver->domains, iter, data);
}
static virNWFilterCallbackDriver qemuCallbackDriver = {
.name = QEMU_DRIVER_NAME,
.vmFilterRebuild = qemuVMFilterRebuild,
.vmDriverLock = qemuVMDriverLock,
.vmDriverUnlock = qemuVMDriverUnlock,
};
/**
* qemuDomObjFromDomain:
* @domain: Domain pointer that has to be looked up
......@@ -941,7 +918,6 @@ qemuStateInitialize(bool privileged,
qemuProcessReconnectAll(qemu_driver);
virNWFilterRegisterCallbackDriver(&qemuCallbackDriver);
return 0;
error:
......@@ -1081,7 +1057,6 @@ qemuStateCleanup(void)
if (!qemu_driver)
return -1;
virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver);
virThreadPoolFree(qemu_driver->workerPool);
virObjectUnref(qemu_driver->config);
virObjectUnref(qemu_driver->hostdevMgr);
......
......@@ -55,7 +55,6 @@
#include "datatypes.h"
#include "virlog.h"
#include "domain_nwfilter.h"
#include "nwfilter_conf.h"
#include "virfile.h"
#include "virfdstream.h"
#include "configmake.h"
......@@ -143,25 +142,6 @@ static int umlMonitorCommand(const struct uml_driver *driver,
static struct uml_driver *uml_driver;
static int
umlVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(uml_driver->domains, iter, data);
}
static void
umlVMDriverLock(void)
{
umlDriverLock(uml_driver);
}
static void
umlVMDriverUnlock(void)
{
umlDriverUnlock(uml_driver);
}
static virDomainObjPtr
umlDomObjFromDomainLocked(struct uml_driver *driver,
const unsigned char *uuid)
......@@ -194,13 +174,6 @@ umlDomObjFromDomain(struct uml_driver *driver,
}
static virNWFilterCallbackDriver umlCallbackDriver = {
.name = "UML",
.vmFilterRebuild = umlVMFilterRebuild,
.vmDriverLock = umlVMDriverLock,
.vmDriverUnlock = umlVMDriverUnlock,
};
struct umlAutostartData {
struct uml_driver *driver;
virConnectPtr conn;
......@@ -604,7 +577,6 @@ umlStateInitialize(bool privileged,
VIR_FREE(userdir);
virNWFilterRegisterCallbackDriver(&umlCallbackDriver);
return 0;
out_of_memory:
......@@ -697,7 +669,6 @@ umlStateCleanup(void)
return -1;
umlDriverLock(uml_driver);
virNWFilterRegisterCallbackDriver(&umlCallbackDriver);
if (uml_driver->inotifyWatch != -1)
virEventRemoveHandle(uml_driver->inotifyWatch);
VIR_FORCE_CLOSE(uml_driver->inotifyFD);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册