[CRIU] [PATCH v7 06/15] files: new "used" files list introduced
Stanislav Kinsburskiy
skinsbursky at virtuozzo.com
Mon Mar 14 07:59:05 PDT 2016
This list contains all per-process used file fdinfo's, sorted by fd number.
Will be used to safely create new artificial file descriptors and also allow
to recreate temporary descriptors with original number, if possible, like
AutoFS tries to preserve original pipe write end descriptor, when it was
closed.
This patch also adds simple helper to find unused file descriptor.
Return "hint" if unused or last used descriptor plus one.
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
---
criu/eventpoll.c | 1 +
criu/files.c | 1 +
criu/include/files.h | 30 ++++++++++++++++++++++++++++++
criu/include/rst_info.h | 1 +
criu/tty.c | 1 +
5 files changed, 34 insertions(+)
diff --git a/criu/eventpoll.c b/criu/eventpoll.c
index 9fa13c2..205a02a 100644
--- a/criu/eventpoll.c
+++ b/criu/eventpoll.c
@@ -185,6 +185,7 @@ static void eventpoll_collect_fd(struct file_desc *d,
struct fdinfo_list_entry *fle, struct rst_info *ri)
{
list_add_tail(&fle->ps_list, &ri->eventpoll);
+ collect_used_fd(fle, ri);
}
static struct file_desc_ops desc_ops = {
diff --git a/criu/files.c b/criu/files.c
index 8a7d85f..5f59110 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -686,6 +686,7 @@ int prepare_fd_pid(struct pstree_item *item)
pid_t pid = item->pid.virt;
struct rst_info *rst_info = rsti(item);
+ INIT_LIST_HEAD(&rst_info->used);
INIT_LIST_HEAD(&rst_info->fds);
INIT_LIST_HEAD(&rst_info->eventpoll);
INIT_LIST_HEAD(&rst_info->tty_slaves);
diff --git a/criu/include/files.h b/criu/include/files.h
index 5db6ab1..9d7a500 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -67,6 +67,7 @@ struct fdinfo_list_entry {
struct list_head desc_list; /* To chain on @fd_info_head */
struct file_desc *desc; /* Associated file descriptor */
struct list_head ps_list; /* To chain per-task files */
+ struct list_head used_list; /* To chain per-task used fds */
int pid;
futex_t real_pid;
FdinfoEntry *fe;
@@ -108,9 +109,38 @@ struct file_desc_ops {
char * (*name)(struct file_desc *, char *b, size_t s);
};
+static inline void collect_used_fd(struct fdinfo_list_entry *new_fle, struct rst_info *ri)
+{
+ struct fdinfo_list_entry *fle;
+
+ list_for_each_entry(fle, &ri->used, used_list) {
+ if (new_fle->fe->fd < fle->fe->fd)
+ break;
+ }
+
+ list_add_tail(&new_fle->used_list, &fle->used_list);
+}
+
static inline void collect_gen_fd(struct fdinfo_list_entry *fle, struct rst_info *ri)
{
list_add_tail(&fle->ps_list, &ri->fds);
+ collect_used_fd(fle, ri);
+}
+
+static inline unsigned int find_unused_fd(struct list_head *head, int hint_fd)
+{
+ struct fdinfo_list_entry *fle;
+ bool hint_fd_used = false;
+ int last_used_fd = 0;
+
+ list_for_each_entry(fle, head, used_list) {
+ if (fle->fe->fd == hint_fd)
+ hint_fd_used = true;
+ last_used_fd = fle->fe->fd;
+ }
+ if (hint_fd_used || (hint_fd < 0))
+ return last_used_fd + 1;
+ return hint_fd;
}
struct file_desc {
diff --git a/criu/include/rst_info.h b/criu/include/rst_info.h
index b6d378e..562e2f0 100644
--- a/criu/include/rst_info.h
+++ b/criu/include/rst_info.h
@@ -27,6 +27,7 @@ struct fdt {
struct _MmEntry;
struct rst_info {
+ struct list_head used;
struct list_head fds;
struct list_head eventpoll;
struct list_head tty_slaves;
diff --git a/criu/tty.c b/criu/tty.c
index ba44af6..b9aa8e7 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -1047,6 +1047,7 @@ static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
tgt = &ri->tty_slaves;
list_add_tail(&fle->ps_list, tgt);
+ collect_used_fd(fle, ri);
}
static char *tty_d_name(struct file_desc *d, char *buf, size_t s)
More information about the CRIU
mailing list