Difference between revisions of "How to open a file without open system call"
Line 1: | Line 1: | ||
Sometimes CRIU meets an inode object (check [[Dumping files|this]] article for details of what inode is) without a name. This article describes when this happens and what CRIU does in this case. | Sometimes CRIU meets an inode object (check [[Dumping files|this]] article for details of what inode is) without a name. This article describes when this happens and what CRIU does in this case. | ||
+ | |||
+ | == When this happens == | ||
+ | |||
+ | There are two nasty API calls in the Linux kernel -- the <code>inotify_init</code> and the <code>fanotify_init</code>. Both take a file path as an argument and screw one up. What they do is find an inode object using this path, then put an events generator on it and then forget the path completely. The result of both calls is a file-descriptor pointing to the created event generator object. | ||
+ | |||
+ | When CRIU meets the inotify/fanotify (called fsnotify later for convenience) FD it has to find out the file on which the generator sits. But, since the inode's path is lost, this cannot be done in general case. | ||
+ | |||
+ | == Chances to get the name back == | ||
+ | |||
+ | Chances to get the name back exist. To understand when let's dive a little bit more in how Linux manages dentries and inodes. | ||
+ | |||
+ | So, every file on disk is represented by an inode object. Inode has an ID (inode number), access rights, owner, link count and some more data. Names are only stored in special files called ''directories'' -- in directories there's a set of name-to-inode mappings. When accessing a file by its name Linux kernel sequentially reads from disk these mapping tables and for every name found in it creates a dentry object in memory. It's important to know, that dentry is created not only for existing files, but also for non-existing to speed up the ENOENT report for second file lookup. IOW dentries form a cache, which contains records for both present and absent objects on disk. | ||
+ | |||
+ | Since the tree of dentries can gorw infinitely Linux sometimes shrinks one, by freeing the unused dentries. The dentry is unused if no other object references one, and a dentry can be referenced by child dentries and by files (as described in [[dumping files|another]] article). | ||
+ | |||
+ | Having said that, at the time the fsnotify creating happens we have a full dentry chain and the inode sitting in memory. Then the events generator is put on the inode and that's it. Neither inode nor fsnotify object references the dentry, so eventually the whole dentry chain can be shrunk from memory. | ||
[[Category: Under the hood]] | [[Category: Under the hood]] |
Revision as of 08:28, 3 December 2014
Sometimes CRIU meets an inode object (check this article for details of what inode is) without a name. This article describes when this happens and what CRIU does in this case.
When this happens
There are two nasty API calls in the Linux kernel -- the inotify_init
and the fanotify_init
. Both take a file path as an argument and screw one up. What they do is find an inode object using this path, then put an events generator on it and then forget the path completely. The result of both calls is a file-descriptor pointing to the created event generator object.
When CRIU meets the inotify/fanotify (called fsnotify later for convenience) FD it has to find out the file on which the generator sits. But, since the inode's path is lost, this cannot be done in general case.
Chances to get the name back
Chances to get the name back exist. To understand when let's dive a little bit more in how Linux manages dentries and inodes.
So, every file on disk is represented by an inode object. Inode has an ID (inode number), access rights, owner, link count and some more data. Names are only stored in special files called directories -- in directories there's a set of name-to-inode mappings. When accessing a file by its name Linux kernel sequentially reads from disk these mapping tables and for every name found in it creates a dentry object in memory. It's important to know, that dentry is created not only for existing files, but also for non-existing to speed up the ENOENT report for second file lookup. IOW dentries form a cache, which contains records for both present and absent objects on disk.
Since the tree of dentries can gorw infinitely Linux sometimes shrinks one, by freeing the unused dentries. The dentry is unused if no other object references one, and a dentry can be referenced by child dentries and by files (as described in another article).
Having said that, at the time the fsnotify creating happens we have a full dentry chain and the inode sitting in memory. Then the events generator is put on the inode and that's it. Neither inode nor fsnotify object references the dentry, so eventually the whole dentry chain can be shrunk from memory.