From: "Daniel P. Berrange" <berrange(a)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(a)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