]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add APIs for virNetSocket for sending/receiving file descriptors
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 21 Oct 2011 10:13:21 +0000 (11:13 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 28 Oct 2011 09:23:53 +0000 (10:23 +0100)
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
src/libvirt_private.syms
src/probes.d
src/rpc/virnetsocket.c
src/rpc/virnetsocket.h

index f24657177186b2c885786aaf08a10f46e66ed5fb..69d7593a3ca41e4d1345b32c4b4ab0262b30e500 100755 (executable)
@@ -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));
+}
index ad1ef1699b7c6d025d8be6c12c86d01ea548e53c..3b4b429cc930afe18d360db433837b138995c3ae 100644 (file)
@@ -1253,9 +1253,13 @@ virNetServerProgramSendStreamError;
 virNetSocketDupFD;
 virNetSocketFree;
 virNetSocketGetFD;
+virNetSocketHasPassFD;
+virNetSocketIsLocal;
 virNetSocketListen;
 virNetSocketNewConnectTCP;
 virNetSocketNewListenUNIX;
+virNetSocketRecvFD;
+virNetSocketSendFD;
 
 
 # virnettlscontext.h
index 7f66ac0594f9eb220f71ab04fc16943c77388f24..d0e0b86f4a2a6c09e2e752fec1a99c5ff3ccddd0 100644 (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);
 
index e4eff49013cc3d989cc54c85b31d16165597ef95..ab88e19fd94a02e71665ff732be0325ea33d6422 100644 (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);
index 9c4f11251bc7a69c9e10af7591553254e772fff4..13cbb14ddf90c6af368c9af965d06457087ab1c2 100644 (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