Add helpers to create and retrieve Live Update Orchestrator (LUO)
sessions.

The LUO API is available only on Linux. Provide error stubs on other
hosts.

Signed-off-by: Dongli Zhang <[email protected]>
---
 include/migration/cpr.h  |  3 ++
 migration/cpr-luo-stub.c | 26 ++++++++++++++
 migration/cpr-luo.c      | 74 ++++++++++++++++++++++++++++++++++++++++
 migration/meson.build    |  6 ++++
 4 files changed, 109 insertions(+)
 create mode 100644 migration/cpr-luo-stub.c
 create mode 100644 migration/cpr-luo.c

diff --git a/include/migration/cpr.h b/include/migration/cpr.h
index e33eaf588b..f8b161b3d6 100644
--- a/include/migration/cpr.h
+++ b/include/migration/cpr.h
@@ -74,4 +74,7 @@ bool cpr_exec_persist_state(QEMUFile *f, Error **errp);
 bool cpr_exec_has_state(void);
 void cpr_exec_unpersist_state(void);
 void cpr_exec_unpreserve_fds(void);
+
+int cpr_luo_create_session(const char *name, Error **errp);
+int cpr_luo_retrieve_session(const char *name, Error **errp);
 #endif
diff --git a/migration/cpr-luo-stub.c b/migration/cpr-luo-stub.c
new file mode 100644
index 0000000000..ca060ae8c8
--- /dev/null
+++ b/migration/cpr-luo-stub.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2026 Oracle and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "migration/cpr.h"
+#include "qapi/error.h"
+
+static int cpr_luo_unsupported(Error **errp)
+{
+    error_setg(errp, "cpr-luo requires Linux");
+    return -1;
+}
+
+int cpr_luo_create_session(const char *name, Error **errp)
+{
+    return cpr_luo_unsupported(errp);
+}
+
+int cpr_luo_retrieve_session(const char *name, Error **errp)
+{
+    return cpr_luo_unsupported(errp);
+}
diff --git a/migration/cpr-luo.c b/migration/cpr-luo.c
new file mode 100644
index 0000000000..48288ed5f9
--- /dev/null
+++ b/migration/cpr-luo.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2026 Oracle and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include <sys/ioctl.h>
+
+#include "linux-headers/linux/liveupdate.h"
+#include "migration/cpr.h"
+#include "qapi/error.h"
+
+static int luo_open(Error **errp)
+{
+    return qemu_open("/dev/liveupdate", O_RDWR, errp);
+}
+
+int cpr_luo_create_session(const char *name, Error **errp)
+{
+    struct liveupdate_ioctl_create_session create = { 0 };
+    int fd;
+
+    if (g_strlcpy((char *)create.name, name, sizeof(create.name)) >=
+        sizeof(create.name)) {
+        error_setg(errp, "LUO session name is too long");
+        return -1;
+    }
+
+    fd = luo_open(errp);
+    if (fd < 0) {
+        return -1;
+    }
+
+    create.size = sizeof(create);
+    if (ioctl(fd, LIVEUPDATE_IOCTL_CREATE_SESSION, &create) < 0) {
+        error_setg_errno(errp, errno, "failed to create LUO session '%s'",
+                         (char *)create.name);
+        close(fd);
+        return -1;
+    }
+
+    close(fd);
+    return create.fd;
+}
+
+int cpr_luo_retrieve_session(const char *name, Error **errp)
+{
+    struct liveupdate_ioctl_retrieve_session retrieve = { 0 };
+    int fd;
+
+    if (g_strlcpy((char *)retrieve.name, name, sizeof(retrieve.name)) >=
+        sizeof(retrieve.name)) {
+        error_setg(errp, "LUO session name is too long");
+        return -1;
+    }
+
+    fd = luo_open(errp);
+    if (fd < 0) {
+        return -1;
+    }
+
+    retrieve.size = sizeof(retrieve);
+    if (ioctl(fd, LIVEUPDATE_IOCTL_RETRIEVE_SESSION, &retrieve) < 0) {
+        error_setg_errno(errp, errno, "failed to retrieve LUO session '%s'",
+                         (char *)retrieve.name);
+        close(fd);
+        return -1;
+    }
+
+    close(fd);
+    return retrieve.fd;
+}
diff --git a/migration/meson.build b/migration/meson.build
index 4ab9d99cea..a6363c2bf7 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -54,3 +54,9 @@ system_ss.add(when: qatzip, if_true: 
files('multifd-qatzip.c'))
 system_ss.add(when: 'CONFIG_VFIO',
               if_true: files('vfio.c'))
 stub_ss.add(files('vfio-stub.c'))
+
+if host_os == 'linux'
+  system_ss.add(files('cpr-luo.c'))
+else
+  system_ss.add(files('cpr-luo-stub.c'))
+endif
-- 
2.43.5


Reply via email to