Как получить данные об использовании физического (синхронизированного) диска, игнорируя системный кэш?

Как получить данные об использовании физического (синхронизированного) диска, игнорируя системный кэш?

Я использую его duдля постоянного мониторинга объема данных, записываемых на USB-накопители, которые я копирую.

Я сравниваю использование диска на исходном и целевом дисках и отображаю пользователю ход копирования.

Проблема в том, что duсообщается о наличии 100% данных на целевом диске, хотя я вижу, что в системном кэше все еще находится много данных, светодиод диска мигает, а диски не готовы к извлечению.

Я запускаю rsync, syncи umountв последовательности, чтобы убедиться, что данные действительно там, прежде чем позволить пользователю удалить целевой диск. syncОднако я не могу отслеживать ход выполнения. Поэтому пользователь увидит 100% задолго до того, как диски действительно будут синхронизированы.

Мне бы хотелось иметь возможность отслеживать «реальный» ход копирования, поскольку это действительно важно — нет смысла наблюдать за rsyncполным копированием файла размером 1 ГБ за 25 секунд, в то время как мне придется ждать еще 5 минут, пока syncон запишется на диск (я преувеличиваю, но вы поняли).

Вот как я отслеживаю rsyncпрогресс в цикле для каждого диска:

PROGRESS="$(echo "$(du -s "/MEDIA/TARGET" 2>/dev/null  | cut -f 1) / $(du -s "/MEDIA/SOURCE" 2>/dev/null | cut -f 1) " | bc -l)"

$PROGRESSпредставляет собой число с плавающей точкой от 0 до 1, указывающее соотношение между использованием исходного диска и использованием целевого диска.

Как изменить это так, чтобы учитывались только данные, которые уже синхронизированы с диском, а не просто ожидающие в системном кэше?

Редактировать:

Я обнаружил, что ddможет выполнять запись, минуя системный кэш. Я провел тест, и действительно, копирование файла таким образом заставляет duсообщать фактические значения, и мои индикаторы прогресса наконец-то будут точными:

dd if=/media/SOURCE/file of=/media/TARGET/file bs=4M oflag=direct

Это использует кэш чтения, но отключает кэш записи, что упрощает отслеживание процесса без выполнения избыточных чтений. Проблема в том, что для использования ddвместо rsyncмне нужно вручную пересоздать структуру каталогов. Мне не нужно заботиться об атрибутах файлов или датах изменения.

Думаю, я мог бы использовать комбинацию find, mkdirи ddсначала пересоздать дерево каталогов, а затем скопировать файлы по одному. Интересно, есть ли какие-нибудь недостатки у этого подхода?

решение1

Похоже, лучший способ справиться с этим — использоватьпрямой вывод файла. Таким образом, duпоказания будут гораздо точнее.

К сожалению, это возможно только ddв том случае, поэтому нам нужно обойти две проблемы:

  1. ddне знает, что делать с каталогами
  2. ddможно копировать только один файл за раз

Сначала давайте определим входные и выходные каталоги:

SOURCE="/media/source-dir"
TARGET="/media/target-dir"

Теперь перейдем cdв исходный каталог, чтобы findсообщить относительные каталоги, которыми мы можем легко управлять:

cd "$SOURCE"

Дублируйте дерево каталогов из $SOURCEв$TARGET

find . -type d -exec mkdir -p "$TARGET{}" \;

Дублировать файлы из $SOURCEв $TARGETбез кэширования записи (но с использованием кэширования чтения!)

find . -type f -exec dd if={} of="$TARGET{}" bs=8M oflag=direct \;

Это не сохранит время изменения файла, владельца и другие атрибуты, но меня это устраивает.

Связанный контент