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

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


On 12.09.2012 18:28, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> Add two new APIs virNetSocketNewPostExecRestart and
> virNetSocketPreExecRestart which allow a virNetSocketPtr
> object to be created from a JSON object and saved to a
> JSON object, for the purpose of re-exec'ing a process.
> 
> As well as saving the state in JSON format, the second
> method will disable the O_CLOEXEC flag so that the open
> file descriptors are preserved across the process re-exec()
> 
> Since it is not possible to serialize SASL or TLS encryption
> state, an error will be raised if attempting to perform
> serialization on non-raw sockets
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  src/libvirt_private.syms |   2 +
>  src/rpc/virnetsocket.c   | 108 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/rpc/virnetsocket.h   |   6 +++
>  3 files changed, 116 insertions(+)

ACK


> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 6c94584..73e89e0 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1633,6 +1633,8 @@ virNetSocketNewConnectUNIX;
>  virNetSocketNewListenFD;
>  virNetSocketNewListenTCP;
>  virNetSocketNewListenUNIX;
> +virNetSocketNewPostExecRestart;
> +virNetSocketPreExecRestart;
>  virNetSocketRead;
>  virNetSocketRecvFD;
>  virNetSocketRemoteAddrString;
> diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
> index 5a48300..6bff170 100644
> --- a/src/rpc/virnetsocket.c
> +++ b/src/rpc/virnetsocket.c
> @@ -881,6 +881,114 @@ int virNetSocketNewConnectExternal(const char **cmdargv,
>  }
>  
>  
> +virNetSocketPtr virNetSocketNewPostExecRestart(virJSONValuePtr object)
> +{
> +    virSocketAddr localAddr;
> +    virSocketAddr remoteAddr;
> +    int fd, thepid, errfd;
> +    bool isClient;
> +
> +    if (virJSONValueObjectGetNumberInt(object, "fd", &fd) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Missing fd data in JSON document"));
> +        return NULL;
> +    }
> +
> +    if (virJSONValueObjectGetNumberInt(object, "pid", &thepid) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Missing pid data in JSON document"));
> +        return NULL;
> +    }
> +
> +    if (virJSONValueObjectGetNumberInt(object, "errfd", &errfd) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Missing errfd data in JSON document"));
> +        return NULL;
> +    }
> +    if (virJSONValueObjectGetBoolean(object, "isClient", &isClient) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("Missing isClient data in JSON document"));
> +        return NULL;
> +    }
> +
> +    memset(&localAddr, 0, sizeof(localAddr));
> +    memset(&remoteAddr, 0, sizeof(remoteAddr));
> +
> +    remoteAddr.len = sizeof(remoteAddr.data.stor);
> +    if (getsockname(fd, &remoteAddr.data.sa, &remoteAddr.len) < 0) {
> +        virReportSystemError(errno, "%s", _("Unable to get peer socket name"));
> +        return NULL;
> +    }
> +
> +    localAddr.len = sizeof(localAddr.data.stor);
> +    if (getsockname(fd, &localAddr.data.sa, &localAddr.len) < 0) {
> +        virReportSystemError(errno, "%s", _("Unable to get local socket name"));
> +        return NULL;
> +    }
> +
> +    return virNetSocketNew(&localAddr, &remoteAddr,
> +                           isClient, fd, errfd, thepid);
> +}
> +
> +
> +virJSONValuePtr virNetSocketPreExecRestart(virNetSocketPtr sock)
> +{
> +    virJSONValuePtr object = NULL;
> +
> +    virMutexLock(&sock->lock);
> +
> +#if HAVE_SASL
> +    if (sock->saslSession) {
> +        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                       _("Unable to save socket state when SASL session is active"));
> +        goto error;
> +    }
> +#endif
> +    if (sock->tlsSession) {
> +        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                       _("Unable to save socket state when TLS session is active"));
> +        goto error;
> +    }
> +
> +    if (!(object = virJSONValueNewObject()))
> +        goto error;
> +
> +    if (virJSONValueObjectAppendNumberInt(object, "fd", sock->fd) < 0)
> +        goto error;
> +
> +    if (virJSONValueObjectAppendNumberInt(object, "errfd", sock->errfd) < 0)
> +        goto error;
> +
> +    if (virJSONValueObjectAppendNumberInt(object, "pid", sock->pid) < 0)
> +        goto error;
> +
> +    if (virJSONValueObjectAppendBoolean(object, "isClient", sock->client) < 0)
> +        goto error;
> +
> +    if (virSetInherit(sock->fd, true) < 0) {
> +        virReportSystemError(errno,
> +                             _("Cannot disable close-on-exec flag on socket %d"),
> +                             sock->fd);
> +        goto error;
> +    }
> +    if (sock->errfd != -1 &&
> +        virSetInherit(sock->errfd, true) < 0) {
> +        virReportSystemError(errno,
> +                             _("Cannot disable close-on-exec flag on pipe %d"),
> +                             sock->errfd);
> +        goto error;
> +    }
> +
> +    virMutexUnlock(&sock->lock);
> +    return object;
> +
> +error:
> +    virMutexUnlock(&sock->lock);
> +    virJSONValueFree(object);
> +    return NULL;
> +}
> +
> +
>  void virNetSocketDispose(void *obj)
>  {
>      virNetSocketPtr sock = obj;
> diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
> index 75b66c5..604103b 100644
> --- a/src/rpc/virnetsocket.h
> +++ b/src/rpc/virnetsocket.h
> @@ -31,6 +31,7 @@
>  # ifdef HAVE_SASL
>  #  include "virnetsaslcontext.h"
>  # endif
> +# include "json.h"
>  
>  typedef struct _virNetSocket virNetSocket;
>  typedef virNetSocket *virNetSocketPtr;
> @@ -93,6 +94,11 @@ int virNetSocketNewConnectLibSSH2(const char *host,
>  int virNetSocketNewConnectExternal(const char **cmdargv,
>                                     virNetSocketPtr *addr);
>  
> +
> +virNetSocketPtr virNetSocketNewPostExecRestart(virJSONValuePtr object);
> +
> +virJSONValuePtr virNetSocketPreExecRestart(virNetSocketPtr sock);
> +
>  int virNetSocketGetFD(virNetSocketPtr sock);
>  int virNetSocketDupFD(virNetSocketPtr sock, bool cloexec);
>  
> 




More information about the libvir-list mailing list