mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-02 20:58:33 +03:00
Add JSON serialization of virNetServerClientPtr objects for process re-exec()
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>
This commit is contained in:
parent
0cc7925520
commit
3cfc3d7d2c
@ -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;
|
||||
|
@ -1594,6 +1594,8 @@ virNetServerClientIsSecure;
|
||||
virNetServerClientLocalAddrString;
|
||||
virNetServerClientNeedAuth;
|
||||
virNetServerClientNew;
|
||||
virNetServerClientNewPostExecRestart;
|
||||
virNetServerClientPreExecRestart;
|
||||
virNetServerClientRemoteAddrString;
|
||||
virNetServerClientRemoveFilter;
|
||||
virNetServerClientSendMessage;
|
||||
|
@ -609,6 +609,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
||||
-1, 0, false,
|
||||
NULL,
|
||||
virLXCControllerClientPrivateNew,
|
||||
NULL,
|
||||
virLXCControllerClientPrivateFree,
|
||||
ctrl)))
|
||||
goto error;
|
||||
|
@ -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;
|
||||
|
@ -41,6 +41,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
||||
bool keepaliveRequired,
|
||||
const char *mdnsGroupName,
|
||||
virNetServerClientPrivNew clientPrivNew,
|
||||
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
|
||||
virFreeCallback clientPrivFree,
|
||||
void *clientPrivOpaque);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user