arquivo montado de ligação única fica fora de sincronia no linux

4

Estou ligando a montagem de um único arquivo em cima de outro e depois de fazer alterações com um editor, não vejo as modificações em ambos os arquivos. No entanto, se eu fizer as alterações com o shell usando o redirecionamento, > & gt ;, por exemplo, vejo as alterações em ambos os arquivos. Abaixo está um exemplo para demonstrar:

Primeiro caso:

-bash-3.00# echo foo >| foo
-bash-3.00# echo bar >| bar
-bash-3.00# diff foo bar
1c1
< foo
---
> bar
-bash-3.00# mount --bind foo bar
-bash-3.00# echo modified >> foo
-bash-3.00# diff foo bar
-bash-3.00# umount bar

Tudo no caso acima é como eu esperava; os dois arquivos não mostram diferenças após acrescentar "modificado" ao arquivo "foo".

No entanto, se eu executar o mesmo teste, mas usar o vi para editar o foo, obtenho um resultado diferente.

Segundo caso:

-bash-3.00# echo foo >| foo
-bash-3.00# echo bar >| bar
-bash-3.00# diff foo bar
1c1
< foo
---
> bar
-bash-3.00# mount --bind foo bar
-bash-3.00# diff foo bar
-bash-3.00# vi foo
# append "modified with vi" and :wq vi
"foo" 2L, 21C written
-bash-3.00# cat foo
foo
modified with vi
-bash-3.00# cat bar
foo 
-bash-3.00# diff foo bar
2d1
< modified with vi
-bash-3.00# 

Aqui, os dois arquivos são diferentes, embora um esteja ligado ao outro. Alguém aqui sabe o que está acontecendo neste caso?

Obrigado!

    
por capnroscoe 31.07.2012 / 12:21

1 resposta

6

O que está acontecendo é que o vi está criando um novo arquivo (inode) e, efetivamente, desfazendo a ligação, mesmo que a montagem ainda esteja em vigor. Anexar usa o arquivo existente (inode).

Dê uma olhada nos números de inode dos arquivos usando ls -li à medida que eu passo em seus testes.

$ echo foo > foo
$ echo bar > bar
$ ls -li foo bar   # 2 inodes so 2 different files
409617 -rw-r--r-- 1 derek derek 4 Jul 31 12:56 bar
409619 -rw-r--r-- 1 derek derek 4 Jul 31 12:56 foo
$ sudo mount --bind foo bar
$ ls -li foo bar   # both inodes are the same so both reference the same file (foo)
409619 -rw-r--r-- 1 derek derek 4 Jul 31 12:56 bar
409619 -rw-r--r-- 1 derek derek 4 Jul 31 12:56 foo
$ echo mod >> foo
$ ls -li foo bar   # appending doesn't change the inode
409619 -rw-r--r-- 1 derek derek 8 Jul 31 12:57 bar
409619 -rw-r--r-- 1 derek derek 8 Jul 31 12:57 foo
$ vi foo
$ ls -li foo bar   # vi has created a new file called foo (new inode)
                   # bar still points to the old foo
409619 -rw-r--r-- 0 derek derek  8 Jul 31 12:57 bar
409620 -rw-r--r-- 1 derek derek 14 Jul 31 12:57 foo
$ sudo umount bar
$ ls -li foo bar   # umount uncovers the original bar. original foo has no references
409617 -rw-r--r-- 1 derek derek  4 Jul 31 12:56 bar
409620 -rw-r--r-- 1 derek derek 14 Jul 31 12:57 foo

Você precisa pensar em termos dos inodes subjacentes em vez de nomes de arquivos. O que você está tentando fazer que não pode ser feito com links simbólicos?

Eu tentei uma variação e acho que você pode fazer o que quiser. Dê uma olhada no seguinte ...

$ ls -li a/foo /mnt/c/foo
3842157 -rw-r--r-- 1 derek derek 17 Jul 31 19:45 a/foo
 840457 -r--r--r-- 1 root  root   6 Jul 31 19:41 /mnt/c/foo
$ sudo mount --bind a/foo /mnt/c/foo
$ ls -li a/foo /mnt/c/foo
3842157 -rw-r--r-- 1 derek derek 17 Jul 31 19:45 a/foo
3842157 -rw-r--r-- 1 derek derek 17 Jul 31 19:45 /mnt/c/foo
$ vi /mnt/c/foo
$ ls -li a/foo /mnt/c/foo
3842157 -rw-r--r-- 1 derek derek 22 Jul 31 20:02 a/foo
3842157 -rw-r--r-- 1 derek derek 22 Jul 31 20:02 /mnt/c/foo
$ sudo umount /mnt/c/foo
$ ls -li a/foo /mnt/c/foo
3842157 -rw-r--r-- 1 derek derek 22 Jul 31 20:02 a/foo
 840457 -r--r--r-- 1 root  root   6 Jul 31 19:41 /mnt/c/foo

Enquanto a/foo foi montado no arquivo somente leitura /mnt/c/foo , eu poderia editar /mnt/c/foo e ele alterou o conteúdo de a/foo sem alterar o inode.

    
por 31.07.2012 / 14:08