[CRIU] [PATCH RFC 18/30] files: Implement {set,get}_fds_event()

Kirill Tkhai ktkhai at virtuozzo.com
Tue Nov 1 07:33:21 PDT 2016


Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/files.c          |   37 +++++++++++++++++++++++++++++++++++++
 criu/include/files.h  |    3 +++
 criu/include/lock.h   |    5 +++++
 criu/include/pstree.h |    1 +
 4 files changed, 46 insertions(+)

diff --git a/criu/files.c b/criu/files.c
index 29ff9d1..97e3d49 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -1634,3 +1634,40 @@ static int open_transport_socket(pid_t pid)
 
 	return 0;
 }
+
+int set_fds_event(pid_t virt)
+{
+	struct pstree_item *item;
+	int old, st;
+
+	item = pstree_item_by_virt(virt);
+	BUG_ON(!item);
+
+	/* Wait till transport_fd is installed */
+	futex_wait_if_cond(&item->task_st, TFD_INSTALLED, &);
+
+	/* Set FDS_EVENT and wake up if need */
+	do {
+		old = futex_get(&item->task_st);
+		if (old & FDS_EVENT)
+			break;
+		st = atomic_cmpxchg(&item->task_st.raw, old, old | FDS_EVENT);
+	} while (st != old);
+
+	if (!(old & FDS_EVENT))
+		futex_wake(&item->task_st);
+	return 0;
+}
+
+int wait_fds_event(void)
+{
+	int old, st;
+
+	futex_wait_if_cond(&current->task_st, FDS_EVENT, &);
+	do {
+		old = futex_get(&current->task_st);
+		st = atomic_cmpxchg(&current->task_st.raw, old, old & ~FDS_EVENT);
+	} while (st != old);
+
+	return 0;
+}
diff --git a/criu/include/files.h b/criu/include/files.h
index ae4a9a1..7de61d8 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -192,4 +192,7 @@ extern FdinfoEntry *dup_fdinfo(FdinfoEntry *old, int fd, unsigned flags);
 int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple,
 	    int fd, unsigned flags);
 
+int set_fds_event(pid_t virt);
+int wait_fds_event(void);
+
 #endif /* __CR_FILES_H__ */
diff --git a/criu/include/lock.h b/criu/include/lock.h
index 0a99211..fff086a 100644
--- a/criu/include/lock.h
+++ b/criu/include/lock.h
@@ -79,6 +79,11 @@ static inline void futex_set_and_wake(futex_t *f, uint32_t v)
 	LOCK_BUG_ON(sys_futex((uint32_t *)&f->raw.counter, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0);
 }
 
+static inline void futex_wake(futex_t *f)
+{
+	LOCK_BUG_ON(sys_futex((uint32_t *)&f->raw.counter, FUTEX_WAKE, INT_MAX, NULL, NULL, 0) < 0);
+}
+
 /* Mark futex @f as wait abort needed and wake up all waiters */
 static inline void futex_abort_and_wake(futex_t *f)
 {
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index b3547ca..425082e 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -31,6 +31,7 @@ struct pstree_item {
 enum {
 	TSK_ALLOCATED = 0,
 	TFD_INSTALLED = 1 << 0,
+	FDS_EVENT     = 1 << 1,
 };
 
 struct pstree_item *current;



More information about the CRIU mailing list