タブインターフェイスとそのファイル記述子間の接続を見つけるには?

タブインターフェイスとそのファイル記述子間の接続を見つけるには?

qemu一時インターフェースを作成するオーケストレーションスクリプトで始まった仮想マシンがありますtap。プロセスのコマンドライン引数を確認すると、qemu-system-x86_64プロセスがファイルtap記述子を使用してすでに開いているインターフェイスに接続していることがわかります27

-netdev tap,fd=27,id=hostnet1,vhost=on,vhostfd=28

ls -l /proc/<qemu-system-x86_64_PID>/fd/27それによると/dev/net/tun

tapインターフェイス名(たとえばvnet99)を/dev/net/tunwithに渡し、ioctl()正しいfdを返すように動作しますか?それとも一般的に、tapホストのどのインターフェースにファイル記述子27があるのか​​、どうすればわかりますか?

答え1

これiff:間の項目与えることができたでしょう。 回答以前はカーネル3.14に追加されました提出とともにtun: add device name(iff) field to proc fdinfo entryしたがって、Ubuntu 14.04LTSなどのカーネル3.13以下では使用できません。

この場合、カーネルに情報を聞くことはできませんが、カーネルに尋ねることは可能です。実際のコースこの情報はデバッガトレースを使用して提供されます。

Linux 2.6.27 以降、設定されたエントリに関する情報を要求する ioctl を使用できます。トンタップインターフェース:TUNGETIFF。その目的は継承のためです。FDお問い合わせできるようにFD受信インターフェイスの名前とタイプ(ifr_nameそしてifr_flags)またはtuntapデバイスがまだ設定されていないため、(EBADFD)設定する必要があることがわかります。

だから使えますが、gdb、利用可能な開発環境がない場合は、いくつかの必須パラメータと値を知っているか調整する必要があるため、これは少し面倒です(将来またはアーキテクチャによって変更される可能性があります)。この情報と調整はここで必要です。

  • 定義$malloc64ビットシステムでは、返されたメモリアドレスの正しいサイズを処理します。クレジットは次に移動します。このコメントSOで。
  • $malloc(64):struct ifreq64ビットでは40バイトのようです。安全のために64バイトを使用します。
  • 0x800454d2== TUNGETIFF
  • 結果はifr_nameオフセット0にあります。

以下は、見つかった各tuntap fd呼び出しgdbとgdb独自のスクリプトを準備するシェルスクリプトです。

tungetiff.sh:

#!/bin/sh

[ $# -gt 0 ] || exit 1
SCRIPTGDB="$1"; shift

for pid in "$@"; do
    for procfd in /proc/$pid/fd/*; do
        if [ "$(readlink $procfd)" = "/dev/net/tun" ]; then
            fd=$(basename $procfd)
            printf 'pid=%d fd=%d ifname=' $pid $fd
            gdb -batch-silent --pid=$pid -ex 'set $fd'=$fd -x "$SCRIPTGDB"
        fi
    done
done

tungetiff.gdb:

set $malloc=(void *(*)(long long)) malloc
p $malloc(64)
p ioctl($fd, 0x800454d2, $1)
set *((char *)($1+16))=0
set logging file /dev/stdout
set logging on
printf "%s\n",$1
set logging off
call free($1)
quit

一般的な実行例(rootとしてのみ実行でき、libvirt-qemuユーザーもできないようです)qemuシステム):

# ./tungetiff.sh tungetiff.gdb $(pgrep qemu-system-)
pid=22281 fd=26 ifname=vnet1
pid=22281 fd=30 ifname=vnet2
pid=27109 fd=26 ifname=vnet0

答え2

これでファイルディスクリプタ27が既知であるため、/procQEMUプロセスに進むことができます。

 $ ls /proc/<qemu-system-x86_64_PID>/fd/27

このディレクトリと同じレベルには、次の詳細を含むfd他のディレクトリがありますfdinfo

$ cat /proc/<qemu-system-x86_64_PID>/fdinfo/27
pos:    0
flags:  0104002
mnt_id: 18
iff:    tap0123acdc-66

このファイルのエントリはiffタブデバイスです。

引用する

関連情報