Path: blob/master/tools/testing/vsock/msg_zerocopy_common.c
26282 views
// SPDX-License-Identifier: GPL-2.0-only1/* Some common code for MSG_ZEROCOPY logic2*3* Copyright (C) 2023 SberDevices.4*5* Author: Arseniy Krasnov <[email protected]>6*/78#include <stdio.h>9#include <stdlib.h>10#include <sys/types.h>11#include <sys/socket.h>12#include <linux/errqueue.h>1314#include "msg_zerocopy_common.h"1516void vsock_recv_completion(int fd, const bool *zerocopied)17{18struct sock_extended_err *serr;19struct msghdr msg = { 0 };20char cmsg_data[128];21struct cmsghdr *cm;22ssize_t res;2324msg.msg_control = cmsg_data;25msg.msg_controllen = sizeof(cmsg_data);2627res = recvmsg(fd, &msg, MSG_ERRQUEUE);28if (res) {29fprintf(stderr, "failed to read error queue: %zi\n", res);30exit(EXIT_FAILURE);31}3233cm = CMSG_FIRSTHDR(&msg);34if (!cm) {35fprintf(stderr, "cmsg: no cmsg\n");36exit(EXIT_FAILURE);37}3839if (cm->cmsg_level != SOL_VSOCK) {40fprintf(stderr, "cmsg: unexpected 'cmsg_level'\n");41exit(EXIT_FAILURE);42}4344if (cm->cmsg_type != VSOCK_RECVERR) {45fprintf(stderr, "cmsg: unexpected 'cmsg_type'\n");46exit(EXIT_FAILURE);47}4849serr = (void *)CMSG_DATA(cm);50if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) {51fprintf(stderr, "serr: wrong origin: %u\n", serr->ee_origin);52exit(EXIT_FAILURE);53}5455if (serr->ee_errno) {56fprintf(stderr, "serr: wrong error code: %u\n", serr->ee_errno);57exit(EXIT_FAILURE);58}5960/* This flag is used for tests, to check that transmission was61* performed as expected: zerocopy or fallback to copy. If NULL62* - don't care.63*/64if (!zerocopied)65return;6667if (*zerocopied && (serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {68fprintf(stderr, "serr: was copy instead of zerocopy\n");69exit(EXIT_FAILURE);70}7172if (!*zerocopied && !(serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {73fprintf(stderr, "serr: was zerocopy instead of copy\n");74exit(EXIT_FAILURE);75}76}777879