[PATCH v4 1/3] liveupdate: Move file_set_ser handling to session serialization helpers
Pasha Tatashin
pasha.tatashin at soleen.com
Sun Oct 25 18:49:44 PDT 2026
Currently, struct luo_session_ser is populated and cleared across two
layers: luo_session_serialize() writes and clears ser->name, while
luo_file_freeze() and luo_file_unfreeze() write and clear
ser->file_set_ser.
In preparation for allowing userspace to freeze a session explicitly
before kexec reboot, luo_file_freeze() and luo_file_unfreeze() need to
be called on session->file_set before any struct luo_session_ser entry
is reserved in luo_session_serialize().
Drop the struct luo_file_set_ser pointer parameter from
luo_file_freeze() and luo_file_unfreeze(), and rename
luo_session_freeze_one() and luo_session_unfreeze_one() to
luo_session_serialize_one() and luo_session_unserialize_one() so that
all fields of struct luo_session_ser are populated and cleared in one
place.
Signed-off-by: Pasha Tatashin <pasha.tatashin at soleen.com>
---
kernel/liveupdate/luo_file.c | 24 ++++++++----------------
kernel/liveupdate/luo_internal.h | 6 ++----
kernel/liveupdate/luo_session.c | 31 ++++++++++++++++++++-----------
3 files changed, 30 insertions(+), 31 deletions(-)
diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index a39992da504f..988eb313a135 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -440,8 +440,7 @@ static void __luo_file_unfreeze(struct luo_file_set *file_set,
/**
* luo_file_freeze - Freezes all preserved files and serializes their metadata.
- * @file_set: The file_set whose files are to be frozen.
- * @file_set_ser: Where to put the serialized file_set.
+ * @file_set: The file_set whose files are to be frozen.
*
* This function is called from the reboot() syscall path, just before the
* kernel transitions to the new image via kexec. Its purpose is to perform the
@@ -457,8 +456,8 @@ static void __luo_file_unfreeze(struct luo_file_set *file_set,
*
* 2. Serializes Metadata: After a successful freeze, it copies the final file
* metadata—the handler's compatible string, the user token, and the final
- * private data handle—into the pre-allocated contiguous memory buffer
- * (file_set->files) that will be handed over to the next kernel via KHO.
+ * private data handle—into the pre-allocated serialization blocks
+ * (file_set->block_set) that will be handed over to the next kernel via KHO.
*
* Error Handling (Rollback):
* This function is atomic. If any handler's .freeze() operation fails, the
@@ -471,8 +470,7 @@ static void __luo_file_unfreeze(struct luo_file_set *file_set,
* Context: Called only from the liveupdate_reboot() path.
* Return: 0 on success, or a negative errno on failure.
*/
-int luo_file_freeze(struct luo_file_set *file_set,
- struct luo_file_set_ser *file_set_ser)
+int luo_file_freeze(struct luo_file_set *file_set)
{
struct luo_file *luo_file;
struct kho_block_set_it it;
@@ -506,9 +504,6 @@ int luo_file_freeze(struct luo_file_set *file_set,
file_ser->token = luo_file->token;
}
- file_set_ser->count = file_set->count;
- file_set_ser->files = kho_block_set_head_pa(&file_set->block_set);
-
return 0;
err_unfreeze:
@@ -519,28 +514,25 @@ int luo_file_freeze(struct luo_file_set *file_set,
/**
* luo_file_unfreeze - Unfreezes all files in a file_set and clear serialization
- * @file_set: The file_set whose files are to be unfrozen.
- * @file_set_ser: Serialized file_set.
+ * @file_set: The file_set whose files are to be unfrozen.
*
* This function rolls back the state of all files in a file_set after the
* freeze phase has begun but must be aborted. It is the counterpart to
* luo_file_freeze().
*
* It invokes the __luo_file_unfreeze() helper with a NULL argument, which
- * signals the helper to iterate through all files in the file_set and call
- * their respective .unfreeze() handler callbacks.
+ * signals the helper to iterate through all files in the file_set, call their
+ * respective .unfreeze() handler callbacks, and clear the serialized blocks.
*
* Context: This is called when the live update is aborted during
* the reboot() syscall, after luo_file_freeze() has been called.
*/
-void luo_file_unfreeze(struct luo_file_set *file_set,
- struct luo_file_set_ser *file_set_ser)
+void luo_file_unfreeze(struct luo_file_set *file_set)
{
if (!file_set->count)
return;
__luo_file_unfreeze(file_set, NULL);
- memset(file_set_ser, 0, sizeof(*file_set_ser));
}
/**
diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h
index dac6644bfb18..01a172cd9d7a 100644
--- a/kernel/liveupdate/luo_internal.h
+++ b/kernel/liveupdate/luo_internal.h
@@ -103,10 +103,8 @@ int luo_session_deserialize(void);
int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd);
void luo_file_unpreserve_files(struct luo_file_set *file_set);
-int luo_file_freeze(struct luo_file_set *file_set,
- struct luo_file_set_ser *file_set_ser);
-void luo_file_unfreeze(struct luo_file_set *file_set,
- struct luo_file_set_ser *file_set_ser);
+int luo_file_freeze(struct luo_file_set *file_set);
+void luo_file_unfreeze(struct luo_file_set *file_set);
int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
struct file **filep);
int luo_file_finish(struct luo_file_set *file_set);
diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
index f48e9a4185f9..827f9ad1938f 100644
--- a/kernel/liveupdate/luo_session.c
+++ b/kernel/liveupdate/luo_session.c
@@ -218,18 +218,30 @@ static int luo_session_finish_one(struct luo_session *session)
return luo_file_finish(&session->file_set);
}
-static void luo_session_unfreeze_one(struct luo_session *session,
- struct luo_session_ser *ser)
+static void luo_session_unserialize_one(struct luo_session *session,
+ struct luo_session_ser *ser)
{
guard(mutex)(&session->mutex);
- luo_file_unfreeze(&session->file_set, &ser->file_set_ser);
+ luo_file_unfreeze(&session->file_set);
+ memset(ser, 0, sizeof(*ser));
}
-static int luo_session_freeze_one(struct luo_session *session,
- struct luo_session_ser *ser)
+static int luo_session_serialize_one(struct luo_session *session,
+ struct luo_session_ser *ser)
{
+ int err;
+
guard(mutex)(&session->mutex);
- return luo_file_freeze(&session->file_set, &ser->file_set_ser);
+ err = luo_file_freeze(&session->file_set);
+ if (err)
+ return err;
+
+ strscpy(ser->name, session->name, sizeof(ser->name));
+ ser->file_set_ser.count = session->file_set.count;
+ ser->file_set_ser.files =
+ kho_block_set_head_pa(&session->file_set.block_set);
+
+ return 0;
}
static int luo_session_release(struct inode *inodep, struct file *filep)
@@ -656,13 +668,11 @@ int luo_session_serialize(void)
goto err_undo;
}
- err = luo_session_freeze_one(session, ser);
+ err = luo_session_serialize_one(session, ser);
if (err) {
kho_block_set_it_prev(&it);
goto err_undo;
}
-
- strscpy(ser->name, session->name, sizeof(ser->name));
}
if (sh->count > 0)
@@ -675,8 +685,7 @@ int luo_session_serialize(void)
list_for_each_entry_continue_reverse(session, &sh->list, list) {
struct luo_session_ser *ser = kho_block_set_it_prev(&it);
- luo_session_unfreeze_one(session, ser);
- memset(ser->name, 0, sizeof(ser->name));
+ luo_session_unserialize_one(session, ser);
}
up_write(&sh->rwsem);
up_write(&luo_session_serialize_rwsem);
--
2.56.0.307.g5fe7bd680c-goog
More information about the kexec
mailing list