系統狀態變更¶
有些使用者非常不願意重啟系統。 這就需要提供更多的 livepatch 並保持它們之間的一些相容性。
使用累積 livepatch 可以更容易地維護更多的 livepatch。 每個新的 livepatch 完全替換任何舊的 livepatch。 它可以保留、新增甚至刪除修復。 並且由於原子替換功能,通常可以安全地將任何版本的 livepatch 替換為任何其他版本。
問題可能出在影子變數和回撥上。 它們可能會改變系統行為或狀態,使其不再安全地返回並使用舊的 livepatch 或原始核心程式碼。 此外,任何新的 livepatch 都必須能夠檢測到已經安裝的 livepatch 所做的更改。
這就是 livepatch 系統狀態跟蹤發揮作用的地方。 它允許
儲存操作和恢復系統狀態所需的資料
使用更改 ID 和版本定義 livepatch 之間的相容性
1. Livepatch 系統狀態 API¶
系統狀態可能會被多個 livepatch 回撥或新使用的程式碼修改。 此外,必須能夠找到已安裝的 livepatch 所做的更改。
每個修改後的狀態都由 struct klp_state 描述,請參閱 include/linux/livepatch.h。
每個 livepatch 定義一個 struct klp_states 陣列。 它們提到 livepatch 修改的所有狀態。
livepatch 作者必須為每個 struct klp_state 定義以下兩個欄位
id
用於標識受影響的系統狀態的非零數字。
version
描述給定 livepatch 支援的系統狀態更改變體的數字。
可以使用以下兩個函式操作狀態
獲取與給定 livepatch 和狀態 ID 關聯的
struct klp_state。
獲取與給定功能 ID 和已安裝的 livepatch 關聯的
struct klp_state。
2. Livepatch 相容性¶
系統狀態版本用於防止載入不相容的 livepatch。 檢查在啟用 livepatch 時完成。 規則是
允許任何全新的系統狀態修改。
對於已修改的系統狀態,允許使用相同或更高版本的系統狀態修改。
累積 livepatch 必須處理來自已安裝的 livepatch 的所有系統狀態修改。
允許非累積 livepatch 觸及已修改的系統狀態。
3. 支援的場景¶
Livepatch 有其生命週期,系統狀態變更也是如此。 每個相容的 livepatch 都必須支援以下場景
當啟用 livepatch 並且該狀態尚未被正在被替換的 livepatch 修改時,修改系統狀態。
接管或更新系統狀態修改,如果它已經被正在被替換的 livepatch 完成。
停用 livepatch 時,恢復原始狀態。
還原轉換時,恢復先前的狀態。 可能是原始系統狀態或正在被替換的 livepatch 所做的狀態修改。
當發生錯誤且無法啟用 livepatch 時,刪除任何已做的更改。
4. 預期用法¶
系統狀態通常由 livepatch 回撥修改。 每個回撥的預期角色如下
pre_patch()
必要時分配 *state->data*。 分配可能會失敗,並且 *pre_patch()* 是唯一可以停止載入 livepatch 的回撥。 如果資料已由先前安裝的 livepatch 提供,則不需要分配。
在轉換完成之前,執行新程式碼所需的任何其他準備操作。 例如,初始化 *state->data*。
系統狀態本身通常在 *post_patch()* 中修改,此時整個系統都能夠處理它。
發生錯誤時清理自己的爛攤子。 這可以透過自定義程式碼或顯式呼叫 *post_unpatch()* 來完成。
post_patch()
當它們相容時,從先前的 livepatch 複製 *state->data*。
進行實際的系統狀態修改。 最終允許新程式碼使用它。
確保 *state->data* 具有所有必要的資訊。
當不再需要時,從替換的 livepatch 中釋放 *state->data*。
pre_unpatch()
防止 livepatch 新增的程式碼依賴於系統狀態更改。
還原系統狀態修改。
post_unpatch()
透過檢查 *
klp_get_prev_state()* 區分轉換反轉和 livepatch 停用。在轉換反轉的情況下,恢復先前的系統狀態。 這可能意味著什麼都不做。
刪除任何不再需要的設定或資料。
注意
*pre_unpatch()* 通常執行與 *post_patch()* 對稱的操作。 唯一的區別是它僅在停用 livepatch 時被呼叫。 因此,它不需要關心任何先前安裝的 livepatch。
*post_unpatch()* 通常執行與 *pre_patch()* 對稱的操作。 它也可能在轉換反轉期間被呼叫。 因此,它必須處理先前安裝的 livepatch 的狀態。