What is there behind a symbolic link?
Asked Answered
P

2

25

How are symbolic links managed internally by UNIX/Linux systems. It is known that a symbolic link may exist even without an actual target file (Dangling link). So what is that which represents a symbolic link internally.

In Windows, the answer is a reparse point.

Questions:

Is the answer an inode in UNIX/Linux?

If yes, then will the inode number be same for target and links?

If yes, can the link inode can have permissions different from that of target's inode (if one exists)?

Perfervid answered 4/6, 2013 at 8:24 Comment(0)
M
26

It is not about UNIX/Linux but about filesystem implementation - but yes, Unix/Linux uses inodes at kernel level and filesystem implementations have inodes (at least virtual ones).

In the general, symbolic links are simply files (btw, directories are also files), that have:

  • the flag file-type in the "inode" that tells to the system this file is a "symbolic link"
  • file-content: path to the target - in other words: a symbolic link is simply a file which contains a filename with a flag in the inode.

Virtual filesystems can have symbolic links too, so, check FUSE or some other filesystem implementation sources. (ext2/ext3/ufs..etc)

So,

Is the answer an inode in UNIX/Linux?

depends on filesystem implementation, but yes, generally the inode contains a "file-type" (and owners, access rights, timestamps, size, pointers to data blocks). There are filesystems that don't have inodes (in a physical implementation) but have only "virtual inodes" for maintaining compatibility with the kernel.

If yes, then will the inode number be same for target and links?

No. Usually, the symlink is a file with its own inode, (with file-type, own data blocks, etc.)

If yes, can the link inode can have permissions different from that of target's inode(if one exists)?

This is about how symlink files are handled. Usually, the kernel doesn't allow changes to the symlink permissions - and symlinks always have default permissions. You could write your own filesystem that would allow different permissions for symlinks, but you would get into trouble because common programs like chmod don't change permissions on symlinks themselves, so making such a filesystem would be pointless anyway)

To understand the difference between hard links and symlinks, you should understand directories first.

Directories are files (with differentiated by a flag in the inode) that tell the kernel, "handle this file as a map of file-name to inode_number". Hard-links are simply file names that map to the same inode. So if the directory-file contains:

file_a: 1000
file_b: 1001
file_c: 1000

the above means, in this directory, are 3 files:

  • file_a described by inode 1000
  • file_b described by inode 1001 and
  • file_c again described by inode 1000 (so it is a hard link with file_a, not hardlink to file_a - because it is impossible to tell which filename came first - they are identical).

This is the main difference to symlinks, where the inode of file_b (inode 1001) could have content "file_a" and a flag meaning "this is a symlink". In this case, file_b would be a symlink pointing to file_a.

Majuscule answered 4/6, 2013 at 9:22 Comment(0)
M
3

You can also easily explore this on your own:

$ touch a
$ ln -s a b
$ ln a c
$ ls -li
total 0
95905 -rw-r--r-- 1 regnarg regnarg 0 Jun 19 19:01 a
96990 lrwxrwxrwx 1 regnarg regnarg 1 Jun 19 19:01 b -> a
95905 -rw-r--r-- 2 regnarg regnarg 0 Jun 19 19:01 c

The -i option to ls shows inode numbers in the first column. You can see that the symlink has a different inode number while the hardlink has the same. You can also use the stat(1) command:

$ stat a
  File: 'a'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 28h/40d Inode: 95905       Links: 2
[...]

$ stat b
  File: 'b' -> 'a'
  Size: 1           Blocks: 0          IO Block: 4096   symbolic link
Device: 28h/40d Inode: 96990       Links: 1
[...]

If you want to do this programmatically, you can use the lstat(2) system call to find information about the symlink itself (its inode number etc.), while stat(2) shows information about the target of the symlink, if it exists. Example in Python:

>>> import os
>>> os.stat("b").st_ino
95905
>>> os.lstat("b").st_ino
96990
Milore answered 19/6, 2016 at 17:16 Comment(1)
And readlink() allows you to find what is stored as the pathname in a given symlink — but life gets really interesting when one of the elements that the pathname in one symlink traverses is itself a symlink. The kernel handles it with aplomb; people don't necessarily. There's also realpath() which determines a symlink-free absolute path for a given file.Docilla

© 2022 - 2024 — McMap. All rights reserved.