[libvirt] [PATCH 05/12] Add JSON serialization of virNetServerClientPtr objects for process re-exec()
Michal Privoznik
mprivozn at redhat.com
Fri Oct 5 11:25:23 UTC 2012
On 12.09.2012 18:28, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
>
> Add two new APIs virNetServerClientNewPostExecRestart and
> virNetServerClientPreExecRestart which allow a virNetServerClientPtr
> 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 connected socket associated
> with the client
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> daemon/libvirtd.c | 1 +
> src/libvirt_private.syms | 2 +
> src/lxc/lxc_controller.c | 1 +
> src/rpc/virnetserver.c | 4 ++
> src/rpc/virnetserver.h | 1 +
> src/rpc/virnetserverclient.c | 135 +++++++++++++++++++++++++++++++++++++++++++
> src/rpc/virnetserverclient.h | 15 +++++
> 7 files changed, 159 insertions(+)
ACK
>
> diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
> index 6973df6..5696073 100644
> --- a/daemon/libvirtd.c
> +++ b/daemon/libvirtd.c
> @@ -1204,6 +1204,7 @@ int main(int argc, char **argv) {
> !!config->keepalive_required,
> config->mdns_adv ? config->mdns_name : NULL,
> remoteClientInitHook,
> + NULL,
> remoteClientFreeFunc,
> NULL))) {
> ret = VIR_DAEMON_ERR_INIT;
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index b847f46..004a8da 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1560,6 +1560,8 @@ virNetServerClientIsSecure;
> virNetServerClientLocalAddrString;
> virNetServerClientNeedAuth;
> virNetServerClientNew;
> +virNetServerClientNewPostExecRestart;
> +virNetServerClientPreExecRestart;
> virNetServerClientRemoteAddrString;
> virNetServerClientRemoveFilter;
> virNetServerClientSendMessage;
> diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
> index e5aea11..74bf7ac 100644
> --- a/src/lxc/lxc_controller.c
> +++ b/src/lxc/lxc_controller.c
> @@ -616,6 +616,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
> -1, 0, false,
> NULL,
> virLXCControllerClientPrivateNew,
> + NULL,
> virLXCControllerClientPrivateFree,
> ctrl)))
> goto error;
> diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
> index 0a6ecdc..902c34e 100644
> --- a/src/rpc/virnetserver.c
> +++ b/src/rpc/virnetserver.c
> @@ -105,6 +105,7 @@ struct _virNetServer {
> void *autoShutdownOpaque;
>
> virNetServerClientPrivNew clientPrivNew;
> + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
> virFreeCallback clientPrivFree;
> void *clientPrivOpaque;
> };
> @@ -312,6 +313,7 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc,
> virNetServerServiceGetMaxRequests(svc),
> virNetServerServiceGetTLSContext(svc),
> srv->clientPrivNew,
> + srv->clientPrivPreExecRestart,
> srv->clientPrivFree,
> srv->clientPrivOpaque)))
> return -1;
> @@ -363,6 +365,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
> bool keepaliveRequired,
> const char *mdnsGroupName,
> virNetServerClientPrivNew clientPrivNew,
> + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
> virFreeCallback clientPrivFree,
> void *clientPrivOpaque)
> {
> @@ -388,6 +391,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
> srv->keepaliveRequired = keepaliveRequired;
> srv->sigwrite = srv->sigread = -1;
> srv->clientPrivNew = clientPrivNew;
> + srv->clientPrivPreExecRestart = clientPrivPreExecRestart;
> srv->clientPrivFree = clientPrivFree;
> srv->clientPrivOpaque = clientPrivOpaque;
> srv->privileged = geteuid() == 0 ? true : false;
> diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
> index 9188072..778b069 100644
> --- a/src/rpc/virnetserver.h
> +++ b/src/rpc/virnetserver.h
> @@ -41,6 +41,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
> bool keepaliveRequired,
> const char *mdnsGroupName,
> virNetServerClientPrivNew clientPrivNew,
> + virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
> virFreeCallback clientPrivFree,
> void *clientPrivOpaque);
>
> diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
> index acd2b4d..661242a 100644
> --- a/src/rpc/virnetserverclient.c
> +++ b/src/rpc/virnetserverclient.c
> @@ -98,6 +98,7 @@ struct _virNetServerClient
>
> void *privateData;
> virFreeCallback privateDataFreeFunc;
> + virNetServerClientPrivPreExecRestart privateDataPreExecRestart;
> virNetServerClientCloseFunc privateDataCloseFunc;
>
> virKeepAlivePtr keepalive;
> @@ -395,6 +396,7 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
> size_t nrequests_max,
> virNetTLSContextPtr tls,
> virNetServerClientPrivNew privNew,
> + virNetServerClientPrivPreExecRestart privPreExecRestart,
> virFreeCallback privFree,
> void *privOpaque)
> {
> @@ -411,12 +413,145 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
> return NULL;
> }
> client->privateDataFreeFunc = privFree;
> + client->privateDataPreExecRestart = privPreExecRestart;
> }
>
> return client;
> }
>
>
> +virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr object,
> + virNetServerClientPrivNewPostExecRestart privNew,
> + virNetServerClientPrivPreExecRestart privPreExecRestart,
> + virFreeCallback privFree,
> + void *privOpaque)
> +{
> + virJSONValuePtr child;
> + virNetServerClientPtr client = NULL;
> + virNetSocketPtr sock;
> + const char *identity = NULL;
> + int auth;
> + bool readonly;
> + unsigned int nrequests_max;
> +
> + if (virJSONValueObjectGetNumberInt(object, "auth", &auth) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing auth field in JSON state document"));
> + return NULL;
> + }
> + if (virJSONValueObjectGetBoolean(object, "readonly", &readonly) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing readonly field in JSON state document"));
> + return NULL;
> + }
> + if (virJSONValueObjectGetNumberUint(object, "nrequests_max",
> + (unsigned int *)&nrequests_max) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing nrequests_client_max field in JSON state document"));
> + return NULL;
> + }
> + if (virJSONValueObjectHasKey(object, "identity") &&
> + (!(identity = virJSONValueObjectGetString(object, "identity")))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing identity field in JSON state document"));
> + return NULL;
> + }
> +
> + if (!(child = virJSONValueObjectGet(object, "sock"))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing sock field in JSON state document"));
> + return NULL;
> + }
> +
> + if (!(sock = virNetSocketNewPostExecRestart(child))) {
> + virObjectUnref(sock);
> + return NULL;
> + }
> +
> + if (!(client = virNetServerClientNewInternal(sock,
> + auth,
> + readonly,
> + nrequests_max,
> + NULL))) {
> + virObjectUnref(sock);
> + return NULL;
> + }
> + virObjectUnref(sock);
> +
> + if (identity &&
> + virNetServerClientSetIdentity(client, identity) < 0)
> + goto error;
> +
> + if (privNew) {
> + if (!(child = virJSONValueObjectGet(object, "privateData"))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing privateData field in JSON state document"));
> + goto error;
> + }
> + if (!(client->privateData = privNew(client, child, privOpaque))) {
> + goto error;
> + }
> + client->privateDataFreeFunc = privFree;
> + client->privateDataPreExecRestart = privPreExecRestart;
> + }
> +
> +
> + return client;
> +
> +error:
> + virObjectUnref(client);
> + return NULL;
> +}
> +
> +
> +virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client)
> +{
> + virJSONValuePtr object = virJSONValueNewObject();
> + virJSONValuePtr child;
> +
> + if (!object)
> + return NULL;
> +
> + virNetServerClientLock(client);
> +
> + if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0)
> + goto error;
> + if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0)
> + goto error;
> + if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0)
> + goto error;
> +
> + if (client->identity &&
> + virJSONValueObjectAppendString(object, "identity", client->identity) < 0)
> + goto error;
> +
> + if (!(child = virNetSocketPreExecRestart(client->sock)))
> + goto error;
> +
> + if (virJSONValueObjectAppend(object, "sock", child) < 0) {
> + virJSONValueFree(child);
> + goto error;
> + }
> +
> + if (client->privateData && client->privateDataPreExecRestart &&
> + !(child = client->privateDataPreExecRestart(client, client->privateData)))
> + goto error;
> +
> + if (virJSONValueObjectAppend(object, "privateData", child) < 0) {
> + virJSONValueFree(child);
> + goto error;
> + }
> +
> + virNetServerClientUnlock(client);
> + return object;
> +
> +error:
> + virNetServerClientUnlock(client);
> + virJSONValueFree(object);
> + return NULL;
> +}
> +
> +
> int virNetServerClientGetAuth(virNetServerClientPtr client)
> {
> int auth;
> diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
> index f950c61..2a2413b 100644
> --- a/src/rpc/virnetserverclient.h
> +++ b/src/rpc/virnetserverclient.h
> @@ -27,6 +27,7 @@
> # include "virnetsocket.h"
> # include "virnetmessage.h"
> # include "virobject.h"
> +# include "json.h"
>
> typedef struct _virNetServerClient virNetServerClient;
> typedef virNetServerClient *virNetServerClientPtr;
> @@ -39,6 +40,11 @@ typedef int (*virNetServerClientFilterFunc)(virNetServerClientPtr client,
> virNetMessagePtr msg,
> void *opaque);
>
> +typedef virJSONValuePtr (*virNetServerClientPrivPreExecRestart)(virNetServerClientPtr client,
> + void *data);
> +typedef void *(*virNetServerClientPrivNewPostExecRestart)(virNetServerClientPtr client,
> + virJSONValuePtr object,
> + void *opaque);
> typedef void *(*virNetServerClientPrivNew)(virNetServerClientPtr client,
> void *opaque);
>
> @@ -48,9 +54,18 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock,
> size_t nrequests_max,
> virNetTLSContextPtr tls,
> virNetServerClientPrivNew privNew,
> + virNetServerClientPrivPreExecRestart privPreExecRestart,
> virFreeCallback privFree,
> void *privOpaque);
>
> +virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr object,
> + virNetServerClientPrivNewPostExecRestart privNew,
> + virNetServerClientPrivPreExecRestart privPreExecRestart,
> + virFreeCallback privFree,
> + void *privOpaque);
> +
> +virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client);
> +
> int virNetServerClientAddFilter(virNetServerClientPtr client,
> virNetServerClientFilterFunc func,
> void *opaque);
>
More information about the libvir-list
mailing list