[libvirt] [PATCH 4/8] Add APIs for virNetSocket for sending/receiving file descriptors

Daniel P. Berrange berrange at redhat.com
Tue Oct 25 16:03:44 UTC 2011


From: "Daniel P. Berrange" <berrange at redhat.com>

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
---
 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..69d7593 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));
+}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a81966d..6a42d1b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1252,9 +1252,13 @@ virNetServerProgramSendStreamError;
 virNetSocketDupFD;
 virNetSocketFree;
 virNetSocketGetFD;
+virNetSocketHasPassFD;
+virNetSocketIsLocal;
 virNetSocketListen;
 virNetSocketNewConnectTCP;
 virNetSocketNewListenUNIX;
+virNetSocketRecvFD;
+virNetSocketSendFD;
 
 
 # virnettlscontext.h
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..ab88e19 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,
+                    _("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);
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




More information about the libvir-list mailing list