Π Linux Π΅ΡΡΡ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΡΠ΄ΡΠ° ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. ΠΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΈΠ· Π½ΠΈΡ
Π½Π΅Π³Π°ΡΠΈΠ²Π½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π½Π΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Ρ Π² ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π΅.
ΠΠ°ΡΡ Π»Π΅Ρ Π½Π°Π·Π°Π΄ Π±ΡΠ»
Π‘Π΅ΠΉΡΠ°Ρ ΡΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΡ
ΡΡΠΈΠ»ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ eBPF, ΠΈ Π² ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΡ ΡΡΠΈΠ»ΠΈΡΡ Π΄Π»Ρ ΠΏΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ
Ceph Is Slow
Π ΠΊΠ»Π°ΡΡΠ΅Ρ Ceph Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π½ΠΎΠ²ΡΠΉ Ρ ΠΎΡΡ. ΠΠΎΡΠ»Π΅ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΈ ΡΠ°ΡΡΠΈ Π΄Π°Π½Π½ΡΡ Π½Π° Π½Π΅Π³ΠΎ ΠΌΡ Π·Π°ΠΌΠ΅ΡΠΈΠ»ΠΈ, ΡΡΠΎ ΡΠΊΠΎΡΠΎΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° Π·Π°ΠΏΠΈΡΡ ΠΈΠΌ Π³ΠΎΡΠ°Π·Π΄ΠΎ Π½ΠΈΠΆΠ΅, ΡΠ΅ΠΌ Π½Π° Π΄ΡΡΠ³ΠΈΡ ΡΠ΅ΡΠ²Π΅ΡΠ°Ρ .
Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ Π΄ΡΡΠ³ΠΈΡ
ΠΏΠ»Π°ΡΡΠΎΡΠΌ, Π½Π° ΡΡΠΎΠΌ Ρ
ΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ bcache ΠΈ Π½ΠΎΠ²ΠΎΠ΅ ΡΠ΄ΡΠΎ linux 4.15. Π₯ΠΎΡΡ ΡΠ°ΠΊΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π·Π΄Π΅ΡΡ Π²ΠΏΠ΅ΡΠ²ΡΠ΅. Π Π½Π° ΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ Π±ΡΠ»ΠΎ ΡΡΠ½ΠΎ, ΡΡΠΎ ΠΊΠΎΡΠ½Π΅ΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠ΅ΠΎΡΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΌΠΎΠ³Π»ΠΎ Π±ΡΡΡ ΡΡΠΎ ΡΠ³ΠΎΠ΄Π½ΠΎ.
Investigating the Host
ΠΠ°ΡΠ½Π΅ΠΌ Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΡΡΠΎ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ Π²Π½ΡΡΡΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠ° ceph-osd. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ
ΠΠ°ΡΡΠΈΠ½ΠΊΠ° Π³ΠΎΠ²ΠΎΡΠΈΡ Π½Π°ΠΌ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ fdatasync() ΠΏΠΎΡΡΠ°ΡΠΈΠ»Π° ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΡΠΈ ΠΎΡΠΏΡΠ°Π²ΠΊΠ΅ Π·Π°ΠΏΡΠΎΡΠ° Π² ΡΡΠ½ΠΊΡΠΈΠΈ generic_make_request(). ΠΠ½Π°ΡΠΈΡ, ΡΡΠΎ ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΠΏΡΠΈΡΠΈΠ½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π³Π΄Π΅-ΡΠΎ Π²Π½Π΅ ΡΠ°ΠΌΠΎΠ³ΠΎ Π΄Π΅ΠΌΠΎΠ½Π° osd. ΠΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π»ΠΈΠ±ΠΎ ΡΠ΄ΡΠΎ, Π»ΠΈΠ±ΠΎ Π΄ΠΈΡΠΊΠΈ. ΠΡΠ²ΠΎΠ΄ iostat ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π» Π²ΡΡΠΎΠΊΡΡ Π·Π°Π΄Π΅ΡΠΆΠΊΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠΎΠ² bcache-Π΄ΠΈΡΠΊΠ°ΠΌΠΈ.
ΠΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ΅ Ρ ΠΎΡΡΠ° ΠΌΡ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ»ΠΈ, ΡΡΠΎ Π΄Π΅ΠΌΠΎΠ½ systemd-udevd ΠΏΠΎΡΡΠ΅Π±Π»ΡΠ΅Ρ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ CPU β ΠΎΠΊΠΎΠ»ΠΎ 20% Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ΄ΡΠ°Ρ . ΠΡΠΎ ΡΡΡΠ°Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, ΡΠ°ΠΊ ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ Π²ΡΡΡΠ½ΠΈΡΡ Π΅Π³ΠΎ ΠΏΡΠΈΡΠΈΠ½Ρ. Π’Π°ΠΊ ΠΊΠ°ΠΊ Systemd-udevd ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Ρ ueventβΠ°ΠΌΠΈ, ΠΌΡ ΡΠ΅ΡΠΈΠ»ΠΈ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π½Π° Π½ΠΈΡ ΡΠ΅ΡΠ΅Π· udevadm monitor. ΠΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ, Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π»ΠΎΡΡ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ change-ΡΠΎΠ±ΡΡΠΈΠΉ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π±Π»ΠΎΡΠ½ΠΎΠ³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π° Π² ΡΠΈΡΡΠ΅ΠΌΠ΅. ΠΡΠΎ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π½Π΅ΠΎΠ±ΡΡΠ½ΠΎ, ΠΏΠΎΡΡΠΎΠΌΡ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ, ΡΡΠΎ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ Π²ΡΠ΅ ΡΡΠΈ ΠΈΠ²Π΅Π½ΡΡ.
Using the BCC Toolkit
ΠΠ°ΠΊ ΠΌΡ ΡΠΆΠ΅ Π²ΡΡΡΠ½ΠΈΠ»ΠΈ, ΡΠ΄ΡΠΎ (ΠΈ Π΄Π΅ΠΌΠΎΠ½ ceph Π² ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠΌ Π²ΡΠ·ΠΎΠ²Π΅) ΡΡΠ°ΡΠΈΡ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π² generic_make_request(). ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π·Π°ΠΌΠ΅ΡΠΈΡΡ ΡΠΊΠΎΡΠΎΡΡΡ ΡΠ°Π±ΠΎΡΡ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ. Π
ΠΠ±ΡΡΠ½ΠΎ ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π±ΡΡΡΡΠΎ. ΠΡΠ΅, ΡΡΠΎ ΠΎΠ½Π° Π΄Π΅Π»Π°Π΅Ρ β ΠΏΠ΅ΡΠ΅Π΄Π°Π΅Ρ Π·Π°ΠΏΡΠΎΡ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠ° ΡΡΡΡΠΎΠΉΡΡΠ²Π°.
Bcache β ΡΡΠΎ ΡΠ»ΠΎΠΆΠ½ΠΎΠ΅ ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΡΡΠ΅Ρ Π΄ΠΈΡΠΊΠΎΠ²:
- backing device (ΠΊΠ΅ΡΠΈΡΡΠ΅ΠΌΡΠΉ Π΄ΠΈΡΠΊ), Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΡΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡΠΉ HDD;
- caching device (ΠΊΠ΅ΡΠΈΡΡΡΡΠΈΠΉ Π΄ΠΈΡΠΊ), Π·Π΄Π΅ΡΡ ΡΡΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·Π΄Π΅Π» NVMe ΡΡΡΡΠΎΠΉΡΡΠ²Π°;
- Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ Π΄Π΅Π²Π°ΠΉΡ bcache, Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
ΠΡ Π·Π½Π°Π΅ΠΌ, ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° Π·Π°ΠΏΡΠΎΡΠ° ΡΠΎΡΠΌΠΎΠ·ΠΈΡ, Π½ΠΎ Π΄Π»Ρ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΈΠ· ΡΡΠΈΡ ΡΡΡΡΠΎΠΉΡΡΠ²? Π Π°Π·Π±Π΅ΡΠ΅ΠΌΡΡ Ρ ΡΡΠΈΠΌ ΡΡΡΡ ΠΏΠΎΠ·ΠΆΠ΅.
Π‘Π΅ΠΉΡΠ°Ρ ΠΌΡ Π·Π½Π°Π΅ΠΌ, ΡΡΠΎ ueventβΡ, Π²Π΅ΡΠΎΡΡΠ½ΠΎ, ΠΏΡΠΈΠ²ΠΎΠ΄ΡΡ ΠΊ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ. ΠΠ°ΠΉΡΠΈ, ΡΡΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΈΡ
Π³Π΅Π½Π΅ΡΠ°ΡΠΈΡ, Π½Π΅ ΡΠ°ΠΊ ΠΏΡΠΎΡΡΠΎ. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ ΡΡΠΎ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΡΠΎΡΡ, Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌΡΠΉ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈ. ΠΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΡΡΠΎ Π·Π° ΡΠΎΡΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Π² ΡΠΈΡΡΠ΅ΠΌΠ΅, Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΊΡΠΈΠΏΡΠ° execsnoop ΠΈΠ· ΡΠΎΠ³ΠΎ ΠΆΠ΅
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΎΡ ΡΠ°ΠΊ:
/usr/share/bcc/tools/execsnoop | tee ./execdump
ΠΠ΅ Π±ΡΠ΄Π΅ΠΌ Π·Π΄Π΅ΡΡ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡ ΠΏΠΎΠ»Π½ΡΠΉ Π²ΡΠ²ΠΎΠ΄ execsnoop, Π½ΠΎ ΠΎΠ΄Π½Π° ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΡΡΠ°Ρ Π½Π°Ρ ΡΡΡΠΎΠΊΠ° Π²ΡΠ³Π»ΡΠ΄Π΅Π»Π° Π²ΠΎΡ ΡΠ°ΠΊ:
sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:/]' '{print $2}' | sed 's/^ ([0-9]*) C.*/1/'
Π’ΡΠ΅ΡΡΡ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° ΡΡΠΎ PPID (parent PID) ΠΏΡΠΎΡΠ΅ΡΡΠ°. ΠΡΠΎΡΠ΅ΡΡΠΎΠΌ Ρ PID 5802 ΠΎΠΊΠ°Π·Π°Π»ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² Π½Π°ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π°. ΠΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΠΈΡΡΠ΅ΠΌΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° Π±ΡΠ»ΠΈ Π½Π°ΠΉΠ΄Π΅Π½Ρ ΠΎΡΠΈΠ±ΠΎΡΠ½ΠΎ Π·Π°Π΄Π°Π½Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ. Π’Π΅ΠΌΠΏΠ΅ΡΠ°ΡΡΡΠ° HBA-Π°Π΄Π°ΠΏΡΠ΅ΡΠ° ΡΠ½ΠΈΠΌΠ°Π»Π°ΡΡ ΡΠ°Π· Π² 30 ΡΠ΅ΠΊΡΠ½Π΄, ΡΡΠΎ Π³ΠΎΡΠ°Π·Π΄ΠΎ ΡΠ°ΡΠ΅, ΡΠ΅ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ. ΠΠΎΡΠ»Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π° Π±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ, ΠΌΡ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ»ΠΈ, ΡΡΠΎ Π·Π°Π΄Π΅ΡΠΆΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΡΠΎΠΌ Ρ ΠΎΡΡΠ΅ ΠΏΠ΅ΡΠ΅ΡΡΠ°Π»Π° Π²ΡΠ΄Π΅Π»ΡΡΡΡ Π½Π° ΡΠΎΠ½Π΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΡ Ρ ΠΎΡΡΠΎΠ².
ΠΠΎ Π²ΡΡ Π΅ΡΡ Π½Π΅ΠΏΠΎΠ½ΡΡΠ½ΠΎ, ΠΏΠΎΡΠ΅ΠΌΡ bcache-ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ ΡΠ°ΠΊ ΡΠΎΡΠΌΠΎΠ·ΠΈΠ»ΠΎ. ΠΡ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΠ»ΠΈ ΡΠ΅ΡΡΠΎΠ²ΡΡ ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ ΠΈ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°Π»ΠΈ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π·Π°ΠΏΡΡΡΠΈΠ² fio Π½Π° bcache, ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈ Π·Π°ΠΏΡΡΠΊΠ°Ρ udevadm trigger Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ uevents.
Writing BCC-Based Tools
ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠΎΡΡΡΡ ΡΡΠΈΠ»ΠΈΡΡ Π΄Π»Ρ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΠΈ Π²ΡΠ²ΠΎΠ΄Π° Π½Π° ΡΠΊΡΠ°Π½ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ² generic_make_request(). ΠΠ°Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ΅Ρ ΠΈΠΌΡ Π΄ΠΈΡΠΊΠ°, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ»Π° Π²ΡΠ·Π²Π°Π½Π° ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ.
ΠΠ»Π°Π½ ΠΏΡΠΎΡΡ:
- Π Π΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΠΌ kprobe Π½Π° generic_make_request():
- Π‘ΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ Π² ΠΏΠ°ΠΌΡΡΡ ΠΈΠΌΡ Π΄ΠΈΡΠΊΠ°, Π΄ΠΎΡΡΡΠΏΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π· Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΡΡΠ½ΠΊΡΠΈΠΈ;
- Π‘ΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ ΠΌΠ΅ΡΠΊΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ.
- Π Π΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΠΌ kretprobe Π½Π° Π²ΠΎΠ·Π²ΡΠ°Ρ ΠΈΠ· generic_make_request():
- ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ΅ΠΊΡΡΡΡ ΠΌΠ΅ΡΠΊΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ;
- ΠΡΠ΅ΠΌ ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΡΡ ΠΌΠ΅ΡΠΊΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌ Ρ ΡΠ΅ΠΊΡΡΠ΅ΠΉ;
- ΠΡΠ»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π±ΠΎΠ»ΡΡΠ΅ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ, ΡΠΎ Π½Π°Ρ ΠΎΠ΄ΠΈΠΌ ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΠΎΠ΅ ΠΈΠΌΡ Π΄ΠΈΡΠΊΠ° ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌ Π½Π° ΡΠ΅ΡΠΌΠΈΠ½Π°Π».
Kprobes ΠΈ kretprobes ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌ ΡΠΎΡΠ΅ΠΊ ΠΎΡΡΠ°Π½ΠΎΠ²Π° Π΄Π»Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΊΠΎΠ΄Π° ΡΡΠ½ΠΊΡΠΈΠΉ Π½Π° Π»Π΅ΡΡ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ
Π’Π΅ΠΊΡΡ eBPF Π²Π½ΡΡΡΠΈ python-ΡΠΊΡΠΈΠΏΡΠ° Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
bpf_text = βββ # Here will be the bpf program code βββ
ΠΠ»Ρ ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½ΡΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ, eBPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ
struct data_t {
u64 pid;
u64 ts;
char comm[TASK_COMM_LEN];
u64 lat;
char disk[DISK_NAME_LEN];
};
BPF_HASH(p, u64, struct data_t);
BPF_PERF_OUTPUT(events);
ΠΠ΄Π΅ΡΡ ΠΌΡ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΠΌ Ρ
ΡΡ-ΡΠ°Π±Π»ΠΈΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ p, Ρ ΠΊΠ»ΡΡΠΎΠΌ ΡΠΈΠΏΠ° u64 ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΈΠΏΠ° struct data_t. Π’Π°Π±Π»ΠΈΡΠ° Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ½Π° Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Π½Π°ΡΠ΅ΠΉ BPF-ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΠ°ΠΊΡΠΎΡ BPF_PERF_OUTPUT ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅Ρ Π΄ΡΡΠ³ΡΡ ΡΠ°Π±Π»ΠΈΡΡ, Π½Π°Π·ΡΠ²Π°Π΅ΠΌΡΡ events, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ
ΠΡΠΈ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΈ Π·Π°Π΄Π΅ΡΠΆΠ΅ΠΊ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠΎΠΌ ΠΈΠ· Π½Π΅Π΅, Π»ΠΈΠ±ΠΎ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ·ΠΎΠ²Π°ΠΌΠΈ ΡΠ°Π·Π½ΡΡ
ΡΡΠ½ΠΊΡΠΈΠΉ, Π½ΡΠΆΠ½ΠΎ ΡΡΠΈΡΡΠ²Π°ΡΡ, ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°ΡΡ ΠΎΠ΄Π½ΠΎΠΌΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΡ. ΠΡΡΠ³ΠΈΠΌΠΈ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ, Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡΡ ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΌ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎΠΌ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΡΠ½ΠΊΡΠΈΠΉ. Π£ Π½Π°Ρ Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΠ·ΠΌΠ΅ΡΠΈΡΡ Π·Π°Π΄Π΅ΡΠΆΠΊΡ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠΎΠΌ ΠΈΠ· ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°, Π½ΠΎ ΡΡΠΎ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, Π±Π΅ΡΠΏΠΎΠ»Π΅Π·Π½ΠΎ. Π₯ΠΎΡΠΎΡΠΈΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠΌ Π·Π΄Π΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ ΡΠ»ΡΠΆΠΈΡΡ
ΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΊΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ ΠΈΡΡΠ»Π΅Π΄ΡΠ΅ΠΌΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ:
void start(struct pt_regs *ctx, struct bio *bio) {
u64 pid = bpf_get_current_pid_tgid();
struct data_t data = {};
u64 ts = bpf_ktime_get_ns();
data.pid = pid;
data.ts = ts;
bpf_probe_read_str(&data.disk, sizeof(data.disk), (void*)bio->bi_disk->disk_name);
p.update(&pid, &data);
}
ΠΠ΄Π΅ΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π²ΡΠΎΡΠΎΠ³ΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄ΡΡΠ°Π²Π»Π΅Π½ ΠΏΠ΅ΡΠ²ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ Π²ΡΠ·Π²Π°Π½Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ
Π‘Π»Π΅Π΄ΡΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ Π½Π° Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅ ΠΈΠ· generic_make_request():
void stop(struct pt_regs *ctx) {
u64 pid = bpf_get_current_pid_tgid();
u64 ts = bpf_ktime_get_ns();
struct data_t* data = p.lookup(&pid);
if (data != 0 && data->ts > 0) {
bpf_get_current_comm(&data->comm, sizeof(data->comm));
data->lat = (ts - data->ts)/1000;
if (data->lat > MIN_US) {
FACTOR
data->pid >>= 32;
events.perf_submit(ctx, data, sizeof(struct data_t));
}
p.delete(&pid);
}
}
ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ ΡΡ ΠΎΠΆΠ° Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ: ΡΠ·Π½Π°Π΅ΠΌ PID ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΌΠ΅ΡΠΊΡ, Π½ΠΎ Π½Π΅ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ Π½ΠΎΠ²ΡΡ ΡΡΡΡΠΊΡΡΡΡ data. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ ΠΈΡΠ΅ΠΌ Π² Ρ ΡΡ-ΡΠ°Π±Π»ΠΈΡΠ΅ ΡΠΆΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΡΡ ΡΡΡΡΠΊΡΡΡΡ ΠΏΠΎ ΠΊΠ»ΡΡΡ == ΡΠ΅ΠΊΡΡΠΈΠΉ PID. ΠΡΠ»ΠΈ ΡΡΡΡΠΊΡΡΡΠ° Π½Π°ΡΠ»Π°ΡΡ, ΡΠΎ ΠΌΡ ΡΠ·Π½Π°Π΅ΠΌ ΠΈΠΌΡ Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ° ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π΅Π³ΠΎ Π² Π½Π΅Ρ.
ΠΠΈΠ½Π°ΡΠ½ΡΠΉ ΡΠ΄Π²ΠΈΠ³, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ Π·Π΄Π΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ, Π½ΡΠΆΠ΅Π½ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ thread GID. Ρ.Π΅. PID ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΠΏΡΡΡΠΈΠ» ΠΏΠΎΡΠΎΠΊ, Π² ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΡ ΡΠ°Π±ΠΎΡΠ°Π΅ΠΌ. ΠΡΠ·ΡΠ²Π°Π΅ΠΌΠ°Ρ Π½Π°ΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡ
ΠΡΠΈ Π²ΡΠ²ΠΎΠ΄Π΅ Π² ΡΠ΅ΡΠΌΠΈΠ½Π°Π» Π½Π°Ρ ΡΠ΅ΠΉΡΠ°Ρ Π½Π΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ΅Ρ ΠΏΠΎΡΠΎΠΊ, Π½ΠΎ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ΅Ρ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΠΏΡΠΎΡΠ΅ΡΡ. ΠΠΎΡΠ»Π΅ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠΉ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ Ρ Π·Π°Π΄Π°Π½Π½ΡΠΌ ΠΏΠΎΡΠΎΠ³ΠΎΠΌ, ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ Π½Π°ΡΡ ΡΡΡΡΠΊΡΡΡΡ data Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠ΅ΡΠ΅Π· ΡΠ°Π±Π»ΠΈΡΡ events, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ ΡΠ΄Π°Π»ΡΠ΅ΠΌ Π·Π°ΠΏΠΈΡΡ ΠΈΠ· p.
Π python-ΡΠΊΡΠΈΠΏΡΠ΅, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π·Π°Π³ΡΡΠΆΠ°ΡΡ Π΄Π°Π½Π½ΡΠΉ ΠΊΠΎΠ΄, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ MIN_US ΠΈ FACTOR Π½Π° ΠΏΠΎΡΠΎΠ³ΠΈ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ ΠΈ Π΅Π΄ΠΈΠ½ΠΈΡΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΄ΠΈΠΌ ΡΠ΅ΡΠ΅Π· Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ:
bpf_text = bpf_text.replace('MIN_US',str(min_usec))
if args.milliseconds:
bpf_text = bpf_text.replace('FACTOR','data->lat /= 1000;')
label = "msec"
else:
bpf_text = bpf_text.replace('FACTOR','')
label = "usec"
Π’Π΅ΠΏΠ΅ΡΡ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΡ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΠ΅ΡΠ΅Π·
b = BPF(text=bpf_text)
b.attach_kprobe(event="generic_make_request",fn_name="start")
b.attach_kretprobe(event="generic_make_request",fn_name="stop")
Π’Π°ΠΊΠΆΠ΅ Π½Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ struct data_t Π² Π½Π°ΡΠ΅ΠΌ ΡΠΊΡΠΈΠΏΡΠ΅, ΠΈΠ½Π°ΡΠ΅ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΡ:
TASK_COMM_LEN = 16 # linux/sched.h
DISK_NAME_LEN = 32 # linux/genhd.h
class Data(ct.Structure):
_fields_ = [("pid", ct.c_ulonglong),
("ts", ct.c_ulonglong),
("comm", ct.c_char * TASK_COMM_LEN),
("lat", ct.c_ulonglong),
("disk",ct.c_char * DISK_NAME_LEN)]
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΡΠ°Π³ β Π²ΡΠ²ΠΎΠ΄ Π΄Π°Π½Π½ΡΡ Π½Π° ΡΠ΅ΡΠΌΠΈΠ½Π°Π»:
def print_event(cpu, data, size):
global start
event = ct.cast(data, ct.POINTER(Data)).contents
if start == 0:
start = event.ts
time_s = (float(event.ts - start)) / 1000000000
print("%-18.9f %-16s %-6d %-1s %s %s" % (time_s, event.comm, event.pid, event.lat, label, event.disk))
b["events"].open_perf_buffer(print_event)
# format output
start = 0
while 1:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()
Π‘Π°ΠΌ ΡΠΊΡΠΈΠΏΡ Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π½Π°
ΠΠ°ΠΊΠΎΠ½Π΅Ρ-ΡΠΎ! Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΡΠΎ, ΡΡΠΎ Π²ΡΠ³Π»ΡΠ΄Π΅Π»ΠΎ ΠΊΠ°ΠΊ ΡΠΎΡΠΌΠΎΠ·ΡΡΠ΅Π΅ bcache-ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ, Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ β ΡΠΎΡΠΌΠΎΠ·ΡΡΠΈΠΉ Π²ΡΠ·ΠΎΠ² generic_make_request() Π΄Π»Ρ ΠΊΡΡΠΈΡΡΠ΅ΠΌΠΎΠ³ΠΎ Π΄ΠΈΡΠΊΠ°.
Dig into the Kernel
Π§ΡΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΠΎΡΠΌΠΎΠ·ΠΈΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π·Π°ΠΏΡΠΎΡΠ°? ΠΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ Π·Π°Π΄Π΅ΡΠΆΠΊΠ° Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π΄Π°ΠΆΠ΅ Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π°ΡΠ°Π»Π° Π°ΠΊΠΊΠ°ΡΠ½ΡΠΈΠ½Π³Π° Π·Π°ΠΏΡΠΎΡΠ°, Ρ.Π΅. ΡΡΠ΅Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° ΡΡΠ°ΡΠΈΡΡΠΈΠΊΠΈ ΠΏΠΎ Π½Π΅ΠΌΡ (/proc/diskstats ΠΈΠ»ΠΈ iostat) Π΅ΡΡ Π½Π΅ Π½Π°ΡΠ°Π»ΡΡ. ΠΡΠΎ Π»Π΅Π³ΠΊΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ, Π·Π°ΠΏΡΡΡΠΈΠ² iostat Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, Π»ΠΈΠ±ΠΎ
ΠΡΠ»ΠΈ ΠΌΡ Π²Π·Π³Π»ΡΠ½Π΅ΠΌ Π½Π° ΡΡΠ½ΠΊΡΠΈΡ generic_make_request(), ΡΠΎ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ Π΄ΠΎ Π½Π°ΡΠ°Π»Π° Π°ΠΊΠΊΠ°ΡΠ½ΡΠΈΠ½Π³Π° Π·Π°ΠΏΡΠΎΡΠ° Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ Π΅ΡΡ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠ΅ΡΠ²Π°Ρ β generic_make_request_checks(), Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π»Π΅Π³ΠΈΡΠΈΠΌΠ½ΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½Π°ΡΡΡΠΎΠ΅ΠΊ Π΄ΠΈΡΠΊΠ°. ΠΡΠΎΡΠ°Ρ β
ret = wait_event_interruptible(q->mq_freeze_wq,
(atomic_read(&q->mq_freeze_depth) == 0 &&
(preempt || !blk_queue_preempt_only(q))) ||
blk_queue_dying(q));
Π Π½Π΅ΠΌ ΡΠ΄ΡΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ ΡΠ°Π·ΠΌΠΎΡΠΎΠ·ΠΊΠΈ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. ΠΠ°ΠΌΠ΅ΡΠΈΠΌ Π·Π°Π΄Π΅ΡΠΆΠΊΡ blk_queue_enter():
~# /usr/share/bcc/tools/funclatency blk_queue_enter -i 1 -m
Tracing 1 functions for "blk_queue_enter"... Hit Ctrl-C to end.
msecs : count distribution
0 -> 1 : 341 |****************************************|
msecs : count distribution
0 -> 1 : 316 |****************************************|
msecs : count distribution
0 -> 1 : 255 |****************************************|
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 1 | |
ΠΠΎΡ
ΠΎΠΆΠ΅, ΡΡΠΎ ΠΌΡ Π±Π»ΠΈΠ·ΠΊΠΈ ΠΊ ΡΠ°Π·Π³Π°Π΄ΠΊΠ΅. Π€ΡΠ½ΠΊΡΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ Π΄Π»Ρ Β«Π·Π°ΠΌΠΎΡΠΎΠ·ΠΊΠΈ/ΡΠ°Π·ΠΌΠΎΡΠΎΠ·ΠΊΠΈΒ» ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ β ΡΡΠΎ
ΠΡΠ΅ΠΌΡ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΠΎΡΠΈΡΡΠΊΠΈ ΡΡΠΎΠΉ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΡΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½ΡΠ½ΠΎ Π·Π°Π΄Π΅ΡΠΆΠΊΠ΅ Π΄ΠΈΡΠΊΠ°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠ΄ΡΠΎ ΠΆΠ΄Π΅Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π²ΡΠ΅Ρ
ΠΏΠΎΡΡΠ°Π²Π»Π΅Π½Π½ΡΡ
Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ. ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΡΡΡΠ΅Π΅Ρ, ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π½Π°ΡΡΡΠΎΠ΅ΠΊ. ΠΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ
Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ Π·Π½Π°Π΅ΠΌ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΡΠ°Π²ΠΈΡΡ ΡΠΈΡΡΠ°ΡΠΈΡ. ΠΠΎΠΌΠ°Π½Π΄Π° udevadm trigger Π² ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²Π΅Π΄Π΅Ρ ΠΊ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ Π½Π°ΡΡΡΠΎΠ΅ΠΊ Π΄Π»Ρ Π±Π»ΠΎΡΠ½ΠΎΠ³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π°. ΠΡΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΎΠΏΠΈΡΠ°Π½Ρ Π² ΠΏΡΠ°Π²ΠΈΠ»Π°Ρ
udev. ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΉΡΠΈ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Β«Π·Π°ΠΌΠΎΡΠ°ΠΆΠΈΠ²Π°ΡΡΒ» ΠΎΡΠ΅ΡΠ΅Π΄Ρ, ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°Π² ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΠΈΡ
ΡΠ΅ΡΠ΅Π· sysfs Π»ΠΈΠ±ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π² ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ΄ΡΠ°. Π Π΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ ΡΡΠΈΠ»ΠΈΡΡ BCC
~# /usr/share/bcc/tools/trace blk_freeze_queue -K -U
PID TID COMM FUNC
3809642 3809642 systemd-udevd blk_freeze_queue
blk_freeze_queue+0x1 [kernel]
elevator_switch+0x29 [kernel]
elv_iosched_store+0x197 [kernel]
queue_attr_store+0x5c [kernel]
sysfs_kf_write+0x3c [kernel]
kernfs_fop_write+0x125 [kernel]
__vfs_write+0x1b [kernel]
vfs_write+0xb8 [kernel]
sys_write+0x55 [kernel]
do_syscall_64+0x73 [kernel]
entry_SYSCALL_64_after_hwframe+0x3d [kernel]
__write_nocancel+0x7 [libc-2.23.so]
[unknown]
3809631 3809631 systemd-udevd blk_freeze_queue
blk_freeze_queue+0x1 [kernel]
queue_requests_store+0xb6 [kernel]
queue_attr_store+0x5c [kernel]
sysfs_kf_write+0x3c [kernel]
kernfs_fop_write+0x125 [kernel]
__vfs_write+0x1b [kernel]
vfs_write+0xb8 [kernel]
sys_write+0x55 [kernel]
do_syscall_64+0x73 [kernel]
entry_SYSCALL_64_after_hwframe+0x3d [kernel]
__write_nocancel+0x7 [libc-2.23.so]
[unknown]
Udev-ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΌΠ΅Π½ΡΡΡΡΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΡΠ΅Π΄ΠΊΠΎ ΠΈ ΠΎΠ±ΡΡΠ½ΠΎ ΡΡΠΎ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ ΠΏΠΎΠ΄ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½ΠΎ. Π’Π°ΠΊ ΡΡΠΎ ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ Π΄Π°ΠΆΠ΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠΆΠ΅ Π·Π°Π΄Π°Π½Π½ΡΡ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π²ΡΠΏΠ»Π΅ΡΠΊ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° ΠΎΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π΄ΠΈΡΠΊΡ. ΠΠΎΠ½Π΅ΡΠ½ΠΎ, Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ udev-ΡΠΎΠ±ΡΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ
ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π΄ΠΈΡΠΊΠΎΠ² (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ Π½Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ/ΠΎΡΠΊΠ»ΡΡΠ°Π΅ΡΡΡ), Π½Π΅ ΠΎΡΠ΅Π½Ρ Ρ
ΠΎΡΠΎΡΠ°Ρ ΠΏΡΠ°ΠΊΡΠΈΠΊΠ°. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΌΠΎΡΡ ΡΠ΄ΡΡ Π½Π΅ Π΄Π΅Π»Π°ΡΡ Π±Π΅ΡΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ ΡΠ°Π±ΠΎΡΡ ΠΈ Π½Π΅ Β«Π·Π°ΠΌΠΎΡΠ°ΠΆΠΈΠ²Π°ΡΡΒ» ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π·Π°ΠΏΡΠΎΡΠΎΠ², Π΅ΡΠ»ΠΈ Π² ΡΡΠΎΠΌ Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.
Conclusion
eBPF β ΡΡΠΎ ΠΎΡΠ΅Π½Ρ Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΈ ΠΌΠΎΡΠ½ΡΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ. Π ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΊΠ΅ΠΉΡ ΠΈ ΠΏΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ ΠΌΠ°Π»ΡΡ ΡΠ°ΡΡΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ. ΠΡΠ»ΠΈ Π²Π°ΠΌ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ° BCC-ΡΡΠΈΠ»ΠΈΡ, ΡΡΠΎΠΈΡ Π²Π·Π³Π»ΡΠ½ΡΡΡ Π½Π°
ΠΡΡΡ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΠΈ ΠΏΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΡΠ΅ Π½Π° eBPF. ΠΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ
β
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com