Add helpers to walk through saved CPR fds to preserve or retrieve
LUO-supported fds. Ignore fds that are not LUO-supported.

Signed-off-by: Dongli Zhang <[email protected]>
---
 include/migration/cpr.h |  2 ++
 migration/cpr-luo.c     | 59 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/include/migration/cpr.h b/include/migration/cpr.h
index 775f584368..bfb2bb0b50 100644
--- a/include/migration/cpr.h
+++ b/include/migration/cpr.h
@@ -92,5 +92,7 @@ int cpr_luo_retrieve_fd(int session_fd, uint64_t token, Error 
**errp);
 QEMUFile *cpr_luo_output(Error **errp);
 QEMUFile *cpr_luo_input(int session_fd, Error **errp);
 bool cpr_luo_persist_state(int session_fd, QEMUFile *f, Error **errp);
+bool cpr_luo_preserve_fds(Error **errp);
+bool cpr_luo_retrieve_fds(Error **errp);
 void cpr_luo_abort(void);
 #endif
diff --git a/migration/cpr-luo.c b/migration/cpr-luo.c
index 5b6bd6e191..f20ba1f30c 100644
--- a/migration/cpr-luo.c
+++ b/migration/cpr-luo.c
@@ -152,6 +152,65 @@ bool cpr_luo_persist_state(int session_fd, QEMUFile *f, 
Error **errp)
                                CPR_LUO_STATE_TOKEN, errp) == 0;
 }
 
+/*
+ * This function must be called only after cpr_fd_pre_save() has assigned
+ * LUO tokens.
+ */
+static bool cpr_luo_preserve_one(CprFd *elem, Error **errp)
+{
+    if (!elem->luo) {
+        return true;
+    }
+
+    if (!elem->luo_token) {
+        error_setg(errp, "missing LUO token for CprFd %s id %d",
+                   elem->name, elem->id);
+        return false;
+    }
+
+    return cpr_luo_preserve_fd(cpr_state.luo_session_fd, elem->fd,
+                               elem->luo_token, errp) == 0;
+}
+
+bool cpr_luo_preserve_fds(Error **errp)
+{
+    return cpr_walk_fd(cpr_luo_preserve_one, errp);
+}
+
+/*
+ * This function must be called only after cpr_fd_post_load() has
+ * initialized luo and received luo_token.
+ */
+static bool cpr_luo_retrieve_one(CprFd *elem, Error **errp)
+{
+    int retrieved_fd;
+
+    if (!elem->luo) {
+        return true;
+    }
+
+    if (!elem->luo_token) {
+        error_setg(errp, "missing LUO token for CprFd %s id %d",
+                   elem->name, elem->id);
+        return false;
+    }
+
+    retrieved_fd = cpr_luo_retrieve_fd(cpr_state.luo_session_fd,
+                                       elem->luo_token, errp);
+
+    if (retrieved_fd < 0) {
+        return false;
+    }
+
+    elem->fd = retrieved_fd;
+    return true;
+}
+
+bool cpr_luo_retrieve_fds(Error **errp)
+{
+    return cpr_walk_fd(cpr_luo_retrieve_one, errp);
+}
+
 void cpr_luo_abort(void)
 {
     int session_fd = cpr_state.luo_session_fd;
-- 
2.43.5


Reply via email to