8

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!

1
  • 1
    Bind-mounting a file is technically possible, but it is very strange. Normally you'd mount a directory. Jul 31, 2012 at 22:44

1 Answer 1

10

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 existing 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.

4
  • 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, 2012 at 12:29
  • 2
    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, 2012 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, 2012 at 19:09
  • 2
    @capnroscoe See why inode value changes when we edit in "vi" editor? for background. Jul 31, 2012 at 22:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .