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

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


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(+)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 183ab42..c8dbe4b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -97,6 +97,7 @@ src/rpc/virnetserver.c
 src/rpc/virnetserverclient.c
 src/rpc/virnetservermdns.c
 src/rpc/virnetserverprogram.c
+src/rpc/virnetserverservice.c
 src/rpc/virnettlscontext.c
 src/secret/secret_driver.c
 src/security/security_apparmor.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 836a926..7ea4b95 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1571,8 +1571,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;
+        }
+
+        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)
+        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);
-- 
1.7.11.2




More information about the libvir-list mailing list