0

I recently ran into the following problem on a Solaris 11 system I do development on:

Somehow, a few directories had their parent pointer (..) pointing to a different directory from the parent.

Let's call the parent directory p, and the directory in question d (i.e., d is in directory p.)

The situation was that d/.. was not p. Specifically, the two commands

ls -ild  p

ls -ild  p/d/..

showed different i-node numbers. In fact the second command gave the same i-node as a different subdirectory of p : p/x

And, no d was not a symbolic link. (That was the first thing I checked.)

How is this possible? I would think the kernel would prevent it from ever happening.

I do know that other people were moving directories around and renaming them, though I don't know exactly what they did. However, I don't think they would know how to do systems hacking.

AdminBee
  • 22,803
  • Does this answer your question? What is a bind mount? – Thomas Dickey Apr 18 '20 at 18:07
  • 1
    @ThomasDickey is that applicable to Solaris too? – Chris Davies Apr 18 '20 at 18:21
  • 1
    yes - that's what I found quickly, and it's the simplest explanation. – Thomas Dickey Apr 18 '20 at 18:31
  • 1
    You would need to give more information about filesystems and mountpoints.UFS e.g. supports hardlinked directories... – schily Apr 18 '20 at 21:59
  • If you do cd p/d/.. ; /bin/pwd does it take you to p or x? – Mark Plotnick Apr 18 '20 at 22:12
  • @ThomasDickey could you please give a link/reference for your quicky found bind mount support in Solaris? And also, how could I reproduce OP's case with bind mounts in Linux. I'm not able to figure it out. –  Apr 19 '20 at 10:05
  • 1
    Please show your exact commands and their output. Also mention what filesystem you're using (df -g p p/d p/d/..), and how you determined that d is not a symbolic link. Make sure ls is not an alias. –  Apr 19 '20 at 10:25
  • 1
    I looked for solaris "bind mount" and saw several promising ones such as this and this, i.e., a "loopback" mount. What I supposed happened is that OP cd'd into a directory which was "really" under another directory, but bind-mounted into the directory where he began changing directories. Whether you call it "bind" or "loopback" is just terminology (not interesting). – Thomas Dickey Apr 19 '20 at 13:36
  • 1
    @ThomasDickey I'm not able to reproduce anything like the OP's case with either bind mounts in Linux or lofs in Solaris. Could you please give an example? –  Apr 19 '20 at 14:34

2 Answers2

2

Let me give a real answer to the original question and explain how to create this kind of state:

mkfile 100m ufs
lofiadm -a /path/to/ufs
newfs /dev/rlofi/1
newfs: Neues Dateisystem /dev/rlofi/1 erstellen: (y/n)? y
/dev/rlofi/1:   204600 Sektoren in 341 Zylindern von 1 Spuren, 600 Sektoren
        99,9MB in 22 Zylindergruppen (16 c/g, 4,69MB/g, 2240 i/g)
Superblock Backups (für fsck -F ufs -o b=#) bei:
 32, 9632, 19232, 28832, 38432, 48032, 57632, 67232, 76832, 86432,
 115232, 124832, 134432, 144032, 153632, 163232, 172832, 182432, 192032, 201632

mount /dev/lofi/1 /mnt
cd /mnt
mkdir -p a/b/c d

ls -lid a/b/ a/b/c a/b/c/..
     5 drwxr-xr-x   3 root     root         512 Apr 20 17:05 a/b/
     6 drwxr-xr-x   2 root     root         512 Apr 20 17:05 a/b/c
     5 drwxr-xr-x   3 root     root         512 Apr 20 17:05 a/b/c/..

link a/b/c/ d/hlink
ls -lid a/b/ a/b/c a/b/c/.. d/ d/hlink/ d/hlink/..
     5 drwxr-xr-x   3 root     root         512 Apr 20 17:05 a/b/
     6 drwxr-xr-x   3 root     root         512 Apr 20 17:05 a/b/c
     5 drwxr-xr-x   3 root     root         512 Apr 20 17:05 a/b/c/..
     7 drwxr-xr-x   2 root     root         512 Apr 20 17:08 d/
     6 drwxr-xr-x   3 root     root         512 Apr 20 17:05 d/hlink/
     5 drwxr-xr-x   3 root     root         512 Apr 20 17:05 d/hlink/..

This is creating a test ufs filesystem in a file, which is then used as a block device via the lofi(7d) "loopback file driver" (see fbk note below) and mounted on the /mnt directory. The ufs filesystem (unlike zfs) also supports creating hard links to directories, but only by root.

As you see, the inode number for a/b/ is 5 and the inode number of a/b/c/.. is 5 as well. You also see, that the link count for directory a/b/c increased by one from the link call.

After creating the new hardlinked directory d/hlink, you see that the inode number for d/hlink/..is not 7 (the inode number of the directory above) but rather 5 (the inode number of the original directory above that directory).

BTW: the loopback filesystem first appeared in 1987 with SunOS-4.0. It's purpose is to act as a VFS indirect layer that allows to mount a filesystem tree a second time in the same machine. I am not sure whether this Linux bind mount is a reimplementation of the loopback filesystem idea.

What is obvious is that the fbk driver (file emulates block device) I invented in October 1988 has been reimplemented in the mid -1990s on linux under the improper name loopback.

schily
  • 19,173
0

If we start from the premise that the simplest possibility is the most likely:

I do know that other people were moving directories around and renaming them, though I don't know exactly what they did.

then the scenario should be relatively straightforward to reproduce. Consider this example run with prompts 1$ for the first terminal interspersed with 2$ for the second

# Set up the scenario
1$ mkdir a a/b a/b/c d
1$ cd a/b/c

# Look at the parent inode
1$ ls -lid ..
143279 drwxr-xr-x 3 roaima roaima 4096 Apr 20 08:42 ..

# Second session changes the directory structure
2$ mv a/b/c d

# Look at the parent inode once more - notice it's changed
1$ ls -lid ..
142603 drwxr-xr-x 3 roaima roaima 4096 Apr 20 08:43
Chris Davies
  • 116,213
  • 16
  • 160
  • 287