[CRIU] [PATCH v8 06/15] files: new "used" files list introduced
Stanislav Kinsburskiy
skinsbursky at virtuozzo.com
Wed Mar 16 06:17:27 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 a couple of simple helpers to find unused file
descriptor:
1) fd_is_used() does exactly what it is named
2) find_unused_fd() returns "hint_fd" if unused or last used descriptor plus
one.
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
---
criu/files.c | 3 +++
criu/include/files.h | 33 +++++++++++++++++++++++++++++++++
criu/include/rst_info.h | 1 +
3 files changed, 37 insertions(+)
diff --git a/criu/files.c b/criu/files.c
index 8a7d85f..40bb13a 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -646,6 +646,8 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info)
else
collect_gen_fd(new_le, rst_info);
+ collect_used_fd(new_le, rst_info);
+
list_add_tail(&new_le->desc_list, &le->desc_list);
new_le->desc = fdesc;
@@ -686,6 +688,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..d38dbfd 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,11 +109,43 @@ 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);
}
+static inline bool fd_is_used(struct list_head *head, int fd)
+{
+ struct fdinfo_list_entry *fle;
+
+ list_for_each_entry(fle, head, used_list) {
+ if (fle->fe->fd == fd)
+ return true;
+ }
+
+ return false;
+}
+
+static inline unsigned int find_unused_fd(struct list_head *head, int hint_fd)
+{
+ if ((hint_fd >= 0) && (!fd_is_used(head, hint_fd)))
+ return hint_fd;
+ /* Return last used fd +1 */
+ return list_entry(head->prev, typeof(struct fdinfo_list_entry), used_list)->fe->fd + 1;
+}
+
struct file_desc {
u32 id; /* File id, unique */
struct hlist_node hash; /* Descriptor hashing and lookup */
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;
More information about the CRIU
mailing list