single bind mounted file gets out of sync in linux

8,784

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.

Share:
8,784

Related videos on Youtube

capnroscoe
Author by

capnroscoe

Updated on September 18, 2022

Comments

  • capnroscoe
    capnroscoe almost 2 years

    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!

    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' almost 12 years
      Bind-mounting a file is technically possible, but it is very strange. Normally you'd mount a directory.
  • capnroscoe
    capnroscoe almost 12 years
    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.
  • StarNamer
    StarNamer almost 12 years
    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
    StarNamer almost 12 years
    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.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 12 years