mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-23 02:04:16 +03:00
util: Add util methods required by ch networking
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>
This commit is contained in:
parent
4bfd513d92
commit
e7daa49a15
@ -326,6 +326,7 @@ src/util/virscsi.c
|
|||||||
src/util/virscsihost.c
|
src/util/virscsihost.c
|
||||||
src/util/virscsivhost.c
|
src/util/virscsivhost.c
|
||||||
src/util/virsecret.c
|
src/util/virsecret.c
|
||||||
|
src/util/virsocket.c
|
||||||
src/util/virsocketaddr.c
|
src/util/virsocketaddr.c
|
||||||
src/util/virstoragefile.c
|
src/util/virstoragefile.c
|
||||||
src/util/virstring.c
|
src/util/virstring.c
|
||||||
|
@ -3372,6 +3372,7 @@ virSecureEraseString;
|
|||||||
# util/virsocket.h
|
# util/virsocket.h
|
||||||
virSocketRecvFD;
|
virSocketRecvFD;
|
||||||
virSocketSendFD;
|
virSocketSendFD;
|
||||||
|
virSocketSendMsgWithFDs;
|
||||||
|
|
||||||
|
|
||||||
# util/virsocketaddr.h
|
# util/virsocketaddr.h
|
||||||
|
@ -19,11 +19,18 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "virerror.h"
|
||||||
#include "virsocket.h"
|
#include "virsocket.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
#define PKT_TIMEOUT_MS 500 /* ms */
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
@ -482,6 +489,64 @@ virSocketRecvFD(int sock, int fdflags)
|
|||||||
|
|
||||||
return fd;
|
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 */
|
#else /* WIN32 */
|
||||||
int
|
int
|
||||||
virSocketSendFD(int sock G_GNUC_UNUSED, int fd G_GNUC_UNUSED)
|
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;
|
errno = ENOSYS;
|
||||||
return -1;
|
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 */
|
#endif /* WIN32 */
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
int virSocketSendFD(int sock, int fd);
|
int virSocketSendFD(int sock, int fd);
|
||||||
int virSocketRecvFD(int sock, int fdflags);
|
int virSocketRecvFD(int sock, int fdflags);
|
||||||
|
int virSocketSendMsgWithFDs(int sock, const char *payload, int *fds,
|
||||||
|
size_t fd_len);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user