What Is There Behind a Symbolic Link

What is there behind a symbolic link?

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.

JAVA how to find the target file path that a symbolic link points to?

https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html#toRealPath-java.nio.file.LinkOption...-

Path toRealPath(LinkOption... options)
throws IOException Returns the real path of an existing file. The precise definition of this method is implementation dependent but
in general it derives from this path, an absolute path that locates
the same file as this path, but with name elements that represent the
actual name of the directories and the file. For example, where
filename comparisons on a file system are case insensitive then the
name elements represent the names in their actual case. Additionally,
the resulting path has redundant name elements removed.

If this path is relative then its absolute path is first obtained, as
if by invoking the toAbsolutePath method.

The options array may be used to indicate how symbolic links are
handled. By default, symbolic links are resolved to their final
target. If the option NOFOLLOW_LINKS is present then this method does
not resolve symbolic links. Some implementations allow special names
such as ".." to refer to the parent directory. When deriving the real
path, and a ".." (or equivalent) is preceded by a non-".." name then
an implementation will typically cause both names to be removed. When
not resolving symbolic links and the preceding name is a symbolic link
then the names are only removed if it guaranteed that the resulting
path will locate the same file as this path.

Parameters: options - options indicating how symbolic links are
handled Returns: an absolute path represent the real path of the file
located by this object Throws: IOException - if the file does not
exist or an I/O error occurs SecurityException - In the case of the
default provider, and a security manager is installed, its checkRead
method is invoked to check read access to the file, and where this
path is not absolute, its checkPropertyAccess method is invoked to
check access to the system property user.dir

Use the toRealPath() method from nio. The NO_FOLLOW_LINKS LinkOption does the opposite of what you are trying to do, so don't use it.

Path realPath = aFile.toPath().toRealPath()

Path realPath = aPath().toRealPath()

One gotcha with this, is that, unlike toAbsolutePath, toRealPath throws an IOException since it actually has to interact with the file system to find the real path.

How to check whether the target of a directory symbolic link exists?

I could use CreateFile for symbolic file to get the file handle and
then check the file is exist or not.

If FILE_FLAG_OPEN_REPARSE_POINT is not specified in call CreateFile and you get file handle this mean that symbolic link/mount point target is exist. so already not need check something. if call fail because target not exist last error will be ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND (may be also ERROR_BAD_PATHNAME)

about FILE_FLAG_BACKUP_SEMANTICS - this is very bad design of CreateFile api. this api internal call NtCreateFile. the FILE_FLAG_BACKUP_SEMANTICS mapped to FILE_OPEN_FOR_BACKUP_INTENT CreateOptions flag. this flag checked inside IopCheckBackupRestorePrivilege

This function will determine if the caller is asking for any accesses
that may be satisfied by Backup or Restore privileges, and if so,
perform the privilege checks. If the privilege checks succeed, then
the appropriate bits will be moved out of the RemainingDesiredAccess
field in the AccessState structure and placed into the
PreviouslyGrantedAccess field.

Note that access is not denied if the caller does not have either or both of the privileges, since he may be granted the desired access via
the security descriptor on the object.

so even if caller have not either or both of the Backup or Restore privileges this not create problems.

but NtCreateFile have the next 2 options: FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE - this let specify are we want create/open file or directory. if we (potential) create new item - we need specify are we want create directory (FILE_DIRECTORY_FILE must be set) or not directory (FILE_NON_DIRECTORY_FILE, but by default assume this case - so optional). when we open file - both this flags is optional - if we not specify both - this mean that we not care are we open file or directory. if we care about this - need specify one of this flags.

but if look to CreateFile visible that not exist option which explicity mapped to FILE_DIRECTORY_FILE or FILE_NON_DIRECTORY_FILE. the CreateFile use for this .. FILE_FLAG_BACKUP_SEMANTICS option. this is very not logical from my view, but as is. when FILE_FLAG_BACKUP_SEMANTICS not set CreateFile pass FILE_NON_DIRECTORY_FILE option for NtCreateFile. when it set - pass FILE_OPEN_FOR_BACKUP_INTENT and not pass FILE_NON_DIRECTORY_FILE. this allow you open file or directory. and no option for set FILE_DIRECTORY_FILE - because this CreatrFile can not create new directory.

so instead have separate option for FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE, CreateFile abuse FILE_FLAG_BACKUP_SEMANTICS wich have double sense here

Can I create a symbolic link in Firebase?

In most databases what you're describing would be a managed foreign key. Nothing similar exists in Realtime Database however. While you can (and often will) store the key of one node as the value somewhere else, Firebase won't know anything about the meaning of such values - and not do anything with them.

Duplicating data is extremely common in NoSQL databases, so I highly recommend embracing it. Once you do, you can start looking at how to then manage the duplicated data, for example by letting Cloud Functions take care of updating the duplicates.

Also see:

  • my answer here: How to write denormalized data in Firebase

  • this article on NoSQL data modeling

  • the video series Firebase for SQL developers

Dealing with unix symlink files on Windows filesystem

Windows file system uses similar approach as UNIX to define what symlink is (like hard- or soft- links), but they are not 100% compatible. You can read more about that here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680(v=vs.85).aspx
The simple answer to you question - you can't just bitwise copy links to have the same Unix specific bits, because Windows NTFS just don't have them. JAVA is also designed to work in a sandbox, so you don't have access to system low-level API in order to make "whatever you want". I wouldn't go for such system-specific task with JAVA. Probably you will not have to.

Depends on your role at this project you can re-define what bundle should contain. Do you really need symlinks inside? May be it is more universal to have some kind of "property" file that maps different parts together? Or distribute it as database? Try not to depend from system specific realization.

Git symbolic links in Windows

You can find the symlinks by looking for files that have a mode of 120000, possibly with this command:

git ls-files -s | awk '/120000/{print $4}'

Once you replace the links, I would recommend marking them as unchanged with git update-index --assume-unchanged, rather than listing them in .git/info/exclude.



Related Topics



Leave a reply



Submit