2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 18:07:57 +00:00
criu/include/file-ids.h
Cyrill Gorcunov 2acc741a3a files: Use sys_kcmp to find file descriptor duplicates v4
We switch generic-object-id concept with sys_kcmp approach,
which implies changes of image format a bit (and since it's
early time for project overall, we're allowed to).

In short -- previously every file descriptor had an ID
generated by a kernel and exported via procfs. If the
appropriate file descriptors were the same objects in
kernel memory -- the IDs did match up to bit. It allows
us to figure out which files were actually the identical
ones and should be restored in a special way.

Once sys_kcmp system call was merged into the kernel,
we've got a new opprotunity -- to use this syscall instead.
The syscall basically compares kernel objects and returns
ordered results suitable for objects sorting in a userspace.

For us it means -- we treat every file descriptor as a combination
of 'genid' and 'subid'. While 'genid' serves for fast comparison
between fds, the 'subid' is kind of a second key, which guarantees
uniqueness of genid+subid tuple over all file descritors found
in a process (or group of processes).

To be able to find and dump file descriptors in a single pass we
collect every fd into a global rbtree, where (!) each node might
become a root for a subtree as well.

The main tree carries only non-equal genid. If we find genid which
is already in tree, we need to make sure that it's either indeed
a duplicate or not. For this we use sys_kcmp syscall and if we
find that file descriptors are different -- we simply put new
fd into a subtree.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-28 19:13:47 +04:00

35 lines
660 B
C

#ifndef FILE_IDS_H__
#define FILE_IDS_H__
#include "compiler.h"
#include "types.h"
#include "rbtree.h"
#define FD_ID_INVALID (-1UL)
#define FD_PID_INVALID ((int)-2UL)
struct fd_id_entry {
struct rb_node node;
struct rb_root subtree_root;
struct rb_node subtree_node;
union {
struct {
u32 genid; /* generic id, may have duplicates */
u32 subid; /* subid is always unique */
} key;
u64 id;
} u;
pid_t pid;
int fd;
} __aligned(sizeof(long));
#define MAKE_FD_GENID(dev, ino, pos) \
(((u32)(dev) ^ (u32)(ino) ^ (u32)(pos)))
extern struct fd_id_entry *fd_id_entry_collect(u32 genid, pid_t pid, int fd);
#endif /* FILE_IDS_H__ */