]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add JSON serialization of virNetServerClientPtr objects for process re-exec()
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 9 Aug 2012 11:54:54 +0000 (12:54 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 16 Oct 2012 14:45:55 +0000 (15:45 +0100)
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@redhat.com>
daemon/libvirtd.c
src/libvirt_private.syms
src/lxc/lxc_controller.c
src/rpc/virnetserver.c
src/rpc/virnetserver.h
src/rpc/virnetserverclient.c
src/rpc/virnetserverclient.h

index b49acc5bde315173da2ab12bca617a90614dae0d..d2e0a046be4951e9fb3d10afcee1d534e4a980a9 100644 (file)
@@ -1216,6 +1216,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;
index 3f9d96cff91222ee8339468740036d5cf4c7748b..8b18813016f009ffa08974156d9af4b25f300660 100644 (file)
@@ -1594,6 +1594,8 @@ virNetServerClientIsSecure;
 virNetServerClientLocalAddrString;
 virNetServerClientNeedAuth;
 virNetServerClientNew;
+virNetServerClientNewPostExecRestart;
+virNetServerClientPreExecRestart;
 virNetServerClientRemoteAddrString;
 virNetServerClientRemoveFilter;
 virNetServerClientSendMessage;
index 68f857a13807ef9edb669b39295a8dddd2080bb9..a41c9037c65591e9278c3167587d1f655ebc85d1 100644 (file)
@@ -609,6 +609,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
                                          -1, 0, false,
                                          NULL,
                                          virLXCControllerClientPrivateNew,
+                                         NULL,
                                          virLXCControllerClientPrivateFree,
                                          ctrl)))
         goto error;
index ae4ed46fb0666aa3b686e07bb7bffdc63862fd0e..13a7758646670df011fa75b1a92a80a311126ddb 100644 (file)
@@ -105,6 +105,7 @@ struct _virNetServer {
     void *autoShutdownOpaque;
 
     virNetServerClientPrivNew clientPrivNew;
+    virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
     virFreeCallback clientPrivFree;
     void *clientPrivOpaque;
 };
@@ -309,6 +310,7 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc,
                                          virNetServerServiceGetMaxRequests(svc),
                                          virNetServerServiceGetTLSContext(svc),
                                          srv->clientPrivNew,
+                                         srv->clientPrivPreExecRestart,
                                          srv->clientPrivFree,
                                          srv->clientPrivOpaque)))
         return -1;
@@ -360,6 +362,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
                                 bool keepaliveRequired,
                                 const char *mdnsGroupName,
                                 virNetServerClientPrivNew clientPrivNew,
+                                virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
                                 virFreeCallback clientPrivFree,
                                 void *clientPrivOpaque)
 {
@@ -385,6 +388,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;
index 3fe9e8ccea447f2ce8b940c225cd4a30d73c60c9..81819e794f0b3f9868e375a877a220020225054f 100644 (file)
@@ -41,6 +41,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
                                 bool keepaliveRequired,
                                 const char *mdnsGroupName,
                                 virNetServerClientPrivNew clientPrivNew,
+                                virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
                                 virFreeCallback clientPrivFree,
                                 void *clientPrivOpaque);
 
index 59cba9adbbfd507ee19c64f155156c8c08dc91da..2777e6690a4d36fa279b0b5da3a15eaff3ed0966 100644 (file)
@@ -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;
index 3ce1889367eee44df07fc52aaca408e23dd25b0c..041ffde5152868f4d0e0e3fe82446049ee2d389b 100644 (file)
@@ -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);