Add APIs for virNetSocket for sending/receiving file descriptors

Add APIs to the virNetSocket object, to allow file descriptors
to be sent/received over UNIX domain socket connections

* src/rpc/virnetsocket.c, src/rpc/virnetsocket.h,
  src/libvirt_private.syms: Add APIs for FD send/recv
This commit is contained in:
Daniel P. Berrange 2011-10-21 11:13:21 +01:00
parent f877fed36f
commit 018044c89f
5 changed files with 83 additions and 0 deletions

View File

@ -155,3 +155,13 @@ probe libvirt.rpc.server_client_free {
delete serverSocks[pid(), client];
}
}
probe libvirt.rpc.socket_send_fd {
print_ts(sprintf("= %-16p send fd=%d", sock, fd));
}
probe libvirt.rpc.socket_recv_fd {
print_ts(sprintf("= %-16p recv fd=%d", sock, fd));
}

View File

@ -1253,9 +1253,13 @@ virNetServerProgramSendStreamError;
virNetSocketDupFD;
virNetSocketFree;
virNetSocketGetFD;
virNetSocketHasPassFD;
virNetSocketIsLocal;
virNetSocketListen;
virNetSocketNewConnectTCP;
virNetSocketNewListenUNIX;
virNetSocketRecvFD;
virNetSocketSendFD;
# virnettlscontext.h

View File

@ -19,6 +19,8 @@ provider libvirt {
# file: src/rpc/virnetsocket.c
# prefix: rpc
probe rpc_socket_new(void *sock, int refs, int fd, int errfd, int pid, const char *localAddr, const char *remoteAddr);
probe rpc_socket_send_fd(void *sock, int fd);
probe rpc_socket_recv_fd(void *sock, int fd);
probe rpc_socket_ref(void *sock, int refs);
probe rpc_socket_free(void *sock, int refs);

View File

@ -43,6 +43,8 @@
#include "event.h"
#include "threads.h"
#include "passfd.h"
#define VIR_FROM_THIS VIR_FROM_RPC
#define virNetError(code, ...) \
@ -791,6 +793,17 @@ bool virNetSocketIsLocal(virNetSocketPtr sock)
}
bool virNetSocketHasPassFD(virNetSocketPtr sock)
{
bool hasPassFD = false;
virMutexLock(&sock->lock);
if (sock->localAddr.data.sa.sa_family == AF_UNIX)
hasPassFD = true;
virMutexUnlock(&sock->lock);
return hasPassFD;
}
int virNetSocketGetPort(virNetSocketPtr sock)
{
int port;
@ -1128,6 +1141,55 @@ ssize_t virNetSocketWrite(virNetSocketPtr sock, const char *buf, size_t len)
}
int virNetSocketSendFD(virNetSocketPtr sock, int fd)
{
int ret = -1;
if (!virNetSocketHasPassFD(sock)) {
virNetError(VIR_ERR_INTERNAL_ERROR,
_("Sending file descriptors is not supported on this socket"));
return -1;
}
virMutexLock(&sock->lock);
PROBE(RPC_SOCKET_SEND_FD,
"sock=%p fd=%d", sock, fd);
if (sendfd(sock->fd, fd) < 0) {
virReportSystemError(errno,
_("Failed to send file descriptor %d"),
fd);
goto cleanup;
}
ret = 0;
cleanup:
virMutexUnlock(&sock->lock);
return ret;
}
int virNetSocketRecvFD(virNetSocketPtr sock)
{
int ret = -1;
if (!virNetSocketHasPassFD(sock)) {
virNetError(VIR_ERR_INTERNAL_ERROR,
_("Receiving file descriptors is not supported on this socket"));
return -1;
}
virMutexLock(&sock->lock);
if ((ret = recvfd(sock->fd, O_CLOEXEC)) < 0) {
virReportSystemError(errno, "%s",
_("Failed to recv file descriptor"));
goto cleanup;
}
PROBE(RPC_SOCKET_RECV_FD,
"sock=%p fd=%d", sock, ret);
cleanup:
virMutexUnlock(&sock->lock);
return ret;
}
int virNetSocketListen(virNetSocketPtr sock, int backlog)
{
virMutexLock(&sock->lock);

View File

@ -82,6 +82,8 @@ int virNetSocketDupFD(virNetSocketPtr sock, bool cloexec);
bool virNetSocketIsLocal(virNetSocketPtr sock);
bool virNetSocketHasPassFD(virNetSocketPtr sock);
int virNetSocketGetPort(virNetSocketPtr sock);
int virNetSocketGetLocalIdentity(virNetSocketPtr sock,
@ -94,6 +96,9 @@ int virNetSocketSetBlocking(virNetSocketPtr sock,
ssize_t virNetSocketRead(virNetSocketPtr sock, char *buf, size_t len);
ssize_t virNetSocketWrite(virNetSocketPtr sock, const char *buf, size_t len);
int virNetSocketSendFD(virNetSocketPtr sock, int fd);
int virNetSocketRecvFD(virNetSocketPtr sock);
void virNetSocketSetTLSSession(virNetSocketPtr sock,
virNetTLSSessionPtr sess);
# ifdef HAVE_SASL