Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am bind mounting a single file on top of another one and after making changes with an editor, I don't see the modifications in both files. However, if I make the changes with the shell using redirection, >>, e.g., I do see the changes in both files. Below is an example to demonstrate:

First case:

-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

Everything in the above case is as I expect; the two files show no differences after appending "modified" to the file "foo".

However, if I perform the same test but use vi to edit foo, I get a different result.

Second case:

-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# 

Here, the two files are different even though one is bind mounted onto the other. Anyone here know what is going on in this case?

Thanks!

share|improve this question
    
Bind-mounting a file is technically possible, but it is very strange. Normally you'd mount a directory. –  Gilles Jul 31 '12 at 22:44
add comment

1 Answer

up vote 3 down vote accepted

What is happening is that vi is creating a new file (inode) and, effectively, undoing the bind, even though the mount is still in place. Appending uses the exsiting file (inode).

Take a look at the inode numbers of the files using ls -li as I step through your test(s).

$ 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

You need to think in terms of the underlying inodes rather than file names. What are you trying to do which couldn't be done with symlinks?


I tried a variation and think you can do what you want. Take a look at the following...

$ 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

While a/foo was mounted on the read-only file /mnt/c/foo I could edit /mnt/c/foo and it changed the contents of a/foo without changing the inode.

share|improve this answer
    
Thanks StarNamer, that explains it. I do wonder why vi (vim) creates a new file (inode) when the file already exists? Originally, I was using the bind mounted files because the / filesystem was to be mounted read-only in an embedded system type environment. The bind mounted files lets the original untouched files in / live below ones that can be modified. –  capnroscoe Jul 31 '12 at 12:29
    
A lot of programs work by reading an existing file, creating a new version with a temp name, unlinking (deleting) the old file and renaming the new file with the old name. –  StarNamer Jul 31 '12 at 18:31
    
See additional edits to answer. Basically you need to edit the file you've mounted your copy on. So if you do mount --bind /writeable/file /readonly/file then you should do vi /readonly/file. If you do vi /writeable/file you break the link. –  StarNamer Jul 31 '12 at 19:09
1  
@capnroscoe See why inode value changes when we edit in "vi" editor? for background. –  Gilles Jul 31 '12 at 22:43
    
Excellent. Thanks both for the clarifications! –  capnroscoe Aug 1 '12 at 11:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.