Como obter o uso do disco físico (sincronizado), ignorando o cache do sistema?

Como obter o uso do disco físico (sincronizado), ignorando o cache do sistema?

Estou usando dupara monitorar continuamente a quantidade de dados gravados em unidades USB que estou duplicando.

Comparo o uso do disco das unidades de origem e de destino e exibo o progresso da cópia para o usuário.

O problema é que durelata 100% dos dados presentes na unidade de destino, embora eu veja que muitos dados ainda estão no cache do sistema, o LED da unidade está piscando e as unidades não estão prontas para serem removidas.

Eu corro rsynce syncem umountsequência para garantir que os dados realmente estejam lá antes de permitir que o usuário remova a unidade de destino. No entanto , não consigo monitorar o syncprogresso. Assim, o usuário verá 100% muito antes de as unidades serem realmente sincronizadas.

Eu adoraria poder monitorar o progresso "real" da cópia, pois é o que realmente importa - não adianta ver rsynca cópia completa de um arquivo de 1 GB em 25 segundos, enquanto terei que esperar mais 5 minutos enquanto synclibera isso para dirigir (estou exagerando, mas você entendeu).

É assim que monitoro rsynco progresso em um loop para cada unidade:

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é um valor flutuante entre 0 e 1, indicando a proporção entre o uso da unidade de origem e o uso da unidade de destino.

Como posso modificar isso para considerar apenas os dados que já estão sincronizados com a unidade, e não apenas aguardando no cache do sistema?

Editar:

Descobri que ddposso realizar gravações omitindo o cache do sistema. Fiz um teste e, de fato, copiar um arquivo dessa maneira reporta duvalores reais e minhas indicações de progresso finalmente seriam precisas:

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

Isso usa o cache de leitura, mas desativa o cache de gravação, facilitando o rastreamento do processo, sem realizar leituras excessivas. O problema é que, para usar ddem vez de rsyncpreciso recriar manualmente a estrutura de diretórios. Não preciso cuidar dos atributos do arquivo ou das datas de modificação.

Acho que poderia usar uma combinação de finde mkdirprimeiro ddrecriar a árvore de diretórios e depois copiar os arquivos um por um. Eu me pergunto - se há alguma desvantagem nessa abordagem?

Responder1

Parece que a melhor maneira de lidar com isso é usarsaída direta de arquivo. Desta forma duas leituras serão muito mais precisas.

Infelizmente só ddpermite isso, então precisamos solucionar dois problemas:

  1. ddnão sabe o que fazer com diretórios
  2. ddsó pode copiar um arquivo por vez

Primeiro vamos definir os diretórios de entrada e saída:

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

Agora vamos cdpara o diretório de origem para findrelatar os diretórios relativos que podemos manipular facilmente:

cd "$SOURCE"

Duplique a árvore de diretórios de $SOURCEpara$TARGET

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

Arquivos duplicados $SOURCEpara $TARGETomitir cache de gravação (mas utilizando cache de leitura!)

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

Isso não preservará os tempos de modificação dos arquivos, propriedade e outros atributos - mas para mim está tudo bem.

informação relacionada