I figure there is a cache somewhere that is holding up the final 5MB but I thought fsync should make sure that doesn't happen
conv=fsync
significa gravar todos os caches chamando fsync
- após dd
ter escrito todos os dados. Pendurar no final é exatamente o que ele fará.
Quando o arquivo de saída é mais lento que o arquivo de entrada, os dados gravados por dd
podem se acumular em caches. O cache do kernel pode, às vezes, preencher uma fração significativa da RAM do sistema. Isso faz com que informações de progresso sejam muito enganosas. Seu "5MB final" foi apenas um artefato de como dd
mostra o progresso.
Se o seu sistema estava realmente armazenando em cache cerca de 8 GB (ou seja, metade dos 16 GB de dados gravados), então acho que você deve ter cerca de 32 GB de RAM ou ter mexido em certas opções do kernel. Veja o link do lwn.net abaixo. Concordo que não obter informações sobre o progresso por 15 minutos é muito frustrante.
Existem alternativas de comandos dd
que você pode usar. Se você quiser que dd
mostre um progresso mais preciso, talvez seja necessário aceitar mais complexidade. Espero que o seguinte funcione sem degradar seu desempenho, embora talvez a realidade tenha outras idéias além das minhas.
gunzip -c serial2udp.image.gz |
dd iflag=fullblock bs=4M |
sudo dd iflag=fullblock oflag=direct conv=fsync status=progress bs=4M of=/dev/mmcblk0
-
oflag=direct iflag=fullblock
evita o empilhamento do cache do kernel, porque ele o ignora completamente. -
iflag=fullblock
é necessário em tal comando AFAIK (por exemplo, porque você está lendo de um pipe e escrevendo usando IO direto). O efeito de perderfullblock
é outra complexidade infeliz dedd
. Algumas postagens neste site usam isso para argumentar que você deve sempre preferir usar um comando diferente. É difícil encontrar outra maneira de direcionar ou sincronizar o IO. -
conv=fsync
ainda deve ser usado para gravar o cache dispositivo . - Eu adicionei um
dd
extra apósgunzip
para armazenar em buffer a saída descompactada em paralelo com a gravação em disco. Esse é um dos problemas que torna o desempenho comoflag=direct
ouoflag=sync
um pouco complexo. O IO normal (não-direto, não-sync) não deve precisar disso, já que ele é armazenado em buffer pelo cache do kernel. Você também pode não precisar do buffer extra se estiver gravando em um disco rígido com 4M de cache de write-back, mas não presumo que um cartão SD tenha tanto.
Você pode usar alternativamente oflag=direct,sync
(e não precisa de conv=fsync
). Isso pode ser útil para obter boas informações sobre o progresso se você tiver um dispositivo de saída estranho com centenas de megabytes de cache . Mas normalmente eu penso em oflag=sync
como uma barreira potencial para o desempenho.
Existe um artigo link de 2013 que menciona atrasos de um minuto como o seu. Muitas pessoas vêem essa capacidade de armazenar em cache minutos de dados de write-back como indesejáveis. O problema era que o limite do tamanho do cache era aplicado indiscriminadamente, tanto para dispositivos rápidos quanto lentos. Note que não é trivial para o kernel medir a velocidade do dispositivo, porque varia de acordo com os locais dos dados. Por exemplo. se as gravações em cache estiverem espalhadas em locais aleatórios, um disco rígido levará mais tempo para mover repetidamente a cabeça de gravação.
why do the updates hang
O fsync()
é uma chamada de sistema única que se aplica a todo o intervalo do dispositivo file . Ele não retorna nenhuma atualização de status antes de ser feito.