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