mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 07:15:31 +00:00
files: Add more comments about shared files dump/restore
This is not trivial codeflow, let's document it till we remember what and why it does. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
41
files.c
41
files.c
@@ -83,6 +83,39 @@ static inline struct file_desc *find_file_desc(FdinfoEntry *fe)
|
|||||||
return find_file_desc_raw(fe->type, fe->id);
|
return find_file_desc_raw(fe->type, fe->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A file may be shared between several file descriptors. E.g
|
||||||
|
* when doing a fork() every fd of a forker and respective fds
|
||||||
|
* of the child have such. Another way of getting shared files
|
||||||
|
* is by dup()-ing them or sending them via unix sockets in
|
||||||
|
* SCM_RIGHTS message.
|
||||||
|
*
|
||||||
|
* We restore this type of things in 3 steps (states[] below)
|
||||||
|
*
|
||||||
|
* 1. Prepare step.
|
||||||
|
* Select which task will create the file (open() one, or
|
||||||
|
* call any other syscall for than (socket, pipe, etc.). All
|
||||||
|
* the others, that share one, create unix sockets under the
|
||||||
|
* respective file descriptor (transport socket).
|
||||||
|
* 2. Open step.
|
||||||
|
* The one who creates the file (the 'master') creates one,
|
||||||
|
* then creates one more unix socket (transport) and sends the
|
||||||
|
* created file over this socket to the other recepients.
|
||||||
|
* 3. Receive step.
|
||||||
|
* Those, who wait for the file to appear, receive one via
|
||||||
|
* the transport socket, then close the socket and dup() the
|
||||||
|
* received file descriptor into its place.
|
||||||
|
*
|
||||||
|
* There's the 4th step in the states[] array -- the post_open
|
||||||
|
* one. This one is not about file-sharing resolving, but about
|
||||||
|
* doing something with a file using it's 'desired' fd. The
|
||||||
|
* thing is that while going the 3-step process above, the file
|
||||||
|
* may appear in variuos places in the task's fd table, and if
|
||||||
|
* we want to do something with it's _final_ descriptor value,
|
||||||
|
* we should wait for it to appear there. So the post_open is
|
||||||
|
* called when the file is finally set into its place.
|
||||||
|
*/
|
||||||
|
|
||||||
struct fdinfo_list_entry *file_master(struct file_desc *d)
|
struct fdinfo_list_entry *file_master(struct file_desc *d)
|
||||||
{
|
{
|
||||||
if (list_empty(&d->fd_info_head)) {
|
if (list_empty(&d->fd_info_head)) {
|
||||||
@@ -110,6 +143,14 @@ void show_saved_files(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The gen_id thing is used to optimize the comparison of shared files.
|
||||||
|
* If two files have different gen_ids, then they are different for sure.
|
||||||
|
* If it matches, we don't know it and have to call sys_kcmp().
|
||||||
|
*
|
||||||
|
* The kcmp-ids.c engine does this trick, see comments in it for more info.
|
||||||
|
*/
|
||||||
|
|
||||||
static u32 make_gen_id(const struct fd_parms *p)
|
static u32 make_gen_id(const struct fd_parms *p)
|
||||||
{
|
{
|
||||||
return ((u32)p->stat.st_dev) ^ ((u32)p->stat.st_ino) ^ ((u32)p->pos);
|
return ((u32)p->stat.st_dev) ^ ((u32)p->stat.st_ino) ^ ((u32)p->pos);
|
||||||
|
@@ -90,7 +90,7 @@ struct file_desc_ops {
|
|||||||
int (*post_open)(struct file_desc *d, int fd);
|
int (*post_open)(struct file_desc *d, int fd);
|
||||||
/*
|
/*
|
||||||
* Report whether the fd in question wants a transport socket
|
* Report whether the fd in question wants a transport socket
|
||||||
* in it instead of a real file.
|
* in it instead of a real file. See file_master for details.
|
||||||
*/
|
*/
|
||||||
int (*want_transport)(FdinfoEntry *fe, struct file_desc *d);
|
int (*want_transport)(FdinfoEntry *fe, struct file_desc *d);
|
||||||
/*
|
/*
|
||||||
@@ -101,7 +101,7 @@ struct file_desc_ops {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct file_desc {
|
struct file_desc {
|
||||||
u32 id; /* File descriptor id, unique */
|
u32 id; /* File id, unique */
|
||||||
struct hlist_node hash; /* Descriptor hashing and lookup */
|
struct hlist_node hash; /* Descriptor hashing and lookup */
|
||||||
struct list_head fd_info_head; /* Chain of fdinfo_list_entry-s with same ID and type but different pids */
|
struct list_head fd_info_head; /* Chain of fdinfo_list_entry-s with same ID and type but different pids */
|
||||||
struct file_desc_ops *ops; /* Associated operations */
|
struct file_desc_ops *ops; /* Associated operations */
|
||||||
|
Reference in New Issue
Block a user