brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · 5a4bdf7 Raw
88 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Some common code for MSG_ZEROCOPY logic3 *4 * Copyright (C) 2023 SberDevices.5 *6 * Author: Arseniy Krasnov <avkrasnov@salutedevices.com>7 */8 9#include <stdio.h>10#include <stdlib.h>11#include <sys/types.h>12#include <sys/socket.h>13#include <linux/errqueue.h>14 15#include "msg_zerocopy_common.h"16 17void enable_so_zerocopy(int fd)18{19	int val = 1;20 21	if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) {22		perror("setsockopt");23		exit(EXIT_FAILURE);24	}25}26 27void vsock_recv_completion(int fd, const bool *zerocopied)28{29	struct sock_extended_err *serr;30	struct msghdr msg = { 0 };31	char cmsg_data[128];32	struct cmsghdr *cm;33	ssize_t res;34 35	msg.msg_control = cmsg_data;36	msg.msg_controllen = sizeof(cmsg_data);37 38	res = recvmsg(fd, &msg, MSG_ERRQUEUE);39	if (res) {40		fprintf(stderr, "failed to read error queue: %zi\n", res);41		exit(EXIT_FAILURE);42	}43 44	cm = CMSG_FIRSTHDR(&msg);45	if (!cm) {46		fprintf(stderr, "cmsg: no cmsg\n");47		exit(EXIT_FAILURE);48	}49 50	if (cm->cmsg_level != SOL_VSOCK) {51		fprintf(stderr, "cmsg: unexpected 'cmsg_level'\n");52		exit(EXIT_FAILURE);53	}54 55	if (cm->cmsg_type != VSOCK_RECVERR) {56		fprintf(stderr, "cmsg: unexpected 'cmsg_type'\n");57		exit(EXIT_FAILURE);58	}59 60	serr = (void *)CMSG_DATA(cm);61	if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) {62		fprintf(stderr, "serr: wrong origin: %u\n", serr->ee_origin);63		exit(EXIT_FAILURE);64	}65 66	if (serr->ee_errno) {67		fprintf(stderr, "serr: wrong error code: %u\n", serr->ee_errno);68		exit(EXIT_FAILURE);69	}70 71	/* This flag is used for tests, to check that transmission was72	 * performed as expected: zerocopy or fallback to copy. If NULL73	 * - don't care.74	 */75	if (!zerocopied)76		return;77 78	if (*zerocopied && (serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {79		fprintf(stderr, "serr: was copy instead of zerocopy\n");80		exit(EXIT_FAILURE);81	}82 83	if (!*zerocopied && !(serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {84		fprintf(stderr, "serr: was zerocopy instead of copy\n");85		exit(EXIT_FAILURE);86	}87}88