mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
Add JSON serialization of virNetSocketPtr objects for process re-exec()
Add two new APIs virNetSocketNewPostExecRestart and virNetSocketPreExecRestart which allow a virNetSocketPtr object to be created from a JSON object and saved to a JSON object, for the purpose of re-exec'ing a process. As well as saving the state in JSON format, the second method will disable the O_CLOEXEC flag so that the open file descriptors are preserved across the process re-exec() Since it is not possible to serialize SASL or TLS encryption state, an error will be raised if attempting to perform serialization on non-raw sockets Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
8057c04e8d
commit
c298145344
@ -1667,6 +1667,8 @@ virNetSocketNewConnectUNIX;
|
|||||||
virNetSocketNewListenFD;
|
virNetSocketNewListenFD;
|
||||||
virNetSocketNewListenTCP;
|
virNetSocketNewListenTCP;
|
||||||
virNetSocketNewListenUNIX;
|
virNetSocketNewListenUNIX;
|
||||||
|
virNetSocketNewPostExecRestart;
|
||||||
|
virNetSocketPreExecRestart;
|
||||||
virNetSocketRead;
|
virNetSocketRead;
|
||||||
virNetSocketRecvFD;
|
virNetSocketRecvFD;
|
||||||
virNetSocketRemoteAddrString;
|
virNetSocketRemoteAddrString;
|
||||||
|
@ -882,6 +882,114 @@ int virNetSocketNewConnectExternal(const char **cmdargv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virNetSocketPtr virNetSocketNewPostExecRestart(virJSONValuePtr object)
|
||||||
|
{
|
||||||
|
virSocketAddr localAddr;
|
||||||
|
virSocketAddr remoteAddr;
|
||||||
|
int fd, thepid, errfd;
|
||||||
|
bool isClient;
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberInt(object, "fd", &fd) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing fd data in JSON document"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberInt(object, "pid", &thepid) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing pid data in JSON document"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberInt(object, "errfd", &errfd) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing errfd data in JSON document"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (virJSONValueObjectGetBoolean(object, "isClient", &isClient) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Missing isClient data in JSON document"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&localAddr, 0, sizeof(localAddr));
|
||||||
|
memset(&remoteAddr, 0, sizeof(remoteAddr));
|
||||||
|
|
||||||
|
remoteAddr.len = sizeof(remoteAddr.data.stor);
|
||||||
|
if (getsockname(fd, &remoteAddr.data.sa, &remoteAddr.len) < 0) {
|
||||||
|
virReportSystemError(errno, "%s", _("Unable to get peer socket name"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
localAddr.len = sizeof(localAddr.data.stor);
|
||||||
|
if (getsockname(fd, &localAddr.data.sa, &localAddr.len) < 0) {
|
||||||
|
virReportSystemError(errno, "%s", _("Unable to get local socket name"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virNetSocketNew(&localAddr, &remoteAddr,
|
||||||
|
isClient, fd, errfd, thepid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virJSONValuePtr virNetSocketPreExecRestart(virNetSocketPtr sock)
|
||||||
|
{
|
||||||
|
virJSONValuePtr object = NULL;
|
||||||
|
|
||||||
|
virMutexLock(&sock->lock);
|
||||||
|
|
||||||
|
#if HAVE_SASL
|
||||||
|
if (sock->saslSession) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
|
_("Unable to save socket state when SASL session is active"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (sock->tlsSession) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
|
_("Unable to save socket state when TLS session is active"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(object = virJSONValueNewObject()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendNumberInt(object, "fd", sock->fd) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendNumberInt(object, "errfd", sock->errfd) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendNumberInt(object, "pid", sock->pid) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendBoolean(object, "isClient", sock->client) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virSetInherit(sock->fd, true) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Cannot disable close-on-exec flag on socket %d"),
|
||||||
|
sock->fd);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (sock->errfd != -1 &&
|
||||||
|
virSetInherit(sock->errfd, true) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Cannot disable close-on-exec flag on pipe %d"),
|
||||||
|
sock->errfd);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
virMutexUnlock(&sock->lock);
|
||||||
|
return object;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virMutexUnlock(&sock->lock);
|
||||||
|
virJSONValueFree(object);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void virNetSocketDispose(void *obj)
|
void virNetSocketDispose(void *obj)
|
||||||
{
|
{
|
||||||
virNetSocketPtr sock = obj;
|
virNetSocketPtr sock = obj;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
# ifdef HAVE_SASL
|
# ifdef HAVE_SASL
|
||||||
# include "virnetsaslcontext.h"
|
# include "virnetsaslcontext.h"
|
||||||
# endif
|
# endif
|
||||||
|
# include "json.h"
|
||||||
|
|
||||||
typedef struct _virNetSocket virNetSocket;
|
typedef struct _virNetSocket virNetSocket;
|
||||||
typedef virNetSocket *virNetSocketPtr;
|
typedef virNetSocket *virNetSocketPtr;
|
||||||
@ -93,6 +94,11 @@ int virNetSocketNewConnectLibSSH2(const char *host,
|
|||||||
int virNetSocketNewConnectExternal(const char **cmdargv,
|
int virNetSocketNewConnectExternal(const char **cmdargv,
|
||||||
virNetSocketPtr *addr);
|
virNetSocketPtr *addr);
|
||||||
|
|
||||||
|
|
||||||
|
virNetSocketPtr virNetSocketNewPostExecRestart(virJSONValuePtr object);
|
||||||
|
|
||||||
|
virJSONValuePtr virNetSocketPreExecRestart(virNetSocketPtr sock);
|
||||||
|
|
||||||
int virNetSocketGetFD(virNetSocketPtr sock);
|
int virNetSocketGetFD(virNetSocketPtr sock);
|
||||||
int virNetSocketDupFD(virNetSocketPtr sock, bool cloexec);
|
int virNetSocketDupFD(virNetSocketPtr sock, bool cloexec);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user