mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-08-18 17:17:55 +00:00

Replace setsockopt() calls with calls to functions that follow setsockopt() with getsockopt() and check that the returned value and its size are the same as have been set. (Except in vsock_perf.) Signed-off-by: Konstantin Shkolnyy <kshk@linux.ibm.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
78 lines
1.8 KiB
C
78 lines
1.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Some common code for MSG_ZEROCOPY logic
|
|
*
|
|
* Copyright (C) 2023 SberDevices.
|
|
*
|
|
* Author: Arseniy Krasnov <avkrasnov@salutedevices.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <linux/errqueue.h>
|
|
|
|
#include "msg_zerocopy_common.h"
|
|
|
|
void vsock_recv_completion(int fd, const bool *zerocopied)
|
|
{
|
|
struct sock_extended_err *serr;
|
|
struct msghdr msg = { 0 };
|
|
char cmsg_data[128];
|
|
struct cmsghdr *cm;
|
|
ssize_t res;
|
|
|
|
msg.msg_control = cmsg_data;
|
|
msg.msg_controllen = sizeof(cmsg_data);
|
|
|
|
res = recvmsg(fd, &msg, MSG_ERRQUEUE);
|
|
if (res) {
|
|
fprintf(stderr, "failed to read error queue: %zi\n", res);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
cm = CMSG_FIRSTHDR(&msg);
|
|
if (!cm) {
|
|
fprintf(stderr, "cmsg: no cmsg\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (cm->cmsg_level != SOL_VSOCK) {
|
|
fprintf(stderr, "cmsg: unexpected 'cmsg_level'\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (cm->cmsg_type != VSOCK_RECVERR) {
|
|
fprintf(stderr, "cmsg: unexpected 'cmsg_type'\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
serr = (void *)CMSG_DATA(cm);
|
|
if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) {
|
|
fprintf(stderr, "serr: wrong origin: %u\n", serr->ee_origin);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (serr->ee_errno) {
|
|
fprintf(stderr, "serr: wrong error code: %u\n", serr->ee_errno);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* This flag is used for tests, to check that transmission was
|
|
* performed as expected: zerocopy or fallback to copy. If NULL
|
|
* - don't care.
|
|
*/
|
|
if (!zerocopied)
|
|
return;
|
|
|
|
if (*zerocopied && (serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {
|
|
fprintf(stderr, "serr: was copy instead of zerocopy\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (!*zerocopied && !(serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {
|
|
fprintf(stderr, "serr: was zerocopy instead of copy\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|