virshのvcpupinとvcpuinfoで表示されるaffinityの違い

以前virsh vcpupinvirsh vcpuinfo で表示されるCPUのAffinity情報が違うということがありました.

% sudo virsh vcpupin vm1 
VCPU   CPU Affinity
----------------------
 0      0-47
 1      0-47
 2      0-47
[...]
% sudo virsh vcpuinfo vm1
VCPU:           0
CPU:            25
State:          running
CPU time:       508.0s
CPU Affinity:   ------------------------yyyyyyyyyyyyyyyyyyyyyyyy

動作的には virsh vcpuinfo の情報の方が正しく,なんでかなぁと思ってたんですが,ソースを調べてみたら virsh vcpuinfo は呼ばれるたびに sched_getaffinity() でアフィニティを取得するのに対して, virsh vcpupin の方はlibvirt内部の情報を参照しているようでした.結果としてlibvirtの外部からCPUアフィニティが変更されるとこのように情報に差異が生じるようです.

実際にlibvirtdをstraceするか,bpftraceなどで sched_getaffinity() の呼び出しを監視すると, virsh cpuinfo コマンドを実行すると shced_getaffinity() が実行されるのに対して,もう一方はされないことが確認できます(なお,virshコマンドはlibvirtdとRPCでやりとりしていますので,virshコマンドの方を対象に監視しても結果は得られません).

ということでlibvirtを使っているときゲストのCPU affinityを知りたいなら virsh vcpuinfo を使った方が良いという話でした(※こちら2020年10月ごろのlibvirtdをコンパイルして使ったときの情報になります).