From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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 <berrange@xxxxxxxxxx> --- po/POTFILES.in | 1 + src/libvirt_private.syms | 2 + src/rpc/virnetserverservice.c | 124 ++++++++++++++++++++++++++++++++++++++++++ src/rpc/virnetserverservice.h | 4 ++ 4 files changed, 131 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index c5f4cf7..e8101a4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -101,6 +101,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 73e89e0..b847f46 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1604,8 +1604,10 @@ virNetServerServiceGetPort; virNetServerServiceGetTLSContext; virNetServerServiceIsReadonly; virNetServerServiceNewFD; +virNetServerServiceNewPostExecRestart; virNetServerServiceNewTCP; virNetServerServiceNewUNIX; +virNetServerServicePreExecRestart; virNetServerServiceSetDispatcher; virNetServerServiceToggle; diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c index 53ff503..c31bff3 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; + } + + for (i = 0 ; i < n ; i++) { + virJSONValuePtr child = virJSONValueArrayGet(socks, i); + virNetSocketPtr sock; + + if (!(sock = virNetSocketNewPostExecRestart(child))) { + virObjectUnref(sock); + goto error; + } + + if (VIR_EXPAND_N(svc->socks, svc->nsocks, 1) < 0) { + virReportOOMError(); + virObjectUnref(sock); + goto error; + } + + svc->socks[svc->nsocks-1] = 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 (virJSONValueObjectAppendNumberInt(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 48f49e7..344d20c 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); -- 1.7.11.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list