gpt4 book ai didi

linux - netlink 分散发送导致内核错误响应 (NLMSG_ERROR)

转载 作者:太空宇宙 更新时间:2023-11-04 03:59:43 25 4
gpt4 key购买 nike

我正在编写一个使用 Netlink 协议(protocol)来收集任务统计信息的程序。我没有走得太远,因为内核对我认为有效的数据包做出了错误响应。我使用 strace 将我的程序的行为与正常工作的 iotop 的行为进行了比较。

来自 iotop 的 strace 的相关位:

socket(PF_NETLINK, SOCK_RAW, 16)        = 3setsockopt(3, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0setsockopt(3, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0getsockname(3, {sa_family=AF_NETLINK, pid=-4286, groups=00000000}, [12]) = 0sendto(3, "\x24\x00\x00\x00\x10\x00\x01\x00\x01\x00\x00\x00\x42\xef\xff\xff\x03\x00\x00\x00\x0e\x00\x02\x00\x54\x41\x53\x4b\x53\x54\x41\x54\x53\x00\x00\x00", 36, 0, NULL, 0) = 36recvfrom(3, "\x70\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x42\xef\xff\xff\x01\x02\x00\x00\x0e\x00\x02\x00\x54\x41\x53\x4b\x53\x54\x41\x54\x53\x00\x00\x00\x06\x00\x01\x00\x17\x00\x00\x00\x08\x00\x03\x00\x01\x00\x00\x00\x08\x00\x04\x00\x00\x00\x00\x00\x08\x00\x05\x00\x04\x00\x00\x00\x2c\x00\x06\x00\x14\x00\x01\x00\x08\x00\x01\x00\x01\x00\x00\x00\x08\x00\x02\x00\x0b\x00\x00\x00\x14\x00\x02\x00\x08\x00\x01\x00\x04\x00\x00\x00\x08\x00\x02\x00\x0a\x00\x00\x00", 16384, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 112

我的程序中 strace 输出的相应部分:

bind(8, {sa_family=AF_NETLINK, pid=19156, groups=00000000}, 12) = 0setsockopt(8, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0setsockopt(8, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0sendmsg(8, {msg_name(0)=NULL, msg_iov(5)=[{"\x24\x00\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00\xd4\x4a\x00\x00", 16}, {"\x03\x00\x00\x00", 4}, {"\x0e\x00\x02\x00", 4}, {"\x54\x41\x53\x4b\x53\x54\x41\x54\x53\x00", 10}, {"\x00\x00", 2}], msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL) = 36recvmsg(8, {msg_name(0)=NULL, msg_iov(1)=[{"\x38\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xd4\x4a\x00\x00", 16}], msg_controllen=0, msg_flags=MSG_TRUNC}, 0) = 16

如果我重新格式化它们,它们看起来有点像这样(作为十六进制转储):(请注意,这些来自不同的运行,因此 pid 值会不同,但重新格式化的 strace 输出的其余部分是相同的。)

sent from iotop24000000 10000100 01000000 42efffff03000000 0e000200 5441534b 53544154 53000000received by iotop70000000 10000000 01000000 42efffff01020000 0e000200 5441534b 53544154 53000000 06000100 17000000 08000300 01000000 08000400 00000000 08000500 04000000 2c000600 14000100 08000100 01000000 08000200 0b000000 14000200 08000100 04000000 08000200 0a000000sent from program24000000 10000100 00000000 d44a000003000000 0e000200 5441534b 53544154 53000000received by program38000000 02000000 00000000 d44a0000

在我看来,有两个区别。

  1. iotop 似乎对 pid 使用负值。我尝试进行更改,以便我的程序也为 pid 发送负数。这没有什么区别。

  2. 我使用分散/聚集方法:这样可以减少内存浪费(这可能会受到我想要的目标 PC 的限制)。但是,我怀疑有一些(如果不是全部)Netlink 组件仅支持按请求发送和接收单个缓冲区。

有人知道 Netlink 是否允许分散/聚集,或者是否要求所有通信一次在一个大缓冲区中完成?

最佳答案

需要记住的一件事是,您需要特定的功能(CAP_NET_ADMIN、CAP_NET_RAW 之一)才能使用 netlink。一般来说,只有 root 才具备必要的能力。有一种方法可以将其提供给普通用户,但这是一个主要问题,涉及额外的 PAM 模块、修改/etc 中的文件以及向可执行文件添加扩展属性。

这对我来说似乎是一个很大的麻烦。

我最终通过放弃所有 asio 代码并粘贴来自 linux 发行版的示例代码来完成这项工作。我怀疑 netlink 与 sendmsg 不能很好地配合。

关于linux - netlink 分散发送导致内核错误响应 (NLMSG_ERROR),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23350602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com