[libvirt] [PATCH libvirt v2 6/9] remote/rpc: Use virNetServerGetProgram() to determine the program

Marc Hartmayer mhartmay at linux.vnet.ibm.com
Thu Apr 12 12:41:01 UTC 2018


Use virNetServerGetProgram() to determine the virNetServerProgram
instead of using hard coded global variables. This allows us to remove
the global variables @remoteProgram and @qemuProgram as they're now no
longer necessary.

Signed-off-by: Marc Hartmayer <mhartmay at linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy at linux.ibm.com>
---

Note: I'm not 100% sure that there is no case where the lock for
@client is already held by the thread which is calling
virNetServerGetProgram and thus the lock order would be violated (the
lock order has to be @server -> @client in the violating case it would
be @client -> @server and therefore a deadlock might occur).

---
 src/libvirt_remote.syms             |   1 +
 src/remote/remote_daemon.c          |   4 +-
 src/remote/remote_daemon.h          |   3 -
 src/remote/remote_daemon_dispatch.c | 116 +++++++++++++++++++++++++++---------
 src/rpc/gendispatch.pl              |   6 ++
 src/rpc/virnetserver.c              |  23 +++++++
 src/rpc/virnetserver.h              |   2 +
 7 files changed, 122 insertions(+), 33 deletions(-)

diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
index 97e22275b980..c31b16cd5909 100644
--- a/src/libvirt_remote.syms
+++ b/src/libvirt_remote.syms
@@ -120,6 +120,7 @@ virNetServerGetCurrentUnauthClients;
 virNetServerGetMaxClients;
 virNetServerGetMaxUnauthClients;
 virNetServerGetName;
+virNetServerGetProgram;
 virNetServerGetThreadPoolParameters;
 virNetServerHasClients;
 virNetServerNew;
diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c
index 31c6ce1b6179..f854a1a6981e 100644
--- a/src/remote/remote_daemon.c
+++ b/src/remote/remote_daemon.c
@@ -71,8 +71,6 @@ VIR_LOG_INIT("daemon.libvirtd");
 #if WITH_SASL
 virNetSASLContextPtr saslCtxt = NULL;
 #endif
-virNetServerProgramPtr remoteProgram = NULL;
-virNetServerProgramPtr qemuProgram = NULL;
 
 volatile bool driversInitialized = false;
 
@@ -1049,6 +1047,8 @@ int main(int argc, char **argv) {
     virNetServerPtr srv = NULL;
     virNetServerPtr srvAdm = NULL;
     virNetServerProgramPtr adminProgram = NULL;
+    virNetServerProgramPtr qemuProgram = NULL;
+    virNetServerProgramPtr remoteProgram = NULL;
     virNetServerProgramPtr lxcProgram = NULL;
     char *remote_config_file = NULL;
     int statuswrite = -1;
diff --git a/src/remote/remote_daemon.h b/src/remote/remote_daemon.h
index 2834da04a9ae..a2eda209683b 100644
--- a/src/remote/remote_daemon.h
+++ b/src/remote/remote_daemon.h
@@ -88,7 +88,4 @@ struct daemonClientPrivate {
 # if WITH_SASL
 extern virNetSASLContextPtr saslCtxt;
 # endif
-extern virNetServerProgramPtr remoteProgram;
-extern virNetServerProgramPtr qemuProgram;
-
 #endif /* __REMOTE_DAEMON_H__ */
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index cf2cd0add7d6..94b9cc3377d8 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -3830,15 +3830,16 @@ remoteDispatchNodeDeviceGetParent(virNetServerPtr server ATTRIBUTE_UNUSED,
 }
 
 static int
-remoteDispatchConnectRegisterCloseCallback(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectRegisterCloseCallback(virNetServerPtr server,
                                            virNetServerClientPtr client,
-                                           virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                           virNetMessagePtr msg,
                                            virNetMessageErrorPtr rerr)
 {
     int rv = -1;
     daemonClientEventCallbackPtr callback = NULL;
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
+    virNetServerProgramPtr program;
 
     virMutexLock(&priv->lock);
 
@@ -3847,10 +3848,15 @@ remoteDispatchConnectRegisterCloseCallback(virNetServerPtr server ATTRIBUTE_UNUS
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     /* eventID, callbackID, and legacy are not used */
     callback->eventID = -1;
     callback->callbackID = -1;
@@ -3903,9 +3909,9 @@ remoteDispatchConnectUnregisterCloseCallback(virNetServerPtr server ATTRIBUTE_UN
 }
 
 static int
-remoteDispatchConnectDomainEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectDomainEventRegister(virNetServerPtr server,
                                          virNetServerClientPtr client,
-                                         virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                         virNetMessagePtr msg,
                                          virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                          remote_connect_domain_event_register_ret *ret ATTRIBUTE_UNUSED)
 {
@@ -3915,12 +3921,18 @@ remoteDispatchConnectDomainEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED
     daemonClientEventCallbackPtr ref;
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
+    virNetServerProgramPtr program;
 
     if (!priv->conn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     /* If we call register first, we could append a complete callback
@@ -3934,7 +3946,7 @@ remoteDispatchConnectDomainEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = VIR_DOMAIN_EVENT_ID_LIFECYCLE;
     callback->callbackID = -1;
     callback->legacy = true;
@@ -4132,9 +4144,9 @@ remoteDispatchDomainGetState(virNetServerPtr server ATTRIBUTE_UNUSED,
  * VIR_DRV_SUPPORTS_FEATURE(VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK),
  * and must not mix the two styles.  */
 static int
-remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server,
                                             virNetServerClientPtr client,
-                                            virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                            virNetMessagePtr msg,
                                             virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                             remote_connect_domain_event_register_any_args *args)
 {
@@ -4144,12 +4156,18 @@ remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNU
     daemonClientEventCallbackPtr ref;
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
+    virNetServerProgramPtr program;
 
     if (!priv->conn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     /* We intentionally do not use VIR_DOMAIN_EVENT_ID_LAST here; any
@@ -4171,7 +4189,7 @@ remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNU
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     callback->legacy = true;
@@ -4207,9 +4225,9 @@ remoteDispatchConnectDomainEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNU
 
 
 static int
-remoteDispatchConnectDomainEventCallbackRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectDomainEventCallbackRegisterAny(virNetServerPtr server,
                                                     virNetServerClientPtr client,
-                                                    virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                                    virNetMessagePtr msg,
                                                     virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                                     remote_connect_domain_event_callback_register_any_args *args,
                                                     remote_connect_domain_event_callback_register_any_ret *ret)
@@ -4221,12 +4239,18 @@ remoteDispatchConnectDomainEventCallbackRegisterAny(virNetServerPtr server ATTRI
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virDomainPtr dom = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->conn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->dom &&
@@ -4248,7 +4272,7 @@ remoteDispatchConnectDomainEventCallbackRegisterAny(virNetServerPtr server ATTRI
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     ref = callback;
@@ -5355,6 +5379,7 @@ remoteDispatchDomainMigratePrepareTunnel3Params(virNetServerPtr server ATTRIBUTE
         virNetServerClientGetPrivateData(client);
     virStreamPtr st = NULL;
     daemonClientStreamPtr stream = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->conn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
@@ -5373,8 +5398,13 @@ remoteDispatchDomainMigratePrepareTunnel3Params(virNetServerPtr server ATTRIBUTE
                                   0, &params, &nparams) < 0)
         goto cleanup;
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     if (!(st = virStreamNew(priv->conn, VIR_STREAM_NONBLOCK)) ||
-        !(stream = daemonCreateClientStream(client, st, remoteProgram,
+        !(stream = daemonCreateClientStream(client, st, program,
                                             &msg->header, false)))
         goto cleanup;
 
@@ -5731,9 +5761,9 @@ static int remoteDispatchDomainCreateWithFiles(virNetServerPtr server ATTRIBUTE_
 
 
 static int
-remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server,
                                              virNetServerClientPtr client,
-                                             virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                             virNetMessagePtr msg,
                                              virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                              remote_connect_network_event_register_any_args *args,
                                              remote_connect_network_event_register_any_ret *ret)
@@ -5745,12 +5775,18 @@ remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UN
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virNetworkPtr net = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->networkConn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->net &&
@@ -5772,7 +5808,7 @@ remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UN
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     ref = callback;
@@ -5854,9 +5890,9 @@ remoteDispatchConnectNetworkEventDeregisterAny(virNetServerPtr server ATTRIBUTE_
 }
 
 static int
-remoteDispatchConnectStoragePoolEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectStoragePoolEventRegisterAny(virNetServerPtr server,
                                                  virNetServerClientPtr client,
-                                                 virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                                 virNetMessagePtr msg,
                                                  virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                                  remote_connect_storage_pool_event_register_any_args *args,
                                                  remote_connect_storage_pool_event_register_any_ret *ret)
@@ -5868,12 +5904,18 @@ remoteDispatchConnectStoragePoolEventRegisterAny(virNetServerPtr server ATTRIBUT
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virStoragePoolPtr  pool = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->storageConn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->pool &&
@@ -5895,7 +5937,7 @@ remoteDispatchConnectStoragePoolEventRegisterAny(virNetServerPtr server ATTRIBUT
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     ref = callback;
@@ -5976,9 +6018,9 @@ remoteDispatchConnectStoragePoolEventDeregisterAny(virNetServerPtr server ATTRIB
 }
 
 static int
-remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server,
                                                 virNetServerClientPtr client,
-                                                virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                                virNetMessagePtr msg,
                                                 virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                                 remote_connect_node_device_event_register_any_args *args,
                                                 remote_connect_node_device_event_register_any_ret *ret)
@@ -5990,12 +6032,18 @@ remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server ATTRIBUTE
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virNodeDevicePtr  dev = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->nodedevConn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->dev &&
@@ -6017,7 +6065,7 @@ remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server ATTRIBUTE
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     ref = callback;
@@ -6098,9 +6146,9 @@ remoteDispatchConnectNodeDeviceEventDeregisterAny(virNetServerPtr server ATTRIBU
 }
 
 static int
-remoteDispatchConnectSecretEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
+remoteDispatchConnectSecretEventRegisterAny(virNetServerPtr server,
                                             virNetServerClientPtr client,
-                                            virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                            virNetMessagePtr msg,
                                             virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                             remote_connect_secret_event_register_any_args *args,
                                             remote_connect_secret_event_register_any_ret *ret)
@@ -6112,12 +6160,18 @@ remoteDispatchConnectSecretEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNU
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
     virSecretPtr secret = NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->secretConn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->secret &&
@@ -6139,7 +6193,7 @@ remoteDispatchConnectSecretEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNU
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(remoteProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = args->eventID;
     callback->callbackID = -1;
     ref = callback;
@@ -6220,9 +6274,9 @@ remoteDispatchConnectSecretEventDeregisterAny(virNetServerPtr server ATTRIBUTE_U
 }
 
 static int
-qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
+qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server,
                                               virNetServerClientPtr client,
-                                              virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                              virNetMessagePtr msg,
                                               virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
                                               qemu_connect_domain_monitor_event_register_args *args,
                                               qemu_connect_domain_monitor_event_register_ret *ret)
@@ -6235,12 +6289,18 @@ qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server ATTRIBUTE_U
         virNetServerClientGetPrivateData(client);
     virDomainPtr dom = NULL;
     const char *event = args->event ? *args->event : NULL;
+    virNetServerProgramPtr program;
 
     if (!priv->conn) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
         goto cleanup;
     }
 
+    if (!(program = virNetServerGetProgram(server, msg))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no matching program found"));
+        goto cleanup;
+    }
+
     virMutexLock(&priv->lock);
 
     if (args->dom &&
@@ -6256,7 +6316,7 @@ qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server ATTRIBUTE_U
     if (VIR_ALLOC(callback) < 0)
         goto cleanup;
     callback->client = virObjectRef(client);
-    callback->program = virObjectRef(qemuProgram);
+    callback->program = virObjectRef(program);
     callback->eventID = -1;
     callback->callbackID = -1;
     ref = callback;
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index b8b83b6b40d3..ad442182d3c8 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -1039,6 +1039,7 @@ elsif ($mode eq "server") {
         if ($call->{streamflag} ne "none") {
             print "    virStreamPtr st = NULL;\n";
             print "    daemonClientStreamPtr stream = NULL;\n";
+            print "    virNetServerProgramPtr remoteProgram;\n";
             if ($call->{sparseflag} ne "none") {
                 print "    const bool sparse = args->flags & $call->{sparseflag};\n"
             } else {
@@ -1081,6 +1082,11 @@ elsif ($mode eq "server") {
             print "    if (!(st = virStreamNew($conn, VIR_STREAM_NONBLOCK)))\n";
             print "        goto cleanup;\n";
             print "\n";
+            print "    if (!(remoteProgram = virNetServerGetProgram(server, msg))) {\n";
+            print "        virReportError(VIR_ERR_INTERNAL_ERROR, \"%s\", _(\"no matching program found\"));\n";
+            print "        goto cleanup;\n";
+            print "    }\n";
+            print "\n";
             print "    if (!(stream = daemonCreateClientStream(client, st, remoteProgram, &msg->header, sparse)))\n";
             print "        goto cleanup;\n";
             print "\n";
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index ef214980b297..47ce88392b24 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -205,6 +205,29 @@ virNetServerGetProgramLocked(virNetServerPtr srv,
 }
 
 
+/**
+ * virNetServerGetProgram:
+ * @srv: server (must NOT be locked by the caller)
+ * @msg: message
+ *
+ * Searches @srv for the right program for a given message @msg.
+ *
+ * Returns a pointer to the server program or NULL if not found.
+ */
+virNetServerProgramPtr
+virNetServerGetProgram(virNetServerPtr srv,
+                       virNetMessagePtr msg)
+{
+    virNetServerProgramPtr ret;
+
+    virObjectLock(srv);
+    ret = virNetServerGetProgramLocked(srv, msg);
+    virObjectUnlock(srv);
+
+    return ret;
+}
+
+
 static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
                                            virNetMessagePtr msg,
                                            void *opaque)
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index a79c39fdb2e7..1867e46664ba 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -76,6 +76,8 @@ int virNetServerSetTLSContext(virNetServerPtr srv,
                               virNetTLSContextPtr tls);
 # endif
 
+virNetServerProgramPtr virNetServerGetProgram(virNetServerPtr srv,
+                                              virNetMessagePtr msg);
 
 int virNetServerAddClient(virNetServerPtr srv,
                           virNetServerClientPtr client);
-- 
2.13.4




More information about the libvir-list mailing list