Quais são as consequências para um sistema de arquivos ext4 quando eu encerro um cp
comando de cópia digitando Ctrl+ Cenquanto ele está em execução?
O sistema de arquivos fica corrompido? O espaço da partição ocupado pelo arquivo copiado incompleto ainda pode ser usado após excluí-lo?
E, mais importante, encerrar um cp
processo é uma coisa segura a se fazer?
É seguro fazer isso, mas naturalmente você pode não ter terminado a cópia.
Quando o
cp
comando é executado, ele faz syscalls que instruem o kernel a fazer cópias do arquivo. Uma syscall, ou chamada de sistema, é uma função que um aplicativo pode usar para solicitar um serviço do kernel, como ler ou gravar dados no disco. O processo de espaço do usuário simplesmente espera que a syscall termine. Se você rastrear as chamadas decp ~/hello.txt /mnt
, ficaria assim:Isso se repete para cada arquivo que deve ser copiado. Nenhuma corrupção ocorrerá devido à maneira como essas syscalls funcionam. Quando syscalls como essas são inseridas, o sinal fatal só terá efeito após a syscall terminar , não enquanto estiver em execução (na verdade, os sinais só chegam durante uma troca de contexto de kernelspace para userspace). Observe que alguns sinais, como
read()
, podem ser encerrados antecipadamente.Por causa disso, matar o processo forçosamente só fará com que ele seja encerrado após o retorno da syscall em execução no momento. Isso significa que o kernel, onde o driver do sistema de arquivos reside, é livre para concluir as operações que precisa concluir para colocar o sistema de arquivos em um estado são. Qualquer E/S desse tipo nunca será encerrada no meio da operação, portanto, não há risco de corrupção do sistema de arquivos.
Como
cp
é um comando de espaço do usuário, isso não afeta a integridade do sistema de arquivos.É claro que você precisa estar preparado para que pelo menos um arquivo não tenha sido copiado completamente se você matar um
cp
programa em execução.a resposta da floresta , embora bonita (e em muitos casos correta) não é o que você verá nos sistemas modernos⁰. Eles estão certos – sob nenhuma circunstância isso corromperia seu sistema de arquivos. Mas sob nenhuma circunstância prática você receberia metade de uma cópia hoje em dia!
Suponha que eu faça isso (apenas para gerar um arquivo grande
yesfile
e copiá-lo para um arquivocopy
(não precisa estar no mesmo sistema de arquivos), enquanto registra todas as chamadas do sistema porcp
):Eu recebo uma imagem diferente: o processo userland
cp
não lê o conteúdo do arquivo e não o grava em outro arquivo ; isso seria ruim, em termos de desempenho: exigiria pelo menos duas trocas de contexto! O programa userland chamaread
, switch, obtém dados, chamawrite
, switch; enxágue e repita se o arquivo for maior que um único buffer de leitura. Agora, esse modelo de repetição exato, lendo apenas um buffer de tamanho limitado, é o que pode levar a arquivos parcialmente copiados na interrupção.Em vez disso, ele usa a
copy_file_range
chamada do sistema (veja o rastreamento abaixo¹);man copy_file_range
diga-nos:Portanto, há uma chamada de sistema de cópia-este-arquivo atômica, que geralmente é usada, portanto, interromper
cp
não pode interromper a cópia.As coisas ficam ainda melhores se o seu sistema de arquivos de origem e destino forem os mesmos, e Btrfs, CIFS, NFS 4.2, OCFS2, overlayfs ou XFS source (no momento da escrita, apenas para esses Linux tem o recurso reflink): se
for bem-sucedido, o sistema não precisa copiar o conteúdo do arquivo – em vez disso, apenas a lista de blocos pertencentes ao arquivo de origem é copiada para o arquivo de destino; cada bloco tem um contador de referência que é aumentado, portanto, no momento em que qualquer processo grava em qualquer um desses arquivos, o sistema de arquivos faz uma cópia na gravação de forma transparente. Então, essas coisas são ainda mais atômicas!
⁰ Pelo menos, se meus GNU coreutils 8.32 com os
copy_file_range
patches de backport do fedora 34 /Linux 5.13.5 forem considerados modernos.¹ saída de rastreamento relevante