tl; dr: Я хочу увидеть / получить имена файлов, частью которых являются сообщенные номера блоков в dmesg, когда vm.block_dump=1
пример dmesg: bash(13515): READ block 5434824 on xvda3 (32 sectors)
Когда, например. sudo sysctl -w vm.block_dump=1
или напр. echo '1' | sudo tee /proc/sys/vm/block_dump
затем "Linux сообщает обо всех выполняемых операциях чтения и записи на диск и о всех загрязнениях блоков, сделанных в файлы. [...] Вывод block_dump записывается в вывод ядра, и его можно получить с помощью" dmesg " . Когда вы используете block_dump и ваш уровень ведения журнала ядра также включает в себя сообщения отладки ядра, вы, вероятно, захотите отключить klogd, в противном случае выходные данные block_dump будут регистрироваться, вызывая активность диска, которая обычно там не присутствует. " (цитата из здесь )
"Загрязнения блоков" не являются проблемой, например.
[ 3140.559675] systemd-journal(291): dirtied inode 399135 (system.journal) on xvda3
Я вижу его имя файла так:
$ echo -e 'open /dev/xvda3\n ncheck 399135' | sudo debugfs -f -
debugfs 1.44.2 (14-May-2018)
debugfs: open /dev/xvda3
debugfs: ncheck 399135
Inode Pathname
399135 /var/log/journal/12c5e521101c444594b96b53751551a8/system.journal
Проблема в том, что «Linux сообщает обо всех операциях чтения и записи на диске, которые имеют место» (если цитировать из вышеприведенного), когда они сообщаются в блоках, например.
[ 3140.376827] kworker/u24:3(21616): WRITE block 11037768 on xvda3 (8 sectors)
[ 3140.724725] bash(13515): READ block 5434824 on xvda3 (32 sectors)
[ 3140.725483] date(13515): READ block 5434896 on xvda3 (160 sectors)
[ 3140.728946] sed(13519): READ block 5143680 on xvda3 (32 sectors)
[ 3140.736022] sleep(13522): READ block 5379184 on xvda3 (24 sectors)
[ 3140.804803] qubes-gui(522): READ block 5179952 on xvda3 (16 sectors)
[ 3140.806519] Xorg(599): READ block 7420192 on xvda3 (176 sectors)
[ 3140.810348] InputThread(613): READ block 7418560 on xvda3 (112 sectors)
[ 3140.815866] at-spi2-registr(812): READ block 5654512 on xvda3 (8 sectors)
[ 3140.816860] xdg-desktop-por(888): READ block 5795168 on xvda3 (8 sectors)
[ 3140.818716] gnome-terminal-(865): READ block 5804672 on xvda3 (16 sectors)
[ 3141.064524] sed(13531): READ block 3446048 on xvda3 (16 sectors)
[ 3141.130808] systemd(571): READ block 4744136 on xvda3 (184 sectors)
Код ядра, отвечающий за отображение таких сообщений, можно увидеть здесь:
https://elixir.bootlin.com/linux/v4.18.5/source/block/blk-core.c#L2542
Ни один из этих блоков не дает никаких номеров инодов, используя это:
$ echo -e 'open /dev/xvda3\n icheck 11037768' |sudo debugfs -f -
debugfs 1.44.2 (14-May-2018)
debugfs: open /dev/xvda3
debugfs: icheck 11037768
Block Inode number
11037768 <block not found>
Вместо <block not found>
выше я должен получить номер инода, который я могу затем использовать с предыдущим эхом, чтобы увидеть имя файла.
То, что я пробовал: на всякий случай, если номер блока кратен размеру сектора (512 байт), и я знаю, что размер блока ext4 равен 4096 байт (sudo blockdev --getbsz /dev/xvda
), я также пытался (используя результат умножения для): 11037768 * 2, 11037768 * 4 и 11037768 * 8 с одинаковым результатом: <block not found>
Что мне здесь не хватает? Эти блоки указывают на записи каталога или что-то, что не является именем файла? Тем не менее, не должен ли debugfs по-прежнему выдавать номер инода?
Есть ли лучший способ получить имя файла?
РЕДАКТИРОВАТЬ: Номер блока, который icheck
(внутри debugfs
) ожидает, это числа, подобные тем, что stat
сообщает debugfs в EXTENTS
, например, любое число в диапазон 2172716-2172721
виден ниже как
$ sudo debugfs -R "stat /usr/lib/python2.7/site-packages/salt/modules/zonecfg.py" /dev/xvda3
debugfs 1.44.2 (14-May-2018)
Inode: 550529 Type: regular Mode: 0644 Flags: 0x80000
Generation: 1781055959 Version: 0x00000000:00000001
User: 0 Group: 0 Project: 0 Size: 22179
File ACL: 0
Links: 1 Blockcount: 48
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x5b6ec29d:1b2e0200 -- Sat Aug 11 13:03:57 2018
atime: 0x5b33b5a9:00000000 -- Wed Jun 27 18:04:57 2018
mtime: 0x5b33b5a9:00000000 -- Wed Jun 27 18:04:57 2018
crtime: 0x5b6ec29d:1af0f900 -- Sat Aug 11 13:03:57 2018
Size of extra inode fields: 32
EXTENTS:
(0-5):2172716-2172721
Другой способ:
$ filefrag -s -v /usr/lib/python2.7/site-packages/salt/modules/zonecfg.py
Filesystem type is: ef53
File size of /usr/lib/python2.7/site-packages/salt/modules/zonecfg.py is 22179 (6 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 5: 2172716.. 2172721: 6: last,eof
/usr/lib/python2.7/site-packages/salt/modules/zonecfg.py: 1 extent found
Теперь остается вопрос: как соотносятся эти номера блоков устройств (номера блоков, указанные для xvda3 в dmesg), с этими физическими смещениями?
EDIT2: Я только что подтвердил, что эти номера физических смещений совпадают с номерами блочных устройств (очевидно, они не совпадают с теми, о которых сообщалось в dmesg); ниже показан последний блок указанного выше файла, и я могу подтвердить, что он такой же, как и при просмотре файла с помощью vim
:
$ sudo dd bs=4096 skip=2172721 count=1 if=/dev/xvda3 | hexdump -C
Я проверил это под ядром 4.18.5 внутри приложения Qubes OS R4.0 Fedora 28. (При необходимости я могу перекомпилировать собственное ядро с пользовательскими .config
/ patches - предложения приветствуются)