Commit b4c09afd authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent dee617dc
...@@ -83,6 +83,39 @@ static inline struct file_desc *find_file_desc(FdinfoEntry *fe) ...@@ -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) ...@@ -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 { ...@@ -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 { ...@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment