]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Add util methods required by ch networking
authorPraveen K Paladugu <prapal@linux.microsoft.com>
Tue, 16 Jan 2024 21:25:41 +0000 (15:25 -0600)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 2 Feb 2024 09:58:29 +0000 (10:58 +0100)
virSocketSendMsgWithFDs method send fds along with payload using
SCM_RIGHTS. virSocketRecv method polls, receives and sends the response
to callers.

These methods are required to add network suppport in ch driver.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
po/POTFILES
src/libvirt_private.syms
src/util/virsocket.c
src/util/virsocket.h

index 023c041f611b422f5d43f9bc429777a4325bc3b0..b594a8dd3915422e6198c52734e5eb235cdd3547 100644 (file)
@@ -326,6 +326,7 @@ src/util/virscsi.c
 src/util/virscsihost.c
 src/util/virscsivhost.c
 src/util/virsecret.c
+src/util/virsocket.c
 src/util/virsocketaddr.c
 src/util/virstoragefile.c
 src/util/virstring.c
index 1a7d80ddf4819b8759c19e84f653932baba990ba..c39837173481522341cfd0a83dba772aeeec8216 100644 (file)
@@ -3372,6 +3372,7 @@ virSecureEraseString;
 # util/virsocket.h
 virSocketRecvFD;
 virSocketSendFD;
+virSocketSendMsgWithFDs;
 
 
 # util/virsocketaddr.h
index cd6f7ecd1b5284ae4f849f9cb270ce99260a6ce3..3b274a4eec463618eb955876a2a25b43a6e174d9 100644 (file)
 
 #include <config.h>
 
+#include "virerror.h"
 #include "virsocket.h"
 #include "virutil.h"
 #include "virfile.h"
+#include "virlog.h"
 
 #include <fcntl.h>
+#include <poll.h>
+
+#define PKT_TIMEOUT_MS 500 /* ms */
+
+#define VIR_FROM_THIS VIR_FROM_NONE
 
 #ifdef WIN32
 
@@ -482,6 +489,64 @@ virSocketRecvFD(int sock, int fdflags)
 
     return fd;
 }
+
+
+/**
+ * virSocketSendMsgWithFDs:
+ * @sock: socket to send payload and fds to
+ * @payload: payload to send
+ * @fds: array of fds to send
+ * @fds_len: len of fds array
+
+ * Send @fds along with @payload to @sock using SCM_RIGHTS.
+ * Return number of bytes sent on success.
+ * On error, set errno and return -1.
+ */
+int
+virSocketSendMsgWithFDs(int sock, const char *payload, int *fds, size_t fds_len)
+{
+    g_autofree char *control = NULL;
+    const size_t control_size = CMSG_SPACE(sizeof(int) * fds_len);
+    struct cmsghdr *cmsg;
+    struct msghdr msg = { 0 };
+    struct iovec iov[1]; /* Send a single payload, so set vector len to 1 */
+    int ret;
+
+    control = g_new0(char, control_size);
+
+    iov[0].iov_base = (void *) payload;
+    iov[0].iov_len = strlen(payload);
+
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+
+    msg.msg_control = control;
+    msg.msg_controllen = control_size;
+
+    cmsg = CMSG_FIRSTHDR(&msg);
+    /* check to eliminate "potential null pointer dereference" errors during build */
+    if (!cmsg) {
+        virReportSystemError(EFAULT, "%s", _("Couldn't fit control msg header in msg"));
+        return -1;
+    }
+
+    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds_len);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * fds_len);
+
+    do {
+        ret = sendmsg(sock, &msg, 0);
+    } while (ret < 0 && errno == EINTR);
+
+    if (ret < 0) {
+        virReportSystemError(errno, "%s", _("sendmsg failed"));
+        return -1;
+    }
+
+    return ret;
+}
+
 #else /* WIN32 */
 int
 virSocketSendFD(int sock G_GNUC_UNUSED, int fd G_GNUC_UNUSED)
@@ -496,4 +561,15 @@ virSocketRecvFD(int sock G_GNUC_UNUSED, int fdflags G_GNUC_UNUSED)
     errno = ENOSYS;
     return -1;
 }
+
+int
+virSocketSendMsgWithFDs(int sock G_GNUC_UNUSED,
+                        const char *payload G_GNUC_UNUSED,
+                        int *fds G_GNUC_UNUSED,
+                        size_t fds_len G_GNUC_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("FD passing is not supported on this platform"));
+    return -1;
+}
 #endif  /* WIN32 */
index 419da8b3ae707c2bb1fc2edba5cc0ee82be35486..31a31c2378244bf10ab1a8619ef4524e78b2cf57 100644 (file)
@@ -22,6 +22,8 @@
 
 int virSocketSendFD(int sock, int fd);
 int virSocketRecvFD(int sock, int fdflags);
+int virSocketSendMsgWithFDs(int sock, const char *payload, int *fds,
+                            size_t fd_len);
 
 #ifdef WIN32