2014-04-28 4 views
0

Netlink 프로토콜을 사용하여 작업 통계를 수집하는 프로그램을 작성하고 있습니다. 커널이 유효한 패킷이라고 믿는 오류로 응답하기 때문에별로 멀지는 않습니다. strace를 사용하여 내 프로그램의 동작을 올바르게 작동하는 iotop의 동작과 비교했습니다.netlink scatter send가 커널 (NLMSG_ERROR)에서 오류 응답을 발생시킵니다.

iotop에서의 strace의 관련 비트 :

 
socket(PF_NETLINK, SOCK_RAW, 16)  = 3 
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [65536], 4) = 0 
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0 
bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0 
getsockname(3, {sa_family=AF_NETLINK, pid=-4286, groups=00000000}, [12]) = 0 
sendto(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 출력의 해당 부분 :

 
bind(8, {sa_family=AF_NETLINK, pid=19156, groups=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 

나는이를 다시 포맷하는 경우, 그들은 (이 같은 비트를 봐 16 진수 덤프) : (이들은 서로 다른 실행이므로 pid 값은 다르지만 형식이 변경된 strace 출력의 나머지는 동일합니다.)

 
sent from iotop 
24000000 10000100 01000000 42efffff 
03000000 0e000200 5441534b 53544154 
53000000 

received by 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 

sent from program 
24000000 10000100 00000000 d44a0000 
03000000 0e000200 5441534b 53544154 
53000000 

received by program 
38000000 02000000 00000000 d44a0000 

두 가지 차이점이있는 것 같습니다.

  1. iotop은 pid에 음수 값을 사용하는 것으로 보입니다. 내 프로그램이 pid에 음수를 보내도록 변경하려고했습니다. 이것은 아무런 효과가 없었다.

  2. 필자는 분산/수집 방식을 사용합니다. 메모리에 낭비가 적습니다 (대상 PC에서 제한 될 수 있음). 그러나 요청 당 하나의 버퍼를 보내고받는 것만 지원하는 일부 Netlink 구성 요소가 있다고 의심됩니다.

Netlink에서 분산/수집을 허용하는지 또는 모든 통신이 한 번에 하나의 큰 버퍼에서 수행되어야하는지 알고 있습니까?

답변

0

netlink를 사용하려면 특정 기능 (CAP_NET_ADMIN, CAP_NET_RAW 중 하나)이 필요하다는 점을 명심해야합니다. 일반적으로 필요한 기능을 가진 것은 루트에 불과합니다. 이것을 일반 사용자에게 줄 수있는 방법이 있지만, PAM 모듈을 추가하고/etc의 파일을 수정하고 확장 된 속성을 실행 파일에 추가하는 것이 주요한 문제입니다.

나에게 많은 문제가있는 것 같습니다.

나는 마침내이 작업을 모든 asio 코드를 버리고 리눅스 배포본에서 예제 코드를 붙여 넣음으로써 만들었다. 나는 넷 링크가 sendmsg와 잘 작동하지 않는다고 생각한다.