0

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
bind(3, {sa_family=AF_NETLINK, pid=0, グループ=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, グループ=00000000}, [ 12]) = 112

私のプログラムからの strace 出力の対応する部分:

bind(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

これらを再フォーマットすると、(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

2つの違いがあるように私には思えます。

  1. iotop は pid に負の値を使用しているようです。私のプログラムもpidに負の数を送信するように変更を試みました。これは違いはありませんでした。

  2. 私はスキャッター/ギャザー アプローチを使用します: メモリの無駄が少なくなります (これは、私が考えているターゲット PC で制約される可能性があります)。ただし、リクエストごとに単一のバッファの送受信のみをサポートする Netlink コンポーネント (すべてではないにしても) がいくつかあると思われます。

Netlink がスキャッター/ギャザーを許可しているかどうか、または一度に 1 つの大きなバッファーですべての通信を行う必要があるかどうかを知っている人はいますか?

4

1 に答える 1

0

netlink を使用するには、特定の機能 (CAP_NET_ADMIN、CAP_NET_RAW のいずれか) が必要であることに注意してください。通常、必要な機能を備えているのは root だけです。これを通常のユーザーに提供する方法はありますが、追加の PAM モジュール、/etc 内のファイルの変更、および実行可能ファイルへの拡張属性の追加が関与する大きな問題です。

それは私には大変なことのように思えます。

最後に、すべての asio コードを捨てて、Linux ディストリビューションからサンプル コードを貼り付けることで、この作業を行いました。netlink は sendmsg とうまく動作しないと思います。

于 2014-05-02T11:02:47.010 に答える