2016-12-07 6 views
2

Мне нужно понять, какие файлы потребляют iops моего жесткого диска. Просто использование «strace» не решит мою проблему. Я хочу знать, какие файлы действительно записываются на диск, а не в кеш страницы. Я попытался использовать «systemtap», но я не могу понять, как узнать, какие файлы (имена файлов или иноды) потребляют мои iops. Есть ли инструменты, которые помогут решить мою проблему?Как контролировать, какие файлы потребляют iops?

ответ

0

Возможно, iotop дает вам подсказку о том, какой процесс выполняет ввод-вывод, в результате у вас есть представление о связанных файлах.

iotop --only 

--only опция используется для просмотра только процессов или потоков на самом деле делают ввода/вывода, вместо того чтобы показывать все процессы или потоки

2

Да, вы определенно можете использовать SystemTap для отслеживания этого. Когда верхний уровень (как правило, подсистема VFS) хочет выполнить операцию ввода-вывода, он будет вызывать функции submit_bio и generic_make_request. Обратите внимание, что это не обязательно означает одну операцию физического ввода-вывода. Например, записи из смежных секторов могут быть объединены планировщиком ввода-вывода.

Фокус в том, как определить путь к файлу в generic_make_request. Это довольно просто для чтения, так как эта функция будет вызываться в том же контексте, что и вызов read(). Пишу, как правило, асинхронные, так write() будет просто обновить запись в кэше страницы и пометить его как грязный, в то время как submit_bio вызывается одним из потоков ядра обратной записи, которые не имеют информации о первородном вызывающем процессе:

Пишет можно вывести, посмотрев на page ссылка в bio структура - есть mapping из struct address_space. struct file что соответствует открытому файлу также содержит f_mapping, который указывает на тот же экземпляр address_space и он также указывает на dentry, содержащий имя файла (это может быть сделано с помощью task_dentry_path)

Таким образом, мы должны были бы два датчика: один для захват пытается прочитать/записать файл и сохранить путь и address_space в ассоциативный массив, а второй - для записи generic_make_request вызовов (это выполняется с помощью зонда ioblock.request).

Ниже приведен пример сценария, который считает IOPS:

// maps struct address_space to path name 
global paths; 

// IOPS per file 
global iops; 

// Capture attempts to read and write by VFS 
probe kernel.function("vfs_read"), 
     kernel.function("vfs_write") { 
    mapping = $file->f_mapping; 

    // Assemble full path name for running task (task_current()) 
    // from open file "$file" of type "struct file" 
    path = task_dentry_path(task_current(), $file->f_path->dentry, 
          $file->f_path->mnt); 

    paths[mapping] = path; 
} 

// Attach to generic_make_request() 
probe ioblock.request { 
    for (i = 0; i < $bio->bi_vcnt ; i++) { 
     // Each BIO request may have more than one page 
     // to write 
     page = $bio->bi_io_vec[i]->bv_page; 
     mapping = @cast(page, "struct page")->mapping; 

     iops[paths[mapping], rw] <<< 1; 
    } 
} 

// Once per second drain iops statistics 
probe timer.s(1) { 
    println(ctime()); 
    foreach([path+, rw] in iops) { 
     printf("%3d %s %s\n", @count(iops[path, rw]), 
           bio_rw_str(rw), path); 
    } 
    delete iops 
} 

Этот пример скрипт работает для XFS, но должен быть обновлен для поддержки AIO и менеджеры томов (в том числе Btrfs). Кроме того, я не уверен, как он будет обрабатывать метаданные чтения и записи, но это хорошее начало;)

Если вы хотите узнать больше о SystemTap вы можете проверить мою книгу: http://myaut.github.io/dtrace-stap-book/kernel/async.html