From: Daniel P. Berrange Date: Thu, 9 Aug 2012 11:54:54 +0000 (+0100) Subject: Add JSON serialization of virNetServerServicePtr objects for process re-exec() X-Git-Tag: v1.0.0-rc1~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0cc79255;p=thirdparty%2Flibvirt.git Add JSON serialization of virNetServerServicePtr objects for process re-exec() Add two new APIs virNetServerServiceNewPostExecRestart and virNetServerServicePreExecRestart which allow a virNetServerServicePtr 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 listening sockets associated with the service Signed-off-by: Daniel P. Berrange --- diff --git a/po/POTFILES.in b/po/POTFILES.in index 23f675d5e8..66779dd87e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -103,6 +103,7 @@ src/rpc/virnetserver.c src/rpc/virnetserverclient.c src/rpc/virnetservermdns.c src/rpc/virnetserverprogram.c +src/rpc/virnetserverservice.c src/rpc/virnetsshsession.c src/rpc/virnettlscontext.c src/secret/secret_driver.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b0f6c81e1b..3f9d96cff9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1638,8 +1638,10 @@ virNetServerServiceGetPort; virNetServerServiceGetTLSContext; virNetServerServiceIsReadonly; virNetServerServiceNewFD; +virNetServerServiceNewPostExecRestart; virNetServerServiceNewTCP; virNetServerServiceNewUNIX; +virNetServerServicePreExecRestart; virNetServerServiceSetDispatcher; virNetServerServiceToggle; diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c index 4d5896a653..8ac523cde2 100644 --- a/src/rpc/virnetserverservice.c +++ b/src/rpc/virnetserverservice.c @@ -250,6 +250,130 @@ error: } +virNetServerServicePtr virNetServerServiceNewPostExecRestart(virJSONValuePtr object) +{ + virNetServerServicePtr svc; + virJSONValuePtr socks; + size_t i; + int n; + + if (virNetServerServiceInitialize() < 0) + return NULL; + + if (!(svc = virObjectNew(virNetServerServiceClass))) + return NULL; + + if (virJSONValueObjectGetNumberInt(object, "auth", &svc->auth) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing auth field in JSON state document")); + goto error; + } + if (virJSONValueObjectGetBoolean(object, "readonly", &svc->readonly) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing readonly field in JSON state document")); + goto error; + } + if (virJSONValueObjectGetNumberUint(object, "nrequests_client_max", + (unsigned int *)&svc->nrequests_client_max) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing nrequests_client_max field in JSON state document")); + goto error; + } + + if (!(socks = virJSONValueObjectGet(object, "socks"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing socks field in JSON state document")); + goto error; + } + + if ((n = virJSONValueArraySize(socks)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("socks field in JSON was not an array")); + goto error; + } + + svc->nsocks = n; + if (VIR_ALLOC_N(svc->socks, svc->nsocks) < 0) { + virReportOOMError(); + goto error; + } + + for (i = 0 ; i < svc->nsocks ; i++) { + virJSONValuePtr child = virJSONValueArrayGet(socks, i); + virNetSocketPtr sock; + + if (!(sock = virNetSocketNewPostExecRestart(child))) { + virObjectUnref(sock); + goto error; + } + + svc->socks[i] = sock; + + /* IO callback is initially disabled, until we're ready + * to deal with incoming clients */ + virObjectRef(svc); + if (virNetSocketAddIOCallback(sock, + 0, + virNetServerServiceAccept, + svc, + virObjectFreeCallback) < 0) { + virObjectUnref(svc); + virObjectUnref(sock); + goto error; + } + } + + return svc; + +error: + virObjectUnref(svc); + return NULL; +} + + +virJSONValuePtr virNetServerServicePreExecRestart(virNetServerServicePtr svc) +{ + virJSONValuePtr object = virJSONValueNewObject(); + virJSONValuePtr socks; + size_t i; + + if (!object) + return NULL; + + if (!(socks = virJSONValueNewArray())) + goto error; + + if (virJSONValueObjectAppendNumberInt(object, "auth", svc->auth) < 0) + goto error; + if (virJSONValueObjectAppendBoolean(object, "readonly", svc->readonly) < 0) + goto error; + if (virJSONValueObjectAppendNumberUint(object, "nrequests_client_max", svc->nrequests_client_max) < 0) + goto error; + + if (virJSONValueObjectAppend(object, "socks", socks) < 0) { + virJSONValueFree(socks); + goto error; + } + + for (i = 0 ; i < svc->nsocks ; i++) { + virJSONValuePtr child; + if (!(child = virNetSocketPreExecRestart(svc->socks[i]))) + goto error; + + if (virJSONValueArrayAppend(socks, child) < 0) { + virJSONValueFree(child); + goto error; + } + } + + return object; + +error: + virJSONValueFree(object); + return NULL; +} + + int virNetServerServiceGetPort(virNetServerServicePtr svc) { /* We're assuming if there are multiple sockets diff --git a/src/rpc/virnetserverservice.h b/src/rpc/virnetserverservice.h index 3fe089be4a..615b572c1a 100644 --- a/src/rpc/virnetserverservice.h +++ b/src/rpc/virnetserverservice.h @@ -56,6 +56,10 @@ virNetServerServicePtr virNetServerServiceNewFD(int fd, size_t nrequests_client_max, virNetTLSContextPtr tls); +virNetServerServicePtr virNetServerServiceNewPostExecRestart(virJSONValuePtr object); + +virJSONValuePtr virNetServerServicePreExecRestart(virNetServerServicePtr service); + int virNetServerServiceGetPort(virNetServerServicePtr svc); int virNetServerServiceGetAuth(virNetServerServicePtr svc);