/* Main driver state */
typedef struct
{
- virMutex lock;
+ virObjectLockable parent;
struct netcf *netcf;
} virNetcfDriverState, *virNetcfDriverStatePtr;
+static virClassPtr virNetcfDriverStateClass;
+static void virNetcfDriverStateDispose(void *obj);
-static void interfaceDriverLock(virNetcfDriverStatePtr driver)
+static int
+virNetcfDriverStateOnceInit(void)
+{
+ if (!(virNetcfDriverStateClass = virClassNew(virClassForObjectLockable(),
+ "virNetcfDriverState",
+ sizeof(virNetcfDriverState),
+ virNetcfDriverStateDispose)))
+ return -1;
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virNetcfDriverState)
+
+static virNetcfDriverStatePtr driverState = NULL;
+
+
+static void
+virNetcfDriverStateDispose(void *obj)
{
- virMutexLock(&driver->lock);
+ virNetcfDriverStatePtr driver = obj;
+
+ if (driver->netcf)
+ ncf_close(driver->netcf);
+}
+
+
+static int
+netcfStateInitialize(bool privileged ATTRIBUTE_UNUSED,
+ virStateInhibitCallback callback ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ if (virNetcfDriverStateInitialize() < 0)
+ return -1;
+
+ if (!(driverState = virObjectLockableNew(virNetcfDriverStateClass)))
+ return -1;
+
+ /* open netcf */
+ if (ncf_init(&driverState->netcf, NULL) != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to initialize netcf"));
+ virObjectUnref(driverState);
+ driverState = NULL;
+ return -1;
+ }
+ return 0;
}
-static void interfaceDriverUnlock(virNetcfDriverStatePtr driver)
+
+static int
+netcfStateCleanup(void)
{
- virMutexUnlock(&driver->lock);
+ if (!driverState) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Attempt to close netcf state driver already closed"));
+ return -1;
+ }
+
+ if (virObjectUnref(driverState)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Attempt to close netcf state driver "
+ "with open connections"));
+ return -1;
+ }
+ driverState = NULL;
+ return 0;
}
+
+static int
+netcfStateReload(void)
+{
+ int ret = -1;
+
+ if (!driverState)
+ return 0;
+
+ virObjectLock(driverState);
+ ncf_close(driverState->netcf);
+ if (ncf_init(&driverState->netcf, NULL) != 0)
+ {
+ /* this isn't a good situation, because we can't shut down the
+ * driver as there may still be connections to it. If we set
+ * the netcf handle to NULL, any subsequent calls to netcf
+ * will just fail rather than causing a crash. Not ideal, but
+ * livable (since this should never happen).
+ */
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to re-init netcf"));
+ driverState->netcf = NULL;
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ virObjectUnlock(driverState);
+
+ return ret;
+}
+
+
/*
* Get a minimal virInterfaceDef containing enough metadata
* for access control checks to be performed. Currently
return iface;
}
-static virDrvOpenStatus netcfInterfaceOpen(virConnectPtr conn,
- virConnectAuthPtr auth ATTRIBUTE_UNUSED,
- unsigned int flags)
+static virDrvOpenStatus
+netcfInterfaceOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags)
{
- virNetcfDriverStatePtr driverState;
-
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
- if (VIR_ALLOC(driverState) < 0)
- goto alloc_error;
-
- /* initialize non-0 stuff in driverState */
- if (virMutexInit(&driverState->lock) < 0)
- {
- /* what error to report? */
- goto mutex_error;
- }
-
- /* open netcf */
- if (ncf_init(&driverState->netcf, NULL) != 0)
- {
- /* what error to report? */
- goto netcf_error;
- }
+ if (!driverState)
+ return VIR_DRV_OPEN_ERROR;
+ virObjectRef(driverState);
conn->interfacePrivateData = driverState;
return VIR_DRV_OPEN_SUCCESS;
-
-netcf_error:
- if (driverState->netcf)
- {
- ncf_close(driverState->netcf);
- }
- virMutexDestroy(&driverState->lock);
-mutex_error:
- VIR_FREE(driverState);
-alloc_error:
- return VIR_DRV_OPEN_ERROR;
}
-static int netcfInterfaceClose(virConnectPtr conn)
+static int
+netcfInterfaceClose(virConnectPtr conn)
{
if (conn->interfacePrivateData != NULL)
{
- virNetcfDriverStatePtr driver = conn->interfacePrivateData;
-
- /* close netcf instance */
- ncf_close(driver->netcf);
- /* destroy lock */
- virMutexDestroy(&driver->lock);
- /* free driver state */
- VIR_FREE(driver);
+ virObjectUnref(conn->interfacePrivateData);
+ conn->interfacePrivateData = NULL;
}
- conn->interfacePrivateData = NULL;
return 0;
}
if (virConnectNumOfInterfacesEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
count = netcfConnectNumOfInterfacesImpl(conn,
NETCF_IFACE_ACTIVE,
virConnectNumOfInterfacesCheckACL);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return count;
}
if (virConnectListInterfacesEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
count = netcfConnectListInterfacesImpl(conn,
NETCF_IFACE_ACTIVE,
names, nnames,
virConnectListInterfacesCheckACL);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return count;
}
if (virConnectNumOfDefinedInterfacesEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
count = netcfConnectNumOfInterfacesImpl(conn,
NETCF_IFACE_INACTIVE,
virConnectNumOfDefinedInterfacesCheckACL);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return count;
}
if (virConnectListDefinedInterfacesEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
count = netcfConnectListInterfacesImpl(conn,
NETCF_IFACE_INACTIVE,
names, nnames,
virConnectListDefinedInterfacesCheckACL);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return count;
}
if (virConnectListAllInterfacesEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
/* List all interfaces, in case of we might support new filter flags
* except active|inactive in future.
VIR_FREE(tmp_iface_objs);
}
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virInterfacePtr ret = NULL;
virInterfaceDefPtr def = NULL;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = ncf_lookup_by_name(driver->netcf, name);
if (!iface) {
const char *errmsg, *details;
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virInterfacePtr ret = NULL;
virInterfaceDefPtr def = NULL;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
niface = ncf_lookup_by_mac_string(driver->netcf, macstr, 1, &iface);
if (niface < 0) {
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL);
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
if (!iface) {
ncf_if_free(iface);
VIR_FREE(xmlstr);
virInterfaceDefFree(ifacedef);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virCheckFlags(0, NULL);
- interfaceDriverLock(driver);
+ virObjectLock(driver);
ifacedef = virInterfaceDefParseString(xml);
if (!ifacedef) {
ncf_if_free(iface);
VIR_FREE(xmlstr);
virInterfaceDefFree(ifacedef);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virInterfaceDefPtr def = NULL;
int ret = -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
if (!iface) {
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virCheckFlags(0, -1);
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
if (!iface) {
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virCheckFlags(0, -1);
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
if (!iface) {
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
virInterfaceDefPtr def = NULL;
int ret = -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo);
if (!iface) {
cleanup:
ncf_if_free(iface);
virInterfaceDefFree(def);
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
if (virInterfaceChangeBeginEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
ret = ncf_change_begin(driver->netcf, 0);
if (ret < 0) {
details ? details : "");
}
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
if (virInterfaceChangeCommitEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
ret = ncf_change_commit(driver->netcf, 0);
if (ret < 0) {
details ? details : "");
}
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
if (virInterfaceChangeRollbackEnsureACL(conn) < 0)
return -1;
- interfaceDriverLock(driver);
+ virObjectLock(driver);
ret = ncf_change_rollback(driver->netcf, 0);
if (ret < 0) {
details ? details : "");
}
- interfaceDriverUnlock(driver);
+ virObjectUnlock(driver);
return ret;
}
#endif /* HAVE_NETCF_TRANSACTIONS */
static virInterfaceDriver interfaceDriver = {
- "netcf",
+ .name = INTERFACE_DRIVER_NAME,
.interfaceOpen = netcfInterfaceOpen, /* 0.7.0 */
.interfaceClose = netcfInterfaceClose, /* 0.7.0 */
.connectNumOfInterfaces = netcfConnectNumOfInterfaces, /* 0.7.0 */
#endif /* HAVE_NETCF_TRANSACTIONS */
};
+static virStateDriver interfaceStateDriver = {
+ .name = INTERFACE_DRIVER_NAME,
+ .stateInitialize = netcfStateInitialize,
+ .stateCleanup = netcfStateCleanup,
+ .stateReload = netcfStateReload,
+};
+
int netcfIfaceRegister(void) {
if (virRegisterInterfaceDriver(&interfaceDriver) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to register netcf interface driver"));
return -1;
}
+ virRegisterStateDriver(&interfaceStateDriver);
return 0;
}