On 12.09.2012 18:28, Daniel P. Berrange wrote: > 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(+) ACK but see my comments below > > 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; > + } Again, it's better to alloc mem at one if we know the desired size. > + > + 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) This should be AppendNumberUInt() > + 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); > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list