[libvirt] [PATCH 16/23] Add JSON serialization of virNetServerPtr objects for process re-exec()

Daniel P. Berrange berrange at redhat.com
Thu Aug 9 15:20:21 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Add two new APIs virNetServerNewPostExecRestart and
virNetServerPreExecRestart which allow a virNetServerPtr
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 all registered services
and clients

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/libvirt_private.syms |   2 +
 src/rpc/virnetserver.c   | 252 +++++++++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserver.h   |  10 ++
 3 files changed, 264 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cdb9b57..879919f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1500,6 +1500,8 @@ virNetServerClose;
 virNetServerIsPrivileged;
 virNetServerKeepAliveRequired;
 virNetServerNew;
+virNetServerNewPostExecRestart;
+virNetServerPreExecRestart;
 virNetServerQuit;
 virNetServerRun;
 virNetServerSetTLSContext;
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 902c34e..92e0264 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -447,6 +447,258 @@ error:
 }
 
 
+virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
+                                               virNetServerClientPrivNew clientPrivNew,
+                                               virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart,
+                                               virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
+                                               virFreeCallback clientPrivFree,
+                                               void *clientPrivOpaque)
+{
+    virNetServerPtr srv = NULL;
+    virJSONValuePtr clients;
+    virJSONValuePtr services;
+    size_t i;
+    int n;
+    unsigned int min_workers;
+    unsigned int max_workers;
+    unsigned int priority_workers;
+    unsigned int max_clients;
+    unsigned int keepaliveInterval;
+    unsigned int keepaliveCount;
+    bool keepaliveRequired;
+    const char *mdnsGroupName = NULL;
+
+    if (virJSONValueObjectGetNumberUint(object, "min_workers", &min_workers) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing min_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetNumberUint(object, "max_workers", &max_workers) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing max_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetNumberUint(object, "priority_workers", &priority_workers) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing priority_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetNumberUint(object, "max_clients", &max_clients) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing max_clients data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing keepaliveInterval data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetNumberUint(object, "keepaliveCount", &keepaliveCount) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing keepaliveCount data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectGetBoolean(object, "keepaliveRequired", &keepaliveRequired) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing keepaliveRequired data in JSON document"));
+        goto error;
+    }
+
+    if (virJSONValueObjectHasKey(object, "mdnsGroupName") &&
+        (!(mdnsGroupName = virJSONValueObjectGetString(object, "mdnsGroupName")))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Malformed mdnsGroupName data in JSON document"));
+        goto error;
+    }
+
+    if (!(srv = virNetServerNew(min_workers, max_clients,
+                                priority_workers, max_clients,
+                                keepaliveInterval, keepaliveCount,
+                                keepaliveRequired, mdnsGroupName,
+                                clientPrivNew, clientPrivPreExecRestart,
+                                clientPrivFree, clientPrivOpaque)))
+        goto error;
+
+    if (!(services = virJSONValueObjectGet(object, "services"))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing services data in JSON document"));
+        goto error;
+    }
+
+    n =  virJSONValueArraySize(services);
+    if (n < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Malformed services data in JSON document"));
+        goto error;
+    }
+
+    for (i = 0 ; i < n ; i++) {
+        virNetServerServicePtr service;
+        virJSONValuePtr child = virJSONValueArrayGet(services, i);
+        if (!child) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Missing service data in JSON document"));
+            goto error;
+        }
+
+        if (!(service = virNetServerServiceNewPostExecRestart(child)))
+            goto error;
+
+        /* XXX mdns entry names ? */
+        if (virNetServerAddService(srv, service, NULL) < 0) {
+            virObjectUnref(service);
+            goto error;
+        }
+    }
+
+
+    if (!(clients = virJSONValueObjectGet(object, "clients"))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Missing clients data in JSON document"));
+        goto error;
+    }
+
+    n =  virJSONValueArraySize(clients);
+    if (n < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Malformed clients data in JSON document"));
+        goto error;
+    }
+
+    for (i = 0 ; i < n ; i++) {
+        virNetServerClientPtr client;
+        virJSONValuePtr child = virJSONValueArrayGet(clients, i);
+        if (!child) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Missing client data in JSON document"));
+            goto error;
+        }
+
+        if (!(client = virNetServerClientNewPostExecRestart(child,
+                                                            clientPrivNewPostExecRestart,
+                                                            clientPrivPreExecRestart,
+                                                            clientPrivFree,
+                                                            clientPrivOpaque)))
+            goto error;
+
+        if (virNetServerAddClient(srv, client) < 0) {
+            virObjectUnref(client);
+            goto error;
+        }
+        virObjectUnref(client);
+    }
+
+    return srv;
+
+error:
+    virObjectUnref(srv);
+    return NULL;
+}
+
+
+virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv)
+{
+    virJSONValuePtr object;
+    virJSONValuePtr clients;
+    virJSONValuePtr services;
+    size_t i;
+
+    virMutexLock(&srv->lock);
+
+    if (!(object = virJSONValueNewObject()))
+        goto error;
+
+    if (virJSONValueObjectAppendNumberUint(object, "min_workers",
+                                           virThreadPoolGetMinWorkers(srv->workers)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set min_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendNumberUint(object, "max_workers",
+                                           virThreadPoolGetMaxWorkers(srv->workers)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set max_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendNumberUint(object, "priority_workers",
+                                           virThreadPoolGetPriorityWorkers(srv->workers)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set priority_workers data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendNumberUint(object, "max_clients", srv->nclients_max) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set max_clients data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendNumberUint(object, "keepaliveInterval", srv->keepaliveInterval) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set keepaliveInterval data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendNumberUint(object, "keepaliveCount", srv->keepaliveCount) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set keepaliveCount data in JSON document"));
+        goto error;
+    }
+    if (virJSONValueObjectAppendBoolean(object, "keepaliveRequired", srv->keepaliveRequired) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set keepaliveRequired data in JSON document"));
+        goto error;
+    }
+
+    if (srv->mdnsGroupName &&
+        virJSONValueObjectAppendString(object, "mdnsGroupName", srv->mdnsGroupName) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot set mdnsGroupName data in JSON document"));
+        goto error;
+    }
+
+    services = virJSONValueNewArray();
+    if (virJSONValueObjectAppend(object, "services", services) < 0) {
+        virJSONValueFree(services);
+        goto error;
+    }
+
+    for (i = 0 ; i < srv->nservices ; i++) {
+        virJSONValuePtr child;
+        if (!(child = virNetServerServicePreExecRestart(srv->services[i])))
+            goto error;
+
+        if (virJSONValueArrayAppend(services, child) < 0) {
+            virJSONValueFree(child);
+            goto error;
+        }
+    }
+
+    clients = virJSONValueNewArray();
+    if (virJSONValueObjectAppend(object, "clients", clients) < 0) {
+        virJSONValueFree(clients);
+        goto error;
+    }
+
+    for (i = 0 ; i < srv->nclients ; i++) {
+        virJSONValuePtr child;
+        if (!(child = virNetServerClientPreExecRestart(srv->clients[i])))
+            goto error;
+
+        if (virJSONValueArrayAppend(clients, child) < 0) {
+            virJSONValueFree(child);
+            goto error;
+        }
+    }
+
+    virMutexUnlock(&srv->lock);
+
+    return object;
+
+error:
+    virJSONValueFree(object);
+    virMutexUnlock(&srv->lock);
+    return NULL;
+}
+
+
 bool virNetServerIsPrivileged(virNetServerPtr srv)
 {
     bool priv;
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 778b069..a5cbcd3 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -31,6 +31,7 @@
 # include "virnetserverclient.h"
 # include "virnetserverservice.h"
 # include "virobject.h"
+# include "json.h"
 
 virNetServerPtr virNetServerNew(size_t min_workers,
                                 size_t max_workers,
@@ -45,6 +46,15 @@ virNetServerPtr virNetServerNew(size_t min_workers,
                                 virFreeCallback clientPrivFree,
                                 void *clientPrivOpaque);
 
+virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
+                                               virNetServerClientPrivNew clientPrivNew,
+                                               virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart,
+                                               virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
+                                               virFreeCallback clientPrivFree,
+                                               void *clientPrivOpaque);
+
+virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv);
+
 typedef int (*virNetServerAutoShutdownFunc)(virNetServerPtr srv, void *opaque);
 
 bool virNetServerIsPrivileged(virNetServerPtr srv);
-- 
1.7.11.2




More information about the libvir-list mailing list