From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add APIs to the virNetSocket object, to allow file descriptors to be send/received over UNIX domain socket connections * src/rpc/virnetsocket.c, src/rpc/virnetsocket.h, src/libvirt_private.syms: Add APIs for FD send/recv --- examples/systemtap/rpc-monitor.stp | 10 ++++++ src/libvirt_private.syms | 4 ++ src/probes.d | 2 + src/rpc/virnetsocket.c | 62 ++++++++++++++++++++++++++++++++++++ src/rpc/virnetsocket.h | 5 +++ 5 files changed, 83 insertions(+), 0 deletions(-) diff --git a/examples/systemtap/rpc-monitor.stp b/examples/systemtap/rpc-monitor.stp index f246571..b76564f 100755 --- a/examples/systemtap/rpc-monitor.stp +++ b/examples/systemtap/rpc-monitor.stp @@ -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)); +} \ No newline at end of file diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index dedbd16..0648e49 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1244,6 +1244,10 @@ virNetSocketDupFD; virNetSocketFree; virNetSocketGetFD; virNetSocketListen; +virNetSocketIsLocal; +virNetSocketHasPassFD; +virNetSocketSendFD; +virNetSocketRecvFD; virNetSocketNewConnectTCP; virNetSocketNewListenUNIX; diff --git a/src/probes.d b/src/probes.d index 6d95c84..2f5d059 100644 --- a/src/probes.d +++ b/src/probes.d @@ -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); diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index e4eff49..e88d84e 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -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, + _("Sending file descriptors is not supported on this socket")); + return -1; + } + virMutexLock(&sock->lock); + + if ((ret = recvfd(sock->fd, 0)) < 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); diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 9c4f112..13cbb14 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -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 -- 1.7.6.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list