af_unix: Add test for SCM_INQ on partial read

Add test to verify that when a skb is partially consumed,
unix_inq_len() return correct remaining byte count.

Before:

  #  RUN           scm_inq.stream.partial_read ...
  # scm_inq.c:165:partial_read:Expected remain (512) == *(int *)CMSG_DATA(cmsg) (768)
  # partial_read: Test terminated by assertion
  #          FAIL  scm_inq.stream.partial_read
  not ok 2 scm_inq.stream.partial_read

After:

  #  RUN           scm_inq.stream.partial_read ...
  #            OK  scm_inq.stream.partial_read
  ok 2 scm_inq.stream.partial_read

Signed-off-by: Jianyu Li <jianyu.li@mediatek.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260601113640.231897-3-jianyu.li@mediatek.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jianyu Li 2026-06-01 19:36:40 +08:00 committed by Jakub Kicinski
parent c1f07a7f2d
commit dd8975ad71

View File

@ -8,8 +8,9 @@
#include "kselftest_harness.h"
#define NR_CHUNKS 100
#define MSG_LEN 256
#define NR_CHUNKS 100
#define MSG_LEN 256
#define NR_PARTIAL_READS 3
FIXTURE(scm_inq)
{
@ -120,4 +121,53 @@ TEST_F(scm_inq, basic)
recv_chunks(_metadata, self);
}
TEST_F(scm_inq, partial_read)
{
char buf[MSG_LEN * NR_PARTIAL_READS] = {};
char cmsg_buf[CMSG_SPACE(sizeof(int))];
struct msghdr msg = {};
struct iovec iov = {};
struct cmsghdr *cmsg;
int err, inq, ret, i;
int remain;
err = setsockopt(self->fd[1], SOL_SOCKET, SO_INQ, &(int){1}, sizeof(int));
if (variant->type != SOCK_STREAM) {
ASSERT_EQ(-ENOPROTOOPT, -errno);
return;
}
ASSERT_EQ(0, err);
ret = send(self->fd[0], buf, sizeof(buf), 0);
ASSERT_EQ(sizeof(buf), ret);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
iov.iov_base = buf;
iov.iov_len = MSG_LEN;
for (i = 0; i < NR_PARTIAL_READS; i++) {
remain = MSG_LEN * (NR_PARTIAL_READS - 1 - i);
memset(buf, 0, MSG_LEN);
memset(cmsg_buf, 0, sizeof(cmsg_buf));
ret = recvmsg(self->fd[1], &msg, 0);
ASSERT_EQ(MSG_LEN, ret);
cmsg = CMSG_FIRSTHDR(&msg);
ASSERT_NE(NULL, cmsg);
ASSERT_EQ(CMSG_LEN(sizeof(int)), cmsg->cmsg_len);
ASSERT_EQ(SOL_SOCKET, cmsg->cmsg_level);
ASSERT_EQ(SCM_INQ, cmsg->cmsg_type);
ASSERT_EQ(remain, *(int *)CMSG_DATA(cmsg));
ret = ioctl(self->fd[1], SIOCINQ, &inq);
ASSERT_EQ(0, ret);
ASSERT_EQ(remain, inq);
}
}
TEST_HARNESS_MAIN