Changes

4 bytes removed ,  21:43, 15 March 2016
m
fixed some english grammar
Line 1: Line 1:  
In Linux files may be inaccessible for open() but still be present in the system. This can happen in several ways and this page is about how this can happen and what CRIU does about it.
 
In Linux files may be inaccessible for open() but still be present in the system. This can happen in several ways and this page is about how this can happen and what CRIU does about it.
   −
== How file can lose it's path ==
+
== How a file can lose its path ==
    
This is pretty simple. A process may do this series of operations
 
This is pretty simple. A process may do this series of operations
Line 24: Line 24:  
If a task opens a file and then a new mountpoint appears on any part of its path, the original file's path may become non existing or point to different file.  
 
If a task opens a file and then a new mountpoint appears on any part of its path, the original file's path may become non existing or point to different file.  
   −
CRIU doesn't work with such files yet aborting the dump. However, there's a way to fix this.
+
CRIU doesn't work with such files yet, aborting the dump. However, there's a way to fix this.
    
Although in Linux there's no way to open a file by a name looking ''under'' certain mount points, there's the openat() call which may look up a file starting from arbitrary point which, in turn, can be over-mounted too.
 
Although in Linux there's no way to open a file by a name looking ''under'' certain mount points, there's the openat() call which may look up a file starting from arbitrary point which, in turn, can be over-mounted too.
Line 38: Line 38:  
If the <code>st_nlink</code> field is zero, then the file is fully deleted from the system. Since no filesystems allow to create a name back for such files, we have no other choice other than get the file itself into images. So we generate a so called ''ghost file'' in the image directory and copy the file contents into it.
 
If the <code>st_nlink</code> field is zero, then the file is fully deleted from the system. Since no filesystems allow to create a name back for such files, we have no other choice other than get the file itself into images. So we generate a so called ''ghost file'' in the image directory and copy the file contents into it.
   −
But what happens if the link count is not zero. Then we should check than the name we got from proc is the one with which we can see this file. So we call <code>stat()</code> on this name and compare <code>st_dev</code> and <code>st_inode</code> fields of it with those obtained from the fstat() call earlier. If they match the file is alive and we can just dump it's name. If they don't the name we got references some other file and we fail the dump. This can be handled, but this situation is quite rare so we decided to implement support for it later.  
+
But what happens if the link count is not zero. Then we should check than the name we got from proc is the one with which we can see this file. So we call <code>stat()</code> on this name and compare <code>st_dev</code> and <code>st_inode</code> fields of it with those obtained from the fstat() call earlier. If they match the file is alive and we can just dump its name. If they don't the name we got references some other file and we fail the dump. This can be handled, but this situation is quite rare so we decided to implement support for it later.  
   −
But there's also the 3rd possibility -- the <code>stat()</code> could fail with ENOENT error, which means, that the file has names, but the one we have one opened by is removed. In ''this'' situation we cannot just save the file name in the images, since this name is not longer alive. Neither we can dump the file as ghost, as the same file can be accessed by some other name. And, as was said, there's no way to fine this other name. Fortunately, in this case filesystems allow to create a new name for a file, so CRIU calls <code>linkat</code> system call creating a temporary name for this file on the disk and saves this name in the image. This is called ''link-remap''. Since this manoeuvre modifies the filesystem, CRIU requires the special option ''--link-remap'' to be passed to it allowing this behaviour. On restore the link-remap names are removed after files restore.
+
But there's also a 3rd possibility -- the <code>stat()</code> could fail with ENOENT error, which means that the file has names, but the one we have it opened by is removed. In ''this'' situation we cannot just save the file name in the images, since this name is not longer alive. Neither we can dump the file as ghost, as the same file can be accessed by some other name. And, as was said, there's no way to find this other name. Fortunately, in this case filesystems allow to create a new name for a file, so CRIU calls <code>linkat</code> system call creating a temporary name for this file on the disk and saves this name in the image. This is called ''link-remap''. Since this manoeuvre modifies the filesystem, CRIU requires the special option ''--link-remap'' to be passed to it allowing this behaviour. On restore the link-remap names are removed after files restore.
   −
Please note, that a file may have been opened by many removed names, and for each a link-remap name should point to the same file, so while dumping and restoring CRIU keeps track of those names to inode mappings.
+
Please note that a file may have been opened by many removed names, and for each a link-remap name should point to the same file, so while dumping and restoring CRIU keeps track of those names to inode mappings.
    
=== Virtual filesystems ===
 
=== Virtual filesystems ===
   −
For proc CRIU does a slightly different trick. When we see dead name in /proc we cannot link() a new name or create a ghost file. Instead, we remember the PID of the process, that died and on restore create a temporary task with the desired pid, which gets killed right after all its open()-ers are restored.
+
For proc CRIU uses a slightly different trick. When we see dead name in /proc we cannot link() a new name or create a ghost file. Instead, we remember the PID of the process that died, and on restore create a temporary task with the desired pid, which gets killed right after all its open()-ers are restored.
    
[[Category: Under the hood]]
 
[[Category: Under the hood]]
 
[[Category: Files]]
 
[[Category: Files]]
1

edit