我正在编写一个使用 Netlink 协议收集任务统计信息的程序。我没有走得太远,因为内核对我认为有效的数据包做出了错误响应。我使用 strace 将我的程序的行为与正常工作的 iotop 的行为进行了比较。
来自 iotop 的 strace 的相关位:
套接字(PF_NETLINK,SOCK_RAW,16)= 3 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0 绑定(3,{sa_family=AF_NETLINK,pid=0,组=00000000},12)= 0 getsockname(3, {sa_family=AF_NETLINK, pid=-4286, groups=00000000}, [12]) = 0 发送到(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) = 36 recvfrom(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 输出的相应部分:
绑定(8,{sa_family=AF_NETLINK,pid=19156,组=00000000},12)= 0 setsockopt(8, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0 setsockopt(8, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0 sendmsg(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) = 36 recvmsg(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 输出的其余部分是相同的。)
从 iotop 发送 24000000 10000100 01000000 42efffff 03000000 0e000200 5441534b 53544154 53000000 iotop 收到 70000000 10000000 01000000 42efffff 01020000 0e000200 5441534b 53544154 53000000 06000100 17000000 08000300 01000000 08000400 00000000 08000500 04000000 2c000600 14000100 08000100 01000000 08000200 0b000000 14000200 08000100 04000000 08000200 0a000000 从程序发送 24000000 10000100 00000000 d44a0000 03000000 0e000200 5441534b 53544154 53000000 程序收到 38000000 02000000 00000000 d44a0000
在我看来,有两个不同之处。
iotop 似乎对 pid 使用负值。我尝试进行更改,以便我的程序也为 pid 发送一个负数。这没什么区别。
我使用分散/收集方法:它在内存上的浪费更少(这可能在我想到的目标 PC 中受到限制)。但是,我怀疑有一些(如果不是全部)Netlink 组件仅支持在每个请求时发送和接收单个缓冲区。
有谁知道 Netlink 是否允许分散/聚集,或者它是否需要一次在一个大缓冲区中完成所有通信?