diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index b49acc5bde315173da2ab12bca617a90614dae0d..d2e0a046be4951e9fb3d10afcee1d534e4a980a9 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1216,6 +1216,7 @@ int main(int argc, char **argv) { !!config->keepalive_required, config->mdns_adv ? config->mdns_name : NULL, remoteClientInitHook, + NULL, remoteClientFreeFunc, NULL))) { ret = VIR_DAEMON_ERR_INIT; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3f9d96cff91222ee8339468740036d5cf4c7748b..8b18813016f009ffa08974156d9af4b25f300660 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1594,6 +1594,8 @@ virNetServerClientIsSecure; virNetServerClientLocalAddrString; virNetServerClientNeedAuth; virNetServerClientNew; +virNetServerClientNewPostExecRestart; +virNetServerClientPreExecRestart; virNetServerClientRemoteAddrString; virNetServerClientRemoveFilter; virNetServerClientSendMessage; diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 68f857a13807ef9edb669b39295a8dddd2080bb9..a41c9037c65591e9278c3167587d1f655ebc85d1 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -609,6 +609,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl) -1, 0, false, NULL, virLXCControllerClientPrivateNew, + NULL, virLXCControllerClientPrivateFree, ctrl))) goto error; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index ae4ed46fb0666aa3b686e07bb7bffdc63862fd0e..13a7758646670df011fa75b1a92a80a311126ddb 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -105,6 +105,7 @@ struct _virNetServer { void *autoShutdownOpaque; virNetServerClientPrivNew clientPrivNew; + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart; virFreeCallback clientPrivFree; void *clientPrivOpaque; }; @@ -309,6 +310,7 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc, virNetServerServiceGetMaxRequests(svc), virNetServerServiceGetTLSContext(svc), srv->clientPrivNew, + srv->clientPrivPreExecRestart, srv->clientPrivFree, srv->clientPrivOpaque))) return -1; @@ -360,6 +362,7 @@ virNetServerPtr virNetServerNew(size_t min_workers, bool keepaliveRequired, const char *mdnsGroupName, virNetServerClientPrivNew clientPrivNew, + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, virFreeCallback clientPrivFree, void *clientPrivOpaque) { @@ -385,6 +388,7 @@ virNetServerPtr virNetServerNew(size_t min_workers, srv->keepaliveRequired = keepaliveRequired; srv->sigwrite = srv->sigread = -1; srv->clientPrivNew = clientPrivNew; + srv->clientPrivPreExecRestart = clientPrivPreExecRestart; srv->clientPrivFree = clientPrivFree; srv->clientPrivOpaque = clientPrivOpaque; srv->privileged = geteuid() == 0 ? true : false; diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 3fe9e8ccea447f2ce8b940c225cd4a30d73c60c9..81819e794f0b3f9868e375a877a220020225054f 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -41,6 +41,7 @@ virNetServerPtr virNetServerNew(size_t min_workers, bool keepaliveRequired, const char *mdnsGroupName, virNetServerClientPrivNew clientPrivNew, + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, virFreeCallback clientPrivFree, void *clientPrivOpaque); diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index 59cba9adbbfd507ee19c64f155156c8c08dc91da..2777e6690a4d36fa279b0b5da3a15eaff3ed0966 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -98,6 +98,7 @@ struct _virNetServerClient void *privateData; virFreeCallback privateDataFreeFunc; + virNetServerClientPrivPreExecRestart privateDataPreExecRestart; virNetServerClientCloseFunc privateDataCloseFunc; virKeepAlivePtr keepalive; @@ -395,6 +396,7 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, size_t nrequests_max, virNetTLSContextPtr tls, virNetServerClientPrivNew privNew, + virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, void *privOpaque) { @@ -411,12 +413,145 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, return NULL; } client->privateDataFreeFunc = privFree; + client->privateDataPreExecRestart = privPreExecRestart; } return client; } +virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr object, + virNetServerClientPrivNewPostExecRestart privNew, + virNetServerClientPrivPreExecRestart privPreExecRestart, + virFreeCallback privFree, + void *privOpaque) +{ + virJSONValuePtr child; + virNetServerClientPtr client = NULL; + virNetSocketPtr sock; + const char *identity = NULL; + int auth; + bool readonly; + unsigned int nrequests_max; + + if (virJSONValueObjectGetNumberInt(object, "auth", &auth) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing auth field in JSON state document")); + return NULL; + } + if (virJSONValueObjectGetBoolean(object, "readonly", &readonly) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing readonly field in JSON state document")); + return NULL; + } + if (virJSONValueObjectGetNumberUint(object, "nrequests_max", + (unsigned int *)&nrequests_max) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing nrequests_client_max field in JSON state document")); + return NULL; + } + if (virJSONValueObjectHasKey(object, "identity") && + (!(identity = virJSONValueObjectGetString(object, "identity")))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing identity field in JSON state document")); + return NULL; + } + + if (!(child = virJSONValueObjectGet(object, "sock"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing sock field in JSON state document")); + return NULL; + } + + if (!(sock = virNetSocketNewPostExecRestart(child))) { + virObjectUnref(sock); + return NULL; + } + + if (!(client = virNetServerClientNewInternal(sock, + auth, + readonly, + nrequests_max, + NULL))) { + virObjectUnref(sock); + return NULL; + } + virObjectUnref(sock); + + if (identity && + virNetServerClientSetIdentity(client, identity) < 0) + goto error; + + if (privNew) { + if (!(child = virJSONValueObjectGet(object, "privateData"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing privateData field in JSON state document")); + goto error; + } + if (!(client->privateData = privNew(client, child, privOpaque))) { + goto error; + } + client->privateDataFreeFunc = privFree; + client->privateDataPreExecRestart = privPreExecRestart; + } + + + return client; + +error: + virObjectUnref(client); + return NULL; +} + + +virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client) +{ + virJSONValuePtr object = virJSONValueNewObject(); + virJSONValuePtr child; + + if (!object) + return NULL; + + virNetServerClientLock(client); + + if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0) + goto error; + if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0) + goto error; + if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0) + goto error; + + if (client->identity && + virJSONValueObjectAppendString(object, "identity", client->identity) < 0) + goto error; + + if (!(child = virNetSocketPreExecRestart(client->sock))) + goto error; + + if (virJSONValueObjectAppend(object, "sock", child) < 0) { + virJSONValueFree(child); + goto error; + } + + if (client->privateData && client->privateDataPreExecRestart && + !(child = client->privateDataPreExecRestart(client, client->privateData))) + goto error; + + if (virJSONValueObjectAppend(object, "privateData", child) < 0) { + virJSONValueFree(child); + goto error; + } + + virNetServerClientUnlock(client); + return object; + +error: + virNetServerClientUnlock(client); + virJSONValueFree(object); + return NULL; +} + + int virNetServerClientGetAuth(virNetServerClientPtr client) { int auth; diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 3ce1889367eee44df07fc52aaca408e23dd25b0c..041ffde5152868f4d0e0e3fe82446049ee2d389b 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -27,6 +27,7 @@ # include "virnetsocket.h" # include "virnetmessage.h" # include "virobject.h" +# include "json.h" typedef struct _virNetServerClient virNetServerClient; typedef virNetServerClient *virNetServerClientPtr; @@ -39,6 +40,11 @@ typedef int (*virNetServerClientFilterFunc)(virNetServerClientPtr client, virNetMessagePtr msg, void *opaque); +typedef virJSONValuePtr (*virNetServerClientPrivPreExecRestart)(virNetServerClientPtr client, + void *data); +typedef void *(*virNetServerClientPrivNewPostExecRestart)(virNetServerClientPtr client, + virJSONValuePtr object, + void *opaque); typedef void *(*virNetServerClientPrivNew)(virNetServerClientPtr client, void *opaque); @@ -48,9 +54,18 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, size_t nrequests_max, virNetTLSContextPtr tls, virNetServerClientPrivNew privNew, + virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, void *privOpaque); +virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr object, + virNetServerClientPrivNewPostExecRestart privNew, + virNetServerClientPrivPreExecRestart privPreExecRestart, + virFreeCallback privFree, + void *privOpaque); + +virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client); + int virNetServerClientAddFilter(virNetServerClientPtr client, virNetServerClientFilterFunc func, void *opaque);