]> xenbits.xensource.com Git - libvirt.git/commitdiff
close callback: move it to driver
authorNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Tue, 1 Mar 2016 14:17:38 +0000 (14:17 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 1 Mar 2016 14:17:38 +0000 (14:17 +0000)
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
src/datatypes.c
src/datatypes.h
src/driver-hypervisor.h
src/libvirt-host.c
src/remote/remote_driver.c

index f9f0b5666cdfbf84726ffd882e451a31d0bcf19f..163db398bfa1830fd9b2f64b5eb03a9a538c5e33 100644 (file)
@@ -118,22 +118,10 @@ VIR_ONCE_GLOBAL_INIT(virDataTypes)
 virConnectPtr
 virGetConnect(void)
 {
-    virConnectPtr ret;
-
     if (virDataTypesInitialize() < 0)
         return NULL;
 
-    if (!(ret = virObjectLockableNew(virConnectClass)))
-        return NULL;
-
-    if (!(ret->closeCallback = virObjectLockableNew(virConnectCloseCallbackDataClass)))
-        goto error;
-
-    return ret;
-
- error:
-    virObjectUnref(ret);
-    return NULL;
+    return virObjectLockableNew(virConnectClass);
 }
 
 /**
@@ -154,14 +142,6 @@ virConnectDispose(void *obj)
     virResetError(&conn->err);
 
     virURIFree(conn->uri);
-
-    if (conn->closeCallback) {
-        virObjectLock(conn->closeCallback);
-        conn->closeCallback->callback = NULL;
-        virObjectUnlock(conn->closeCallback);
-
-        virObjectUnref(conn->closeCallback);
-    }
 }
 
 
@@ -189,6 +169,15 @@ virConnectCloseCallbackDataDispose(void *obj)
     virConnectCloseCallbackDataReset(obj);
 }
 
+virConnectCloseCallbackDataPtr
+virNewConnectCloseCallbackData(void)
+{
+    if (virDataTypesInitialize() < 0)
+        return NULL;
+
+    return virObjectLockableNew(virConnectCloseCallbackDataClass);
+}
+
 void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close,
                                          virConnectPtr conn,
                                          virConnectCloseFunc cb,
index 238317a9e3b23d29bea6fa8781908ece62de0a46..92e686371b24a29e5fe5ae15b61dc578e39c2b4c 100644 (file)
@@ -421,9 +421,6 @@ struct _virConnect {
     virError err;           /* the last error */
     virErrorFunc handler;   /* associated handler */
     void *userData;         /* the user data */
-
-    /* Per-connection close callback */
-    virConnectCloseCallbackDataPtr closeCallback;
 };
 
 /**
@@ -640,6 +637,7 @@ virAdmConnectPtr virAdmConnectNew(void);
 virAdmServerPtr virAdmGetServer(virAdmConnectPtr conn,
                                 const char *name);
 
+virConnectCloseCallbackDataPtr virNewConnectCloseCallbackData(void);
 void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close,
                                          virConnectPtr conn,
                                          virConnectCloseFunc cb,
index ae2ec4d4565769de99aab5ca3efd9e2f1400ee7a..2cbd01bb20ba18be91879d318c1c980ee2f39203 100644 (file)
@@ -1212,6 +1212,16 @@ typedef int
                                const char *password,
                                unsigned int flags);
 
+typedef int
+(*virDrvConnectRegisterCloseCallback)(virConnectPtr conn,
+                                      virConnectCloseFunc cb,
+                                      void *opaque,
+                                      virFreeCallback freecb);
+
+typedef int
+(*virDrvConnectUnregisterCloseCallback)(virConnectPtr conn,
+                                        virConnectCloseFunc cb);
+
 typedef struct _virHypervisorDriver virHypervisorDriver;
 typedef virHypervisorDriver *virHypervisorDriverPtr;
 
@@ -1443,6 +1453,8 @@ struct _virHypervisorDriver {
     virDrvDomainGetFSInfo domainGetFSInfo;
     virDrvDomainInterfaceAddresses domainInterfaceAddresses;
     virDrvDomainSetUserPassword domainSetUserPassword;
+    virDrvConnectRegisterCloseCallback connectRegisterCloseCallback;
+    virDrvConnectUnregisterCloseCallback connectUnregisterCloseCallback;
 };
 
 
index b0597ee2fbf38d8dbd0deba5b114f7b207d421ce..24277b71b75cde7066e8e9b671784f42264f48bb 100644 (file)
@@ -1217,14 +1217,9 @@ virConnectRegisterCloseCallback(virConnectPtr conn,
     virCheckConnectReturn(conn, -1);
     virCheckNonNullArgGoto(cb, error);
 
-    if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != NULL) {
-        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("A close callback is already registered"));
+    if (conn->driver->connectRegisterCloseCallback &&
+        conn->driver->connectRegisterCloseCallback(conn, cb, opaque, freecb) < 0)
         goto error;
-    }
-
-    virConnectCloseCallbackDataRegister(conn->closeCallback, conn, cb,
-                                        opaque, freecb);
 
     return 0;
 
@@ -1257,13 +1252,9 @@ virConnectUnregisterCloseCallback(virConnectPtr conn,
     virCheckConnectReturn(conn, -1);
     virCheckNonNullArgGoto(cb, error);
 
-    if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != cb) {
-        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("A different callback was requested"));
+    if (conn->driver->connectUnregisterCloseCallback &&
+        conn->driver->connectUnregisterCloseCallback(conn, cb) < 0)
         goto error;
-    }
-
-    virConnectCloseCallbackDataUnregister(conn->closeCallback, cb);
 
     return 0;
 
index e0cf33fdc3fa800d99944f53010a3230faf04802..b5b7063d96c80b4cebf1b9a192d7a9657edcaaf9 100644 (file)
@@ -96,6 +96,7 @@ struct private_data {
     bool serverEventFilter;     /* Does server support modern event filtering */
 
     virObjectEventStatePtr eventState;
+    virConnectCloseCallbackDataPtr closeCallback;
 };
 
 enum {
@@ -963,11 +964,13 @@ doRemoteOpen(virConnectPtr conn,
             goto failed;
     }
 
-    virObjectRef(conn->closeCallback);
-
+    if (!(priv->closeCallback = virNewConnectCloseCallbackData()))
+        goto failed;
+    // ref on behalf of netclient
+    virObjectRef(priv->closeCallback);
     virNetClientSetCloseCallback(priv->client,
                                  remoteClientCloseFunc,
-                                 conn->closeCallback, virObjectFreeCallback);
+                                 priv->closeCallback, virObjectFreeCallback);
 
     if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM,
                                                        REMOTE_PROTOCOL_VERSION,
@@ -1097,6 +1100,8 @@ doRemoteOpen(virConnectPtr conn,
     virNetClientClose(priv->client);
     virObjectUnref(priv->client);
     priv->client = NULL;
+    virObjectUnref(priv->closeCallback);
+    priv->closeCallback = NULL;
 #ifdef WITH_GNUTLS
     virObjectUnref(priv->tls);
     priv->tls = NULL;
@@ -1229,11 +1234,13 @@ doRemoteClose(virConnectPtr conn, struct private_data *priv)
 
     virNetClientSetCloseCallback(priv->client,
                                  NULL,
-                                 conn->closeCallback, virObjectFreeCallback);
+                                 priv->closeCallback, virObjectFreeCallback);
 
     virNetClientClose(priv->client);
     virObjectUnref(priv->client);
     priv->client = NULL;
+    virObjectUnref(priv->closeCallback);
+    priv->closeCallback = NULL;
     virObjectUnref(priv->remoteProgram);
     virObjectUnref(priv->lxcProgram);
     virObjectUnref(priv->qemuProgram);
@@ -7887,6 +7894,56 @@ remoteDomainInterfaceAddresses(virDomainPtr dom,
     return rv;
 }
 
+static int
+remoteConnectRegisterCloseCallback(virConnectPtr conn,
+                                   virConnectCloseFunc cb,
+                                   void *opaque,
+                                   virFreeCallback freecb)
+{
+    struct private_data *priv = conn->privateData;
+    int ret = -1;
+
+    remoteDriverLock(priv);
+
+    if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != NULL) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A close callback is already registered"));
+        goto cleanup;
+    }
+
+    virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
+                                        opaque, freecb);
+    ret = 0;
+
+ cleanup:
+    remoteDriverUnlock(priv);
+
+    return ret;
+}
+
+static int
+remoteConnectUnregisterCloseCallback(virConnectPtr conn,
+                                     virConnectCloseFunc cb)
+{
+    struct private_data *priv = conn->privateData;
+    int ret = -1;
+
+    remoteDriverLock(priv);
+
+    if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != cb) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A different callback was requested"));
+        goto cleanup;
+    }
+
+    virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
+    ret = 0;
+
+ cleanup:
+    remoteDriverUnlock(priv);
+
+    return ret;
+}
 
 static int
 remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
@@ -8279,6 +8336,8 @@ static virHypervisorDriver hypervisor_driver = {
     .domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */
     .domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */
     .domainRename = remoteDomainRename, /* 1.2.19 */
+    .connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */
+    .connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */
 };
 
 static virNetworkDriver network_driver = {