
Я работаю busybox 1.27
только на системе Linux output=progress
, поэтому у меня нет доступной собственной реализации busybox, pv
которая, pipe_progress
как и pv
он сам, отсутствует.
У меня два вопроса. Первый основан наhttps://www.linux.com/training-tutorials/show-progress-when-using-dd/. Он говорит, что отправка USR1
сигнала на dd
него "приостанавливает" процесс и dd
после печати текущего состояния продолжит работу, которую он делал. Я пытаюсь провести некоторые тесты производительности, dd
поэтому я хотел бы иметь минимальное влияние на dd
работу. Я хочу получать вывод текущей операции каждую секунду, потому что проходящие данные dd
колеблются, и мне важно распознавать, когда скорость передачи падает.
Первый вопрос: Правда ли, что «dd» «останавливается» каждый раз, когда получает сигнал USR1
?
Если dd
паузы будут каждую секунду, то я добавлю часы к операции, когда передаются десятки гигабайт.
Второй вопрос: Предполагая,даВ качестве ответа на первый вопрос я хотел бы узнать, возможно ли распечатать dd
его текущий статус, не отправляя никаких сигналов процессу, может быть, с помощью какого-то перенаправления STDOUT
(вроде 2>&1)?
Я имею в виду следующее:
# bs with 1Mib so I can have more control on the test.
dd if=/dev/zero of=/dev/null bs=1048576 count=1024
# Printing current operation status.
sudo kill -USR1 $dd_pid
решение1
dd if=/dev/zero of=/dev/null bs=1048576 count=1024
Обратите внимание, чтоdd
может искажать данные, по меньшей мерепри использовании bs
параметра. Иего преимущество в производительностив лучшем случае мал, если вы вручную подберете оптимальный размер блока для вашей конкретной конфигурации системы: cat
или cp
может сделать лучше, и в лучшем случае лишь немного медленнее. Так что не используйте, dd
если вам это не нужно.
Обратите внимание, что начиная с версии 1.23 BusyBox используетsendfile
системный вызов для копирования данных вместо использования read
и write
. Только простые копии, такие как cat
и cp
используют sendfile
, однако: dd
вынужден использовать read
/ , write
поскольку он хочет точного контроля над размерами. Так что с BusyBox ≥1.23 cat
и , cp
скорее всего, будут быстрее, чем dd
.
Правда ли, что «dd» «останавливается» каждый раз, когда получает сигнал USR1?
Технически да, он должен «приостановиться» для обработки сигнала. Однако пауза составляет всего несколько инструкций ЦП (самая затратная часть — это вывод прогресса). Так что это никоим образом не делает ваш бенчмарк недействительным.
Если dd будет останавливаться каждую секунду, то я добавлю часы к операции, когда передаются десятки гигабайт.
Нет, у вас неправильные порядки величин. Вы добавите, может быть, 0,1% времени на потоке с одним ЦП. Основная стоимость — это время ядра для программы бенчмаркинга, а не dd
, так что это внутренне присуще тому, что вы хотите сделать, а не тому, как вы это реализуете.
если возможно заставить dd вывести свое текущее состояние без отправки какого-либо сигнала процессу
Ну, нет. Уже есть простой, исторически сложившийся, стандартный, легкий способ сделать это. Зачем нужен другой способ, который сложнее реализовать?
В Linux есть общий способ узнать, до какой точки дошла копия. Он не зависит от того, какая программа копирует, хотя он не всегда работает со специальными файлами. Узнайте идентификатор процесса, $pid
который копирует, и какие файловые дескрипторы он использует для ввода и вывода. dd
читает из fd 0 и пишет в fd 1. BusyBox cp
обычно читает из fd 3 и пишет в fd 4. Вы можете проверить, какой файл открыт и на каком файловом дескрипторе, с помощью символических ссылок в /proc/$pid/fd
.
$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null
И вы можете проверить позицию в дескрипторе файла $n$
в /proc/$pid/fd/$n
.
$ cat /proc/$pid/fdinfo/4
pos: 74252288
flags: 0100001
mnt_id: 27
Однако обратите внимание, что позиция дескриптора файла может не обновляться для специальных файлов, таких как /dev/zero
, /dev/null
, каналы или сокеты. Она всегда обновляется для обычных файлов. Я не знаю, обновляется ли она для блочных устройств. Так что она, скорее всего, не даст вам никакой информации для копирования между /dev/zero
и /dev/null
, но она может работать в вашем реальном варианте использования.
решение2
Вы также можете запросить информацию о ходе выполнения через /proc
интерфейс.
# dd bs=1M if=/dev/mmcblk0 of=/dev/null &
# pidof dd
1358
Информацию об этом процессе можно найти в /proc/1358
:
# ls -l /proc/1358/fd
total 0
lr-x------ 1 root root 64 Nov 2 09:16 0 -> /dev/mmcblk0
l-wx------ 1 root root 64 Nov 2 09:16 1 -> /dev/null
lrwx------ 1 root root 64 Nov 2 09:16 2 -> /dev/pts/0
Файловый дескриптор 0 — это if=/dev/mmcblk0
, где же теперь прогресс?
# cat /proc/1358/fdinfo/0
pos: 2132803584
flags: 0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos: 2366636032
flags: 0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos: 2587885568
flags: 0400000
mnt_id: 17
Таким образом, для busybox dd вы также можете получить прогресс из его значения fdinfo pos.
При этом отправка сигнала USR1 в умеренном режиме должна иметь минимальное влияние на производительность. Во встроенной системе с небольшим количеством ресурсов опрос fdinfo может иметь такое же влияние.