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@xxxxxxxxxxxxxxxxxx> Reviewed-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx> --- 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, ¶ms, &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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list