[libvirt] [PATCH 04/12] Add JSON serialization of virNetServerServicePtr objects for process re-exec()

Michal Privoznik mprivozn at redhat.com
Fri Oct 5 11:25:34 UTC 2012


On 12.09.2012 18:28, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> 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 at redhat.com>
> ---
>  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);
> 




More information about the libvir-list mailing list