Por que o dd às vezes não espera até que os dados sejam gravados?

20

Às vezes, quando escrevo imagens em uma unidade flash, isso acontece:

$ sudo dd if=install57.fs of=/dev/sdc
573440+0 records in
573440+0 records out
293601280 bytes (294 MB) copied, 0.549231 s, 535 MB/s

Basicamente, o Linux armazena tudo em cache, não grava nada e dd exits. Depois de digitar sync , ele começa a gravar os dados (o LED da unidade flash começa a piscar).

Por que isso acontece?

    
por jgillich 21.08.2015 / 15:59

3 respostas

21

Use isso:

sudo dd if=install57.fs of=/dev/sdc conv=fsync

Isso chama o fsync() após cada write() chamada do sistema. Isso força dd a não armazenar nada em cache. Veja esta parte da manpage do fsync ( man 2 fsync ):

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache 
pages for) the file referred to by the file descriptor fd to the disk device (or other 
permanent storage device) where that file resides. The call blocks until the device reports 
that the transfer has completed. It also flushes metadata information associated with the 
file (see stat(2)).

Este é o comportamento padrão dos kernels. Os kernels Linux gerenciam os caches de gravação e leitura assim: Quando o write() syscall é emitido, os dados são gravados rapidamente no cache e um status de gravação concluída é enviado para o processo. Quando o buffer é necessário ou quando há tempo livre no barramento, os dados são gravados do cache para o disco rígido.

    
por 21.08.2015 / 16:14
10

Isso acontece porque o Linux e a maioria dos outros sistemas operacionais armazenam em cache tanto leituras quanto gravações. Na maioria dos casos, isso torna seu sistema operacional mais responsivo.

Se você quiser garantir que os dados armazenados em cache tenham sido gravados, use sync , como você sabe. O Linux expõe um número significativo de configurações que você pode ajustar também. Este artigo fornece uma boa visão geral de algumas configurações. Você poderia definir o vm.dirty_background_bytes como 0, por exemplo, para garantir que o kernel inicie os encadernadores de flusher imediatamente.

    
por 21.08.2015 / 16:14
7

sync(8) - Linux man page :

The kernel keeps data in memory to avoid doing (relatively slow) disk reads and writes. This improves performance, but if the computer crashes, data may be lost or the file system corrupted as a result. sync ensures that everything in memory is written to disk.

Observação: unmount (ou ejetar) chama automaticamente sync , o que "oculta" isso no uso normal do sistema de arquivos.

    
por 21.08.2015 / 16:14