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

1

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

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

O problema é que du informa 100% dos dados presentes na unidade de destino, embora muitos dados ainda estejam no cache do sistema, o LED da unidade esteja piscando e as unidades não estejam prontas para serem removidas.

Eu executo rsync , sync e umount em sequência para garantir que os dados estejam realmente lá antes de permitir que o usuário remova a unidade de destino. No entanto, não posso monitorar o progresso de sync . Assim, o usuário verá 100% muito antes de as unidades serem realmente sincronizadas.

Adoraria poder monitorizar o progresso da cópia "real", pois é o que realmente importa - não adianta ver rsync copiar completamente o ficheiro de 1 GB em 25 segundos, enquanto vou ter de esperar outro 5 minutos enquanto sync descarrega isso para dirigir (estou exagerando, mas você tem a idéia).

É assim que monitro rsync progress 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 é uma flutuação 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 somente os dados que já estão sincronizados para a unidade e não apenas aguardar no cache do sistema?

Editar:

Descobri que dd pode executar gravações omitindo o cache do sistema. Fiz um teste e, de fato, copiar um arquivo dessa maneira faz com que du reportem valores reais, e minhas indicações de progresso seriam finalmente precisas:

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

Isso usa o cache de leitura, mas desabilitou o cache de gravação, facilitando o acompanhamento do rastreamento, sem executar leituras excessivas. O problema é que, para usar dd em vez de rsync , preciso recriar manualmente a estrutura de diretórios. Não preciso cuidar dos atributos de arquivo ou datas de modificação.

Eu acho que eu poderia usar uma combinação de find , mkdir e dd para primeiro recriar a árvore de diretórios e depois copiar os arquivos um por um. Eu me pergunto - se há alguma desvantagem para esta abordagem?

    
por unfa 26.04.2017 / 11:01

1 resposta

0

Parece que a melhor maneira de lidar com isso é usar saída de arquivo direto . Desta forma, as leituras du serão muito mais precisas.

Infelizmente, apenas dd permite isso, por isso precisamos solucionar dois problemas:

  1. dd não sabe o que fazer com diretórios
  2. dd só pode copiar um arquivo de cada vez

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

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

Agora vamos cd para o diretório de origem, então find informará os diretórios relativos que podemos manipular facilmente:

cd "$SOURCE"

Duplique a árvore de diretórios de $SOURCE para $TARGET

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

Arquivos duplicados de $SOURCE para $TARGET omitindo o cache de gravação (mas utilizando o cache de leitura!)

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

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

    
por 26.04.2017 / 16:11