On 12.09.2012 18:28, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > Add two new APIs virNetServerClientNewPostExecRestart and > virNetServerClientPreExecRestart which allow a virNetServerClientPtr > object to be created from a JSON object and saved to a > JSON object, for the purpose of re-exec'ing a process. > > This includes serialization of the connected socket associated > with the client > > Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> > --- > daemon/libvirtd.c | 1 + > src/libvirt_private.syms | 2 + > src/lxc/lxc_controller.c | 1 + > src/rpc/virnetserver.c | 4 ++ > src/rpc/virnetserver.h | 1 + > src/rpc/virnetserverclient.c | 135 +++++++++++++++++++++++++++++++++++++++++++ > src/rpc/virnetserverclient.h | 15 +++++ > 7 files changed, 159 insertions(+) ACK > > diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c > index 6973df6..5696073 100644 > --- a/daemon/libvirtd.c > +++ b/daemon/libvirtd.c > @@ -1204,6 +1204,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 b847f46..004a8da 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -1560,6 +1560,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 e5aea11..74bf7ac 100644 > --- a/src/lxc/lxc_controller.c > +++ b/src/lxc/lxc_controller.c > @@ -616,6 +616,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 0a6ecdc..902c34e 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; > }; > @@ -312,6 +313,7 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc, > virNetServerServiceGetMaxRequests(svc), > virNetServerServiceGetTLSContext(svc), > srv->clientPrivNew, > + srv->clientPrivPreExecRestart, > srv->clientPrivFree, > srv->clientPrivOpaque))) > return -1; > @@ -363,6 +365,7 @@ virNetServerPtr virNetServerNew(size_t min_workers, > bool keepaliveRequired, > const char *mdnsGroupName, > virNetServerClientPrivNew clientPrivNew, > + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, > virFreeCallback clientPrivFree, > void *clientPrivOpaque) > { > @@ -388,6 +391,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 9188072..778b069 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 acd2b4d..661242a 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 f950c61..2a2413b 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); > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list