nautilus não chama a chamada do sistema de gravação ao colar o arquivo

0

Estou tentando ligar algumas chamadas do sistema usando o módulo do kernel do Linux na versão Ubuntu 14.04 Desktop.

No entanto, quando eu anexei write(unsigned int fd, const char __user *buf, size_t count) e transformou fd em filename, descobri que quando copio /home/user/1.txt e colo em /home/user/folder/ no nautilus, nenhuma gravação foi chamada nessa pasta. No entanto, se eu usar cp /home/user/1.txt /home/user/folder , posso notar que write é chamado e o nome do arquivo é exatamente /home/user/folder/1.txt .

Eu tentei hook pwrite também, mas ainda não detectei chamá-lo ao colar o arquivo usando o nautilus.

Então, como o nautilus copia o arquivo e cola para uma pasta específica quando nenhuma chamada de sistema write é chamada no destino?

    
por user6456568 23.11.2018 / 09:50

1 resposta

1

Parece que o Nautilus usa uma abordagem diferente para fins de otimização.

Digamos que eu tenha um arquivo de teste /ntest/testfile com 45 bytes dentro:

Lorem ipsum dolor sit amet
Leroooy Jeeenkins

Eu quero movê-lo para o diretório /ntest2 . Para rastrear o que exatamente o Nautilus faz, posso ativá-lo assim (na verdade, fiz vários lançamentos com limitações menos rigorosas, mas isso é um bom começo):

strace -f -P '/ntest/testfile' -P '/ntest2/testfile' -qq nautilus

Essencialmente, o trecho a seguir explica o que acontece (note que pipe2() call não é capturado pelo comando acima - eu o inseri baseado em outras sessões de rastreamento):

openat(AT_FDCWD, "/ntest/testfile", O_RDONLY) = 35
openat(AT_FDCWD, "/ntest2/testfile", O_WRONLY|O_CREAT|O_EXCL, 0644) = 36
pipe2([37, 38], O_CLOEXEC)  = 0
stat("/ntest2/testfile", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
splice(35, [0], 38, NULL, 1048576, SPLICE_F_MORE) = 45
splice(37, NULL, 36, [0], 45, SPLICE_F_MORE) = 45
close(35)                   = 0
close(36)                   = 0

O Nautilus usa splice(2) , que permite transferir alguns dados entre fd s sem copiá-los entre o kernel e os espaços do usuário. Como man 2 splice requer que uma das extremidades seja um canal, o Nautilus cria um canal com descritor de arquivo de entrada 38 e descritor de arquivo de saída 37 . Após abrir os arquivos de origem e de destino e criar o canal, o Nautilus usa splice() para ler dados do arquivo de origem para a entrada do pipe; então o segundo splice() é usado para gravar dados desse pipe no arquivo de saída. Essa abordagem não envolve transições de dados de kernel para usuário e de usuário para kernel, como seria com a abordagem comum de read() - write() .

Note que este comportamento não é específico do Nautilus, mas sim da biblioteca que ele usa (glib). Parece que esta é a chamada splice () que observamos, como o Nautilus usa g_file_copy () da glib que, por sua vez, chama file_copy_fallback () - > splice_stream_with_progress () - > do_splice () .

    
por 24.11.2018 / 14:31