Difference between revisions of "Dumping files"

From CRIU
Jump to navigation Jump to search
(Created page with "This is what CRIU does to dump information about opened files. == Files, descriptors and inodes in Linux == When a task opens a file Linux kernel constructs a chain of 3 (we...")
 
Line 3: Line 3:
 
== Files, descriptors and inodes in Linux ==
 
== Files, descriptors and inodes in Linux ==
  
When a task opens a file Linux kernel constructs a chain of 3 (well, 3.5) object to serve this.
+
When a task opens a file Linux kernel constructs a chain of 3 objects to serve this.
  
 
; Inode
 
; Inode
Line 35: Line 35:
 
                             +------+    +--------+    +-------+
 
                             +------+    +--------+    +-------+
 
</pre>
 
</pre>
 +
 +
The File object can be referenced by more than on FDT, e.g. when a task calls <code>fork()</code> the child one gets new FDT, but it references the same Files as the parent does, i.e. Files become shared objects.
 +
 +
The Inode object is also interesting. First of all, remember that in Linux file descriptors can be obtained not only by the <code>open()</code> system call, but also by <code>pipe()</code> and <code>socket()</code> and a bunch of Linux-specific <code>epoll_create</code>, <code>signalfd</code> and others. So when serving ''this'' Linux would anyway create the mentioned above chain of File-Dentry-Inode objects, but the Inode one will be different for different calls. And CRIU knows this all and acts respectively :)
 +
 +
== How info about opened files is stored in CRIU ==
 +
 +
Having said that CRIU introduces several images to keep info about what files are opened by task.
 +
 +
=== File descriptors ===
 +
 +
First image is the <code>fdinfo-$id.img</code> one. This image contains info about FDT of a process. The entries have two important fields -- <code>fd</code> and <code>id</code>.
 +
 +
The ''fd'' is the descriptor number under which the created on restore File should be put. The ''id'' is the identifier to the File-Inode object pair in other images.
 +
 +
=== Files themselves ===
 +
 +
Fore the sake of simplicity CRIU doesn't introduce separate states for Files, Dentries and Inodes leaving it to the kernel. Instead each this triplet is treated as one object and for every Inode type (file, pipe, socket, etc.) separate image is introduced. Thus CRIU has
 +
 +
* reg-files.img for regular files, that are created by open() call
 +
* unixsk.img for unix sockets
 +
* pipes.img for pipes
 +
* inetsk for IP sockets (both TCP and UDP)
 +
* signalfd.img for signal fd
 +
* etc.
 +
 +
In each of this files info about File and Inode of respective file is preserved. Dentry information is effectively stored there for regular files only -- the file's ''path''.
 +
 +
== How CRIU gets the information to dump ==

Revision as of 11:42, 1 December 2014

This is what CRIU does to dump information about opened files.

Files, descriptors and inodes in Linux

When a task opens a file Linux kernel constructs a chain of 3 objects to serve this.

Inode
This is an object which describes file as a couple of meta-data (owner, type, size) and data (the bytes themselves).
Dentry (directory entry)
A helper object that kernel uses to resolve file path into Inode object. If a file has hard-links, then one Inode will have several Dentries.
File
This one describes how a tasks works with an opened Dentry-Inode pair.
File descriptor
It's a number in task's table, that is used to reference the needed File object

So after open() (or some other, see below) system call there will be this chain in the memory

+------+
+ Task +-----+
+------+     |
             v
           +------------------------------+
           | File Descriptors Table (FDT) |
           +------------------------------+
           |   |   | 2 |      ...     |   |
           +------------------------------+
                     |
                     |
                     |      +------+    +--------+    +-------+
                     +----->| File |--->| Dentry |--->| Inode |
                            +------+    +--------+    +-------+

The File object can be referenced by more than on FDT, e.g. when a task calls fork() the child one gets new FDT, but it references the same Files as the parent does, i.e. Files become shared objects.

The Inode object is also interesting. First of all, remember that in Linux file descriptors can be obtained not only by the open() system call, but also by pipe() and socket() and a bunch of Linux-specific epoll_create, signalfd and others. So when serving this Linux would anyway create the mentioned above chain of File-Dentry-Inode objects, but the Inode one will be different for different calls. And CRIU knows this all and acts respectively :)

How info about opened files is stored in CRIU

Having said that CRIU introduces several images to keep info about what files are opened by task.

File descriptors

First image is the fdinfo-$id.img one. This image contains info about FDT of a process. The entries have two important fields -- fd and id.

The fd is the descriptor number under which the created on restore File should be put. The id is the identifier to the File-Inode object pair in other images.

Files themselves

Fore the sake of simplicity CRIU doesn't introduce separate states for Files, Dentries and Inodes leaving it to the kernel. Instead each this triplet is treated as one object and for every Inode type (file, pipe, socket, etc.) separate image is introduced. Thus CRIU has

  • reg-files.img for regular files, that are created by open() call
  • unixsk.img for unix sockets
  • pipes.img for pipes
  • inetsk for IP sockets (both TCP and UDP)
  • signalfd.img for signal fd
  • etc.

In each of this files info about File and Inode of respective file is preserved. Dentry information is effectively stored there for regular files only -- the file's path.

How CRIU gets the information to dump