使用者空間軟體掛起介面文件¶
2006 Rafael J. Wysocki <rjw@sisk.pl>
首先,交換分割槽掛起 開頭的警告仍然適用。
其次,如果您還沒有閱讀 交換分割槽掛起 中的 FAQ,_現在_就應該閱讀。
現在,要使用使用者空間介面進行軟體掛起,您需要特殊的實用程式,這些程式將從核心讀取/寫入系統記憶體快照。例如,可以從 <http://suspend.sourceforge.net> 獲取此類實用程式。如果您打算開發自己的掛起/恢復實用程式,您可能需要檢視它們。
該介面由一個字元裝置組成,該裝置提供 open()、release()、read() 和 write() 操作,以及 include/linux/suspend_ioctls.h 中定義的幾個 ioctl() 命令。該裝置的主裝置號和次裝置號分別為 10 和 231,它們可以從 /sys/class/misc/snapshot/dev 中讀取。
該裝置可以開啟以進行讀取或寫入。如果開啟以進行讀取,則認為處於掛起模式。否則,假定處於恢復模式。該裝置不能同時開啟以進行讀取和寫入。也不可能一次開啟該裝置多次。
即使開啟該裝置也會產生副作用。資料結構被分配,並且呼叫 PM_HIBERNATION_PREPARE / PM_RESTORE_PREPARE 鏈。
該裝置識別的 ioctl() 命令是
- SNAPSHOT_FREEZE
凍結使用者空間程序(當前程序未被凍結);這是 SNAPSHOT_CREATE_IMAGE 和 SNAPSHOT_ATOMIC_RESTORE 成功所必需的
- SNAPSHOT_UNFREEZE
解凍 SNAPSHOT_FREEZE 凍結的使用者空間程序
- SNAPSHOT_CREATE_IMAGE
建立系統記憶體的快照;ioctl() 的最後一個引數應該是指向一個 int 變數的指標,該變數的值將指示呼叫是在建立快照後(1)返回,還是在從快照恢復系統記憶體狀態後(0)返回(恢復後,系統發現自己再次完成 SNAPSHOT_CREATE_IMAGE ioctl());建立快照後,可以使用 read() 操作將其從核心中傳輸出來
- SNAPSHOT_ATOMIC_RESTORE
從上傳的快照映像恢復系統記憶體狀態;在呼叫它之前,您應該使用 write() 操作將系統記憶體快照傳輸回核心;如果核心無法使用快照映像,則此呼叫將不會成功
- SNAPSHOT_FREE
釋放為快照映像分配的記憶體
- SNAPSHOT_PREF_IMAGE_SIZE
設定映像的首選最大大小(核心將盡最大努力確保映像大小不會超過此數字,但如果事實證明不可能,核心將建立儘可能小的映像)
- SNAPSHOT_GET_IMAGE_SIZE
返回休眠映像的實際大小(最後一個引數應該是指向 loff_t 變數的指標,如果呼叫成功,該變數將包含結果)
- SNAPSHOT_AVAIL_SWAP_SIZE
返回可用交換空間量(以位元組為單位)(最後一個引數應該是指向 loff_t 變數的指標,如果呼叫成功,該變數將包含結果)
- SNAPSHOT_ALLOC_SWAP_PAGE
從恢復分割槽分配一個交換頁面(最後一個引數應該是指向 loff_t 變數的指標,如果呼叫成功,該變數將包含交換頁面偏移量)
- SNAPSHOT_FREE_SWAP_PAGES
釋放所有由 SNAPSHOT_ALLOC_SWAP_PAGE 分配的交換頁面
- SNAPSHOT_SET_SWAP_AREA
設定恢復分割槽和從分割槽開頭到交換頭所在位置的偏移量(以 <PAGE_SIZE> 為單位)(最後一個 ioctl() 引數應該指向一個 struct resume_swap_area,如 kernel/power/suspend_ioctls.h 中定義的那樣,包含恢復裝置規範和偏移量);對於交換分割槽,偏移量始終為 0,但對於交換檔案,偏移量不為零(有關詳細資訊,請參閱將交換檔案與軟體掛起 (swsusp) 一起使用)。
- SNAPSHOT_PLATFORM_SUPPORT
啟用/停用休眠平臺支援,具體取決於引數值(如果引數非零,則啟用)
- SNAPSHOT_POWER_OFF
使用平臺(例如 ACPI)驅動程式使核心將系統轉換為休眠狀態(例如 ACPI S4)
- SNAPSHOT_S2RAM
掛起到 RAM;使用此呼叫會導致核心立即進入掛起到 RAM 狀態,因此必須始終在此呼叫之前呼叫 SNAPSHOT_FREEZE,並且還必須在系統喚醒後使用 SNAPSHOT_UNFREEZE 呼叫。需要此呼叫來實現掛起到兩者機制,在這種機制中,首先建立掛起映像,就好像系統已掛起到磁碟一樣,然後系統掛起到 RAM(這樣就可以在電池電量充足時從 RAM 恢復系統,否則根據儲存的掛起映像恢復其狀態)
該裝置的 read() 操作可用於從核心傳輸快照映像。它具有以下限制
您一次不能 read() 超過一個虛擬記憶體頁面
read() 跨越頁面邊界是不可能的(即,如果您在上一次呼叫中 read() 了 1/2 個頁面,您在下一次呼叫中將只能 read() **最多** 1/2 個頁面)
該裝置的 write() 操作用於將系統記憶體快照上傳到核心。它與 read() 操作具有相同的限制。
release() 操作釋放為快照映像分配的所有記憶體和所有使用 SNAPSHOT_ALLOC_SWAP_PAGE 分配的交換頁面(如果有)。因此,無需在關閉裝置之前使用 SNAPSHOT_FREE 或 SNAPSHOT_FREE_SWAP_PAGES(事實上,如果使用者空間程序在關閉裝置時仍然被凍結,它也會解凍 SNAPSHOT_UNFREEZE 凍結的使用者空間程序)。
目前,假定讀取/寫入核心快照映像的使用者空間實用程式將使用一個稱為恢復分割槽的交換分割槽或一個交換檔案作為儲存空間(如果使用交換檔案,則恢復分割槽是儲存該檔案的分割槽)。但是,這並不是必需的,因為它們可以使用例如一個特殊的(空白)掛起分割槽或一個在 SNAPSHOT_CREATE_IMAGE 之前解除安裝並在之後掛載的分割槽上的檔案。
這些實用程式不得對快照映像中資料的排序做出任何假設。映像的內容完全由核心擁有,並且其結構可能會在未來的核心版本中更改。
快照映像必須以未更改的方式寫入核心(即,所有映像資料、元資料和標頭必須以_完全_相同的數量、形式和順序寫入,就像它們被讀取一樣)。否則,恢復後的系統的行為可能是完全不可預測的。
在執行 SNAPSHOT_ATOMIC_RESTORE 時,核心會檢查快照映像的結構是否與儲存在映像頭中的資訊一致。如果檢測到任何不一致,SNAPSHOT_ATOMIC_RESTORE 將不會成功。儘管如此,這並不是一個萬無一失的機制,使用該介面的使用者空間實用程式應該使用額外的手段,例如校驗和,來確保快照映像的完整性。
掛起和恢復實用程式必須將自身鎖定在記憶體中,最好使用 mlockall(),然後在呼叫 SNAPSHOT_FREEZE 之前。
掛起實用程式必須檢查 SNAPSHOT_CREATE_IMAGE 儲存在 ioctl() 的最後一個引數指向的記憶體位置中的值,並據此進行操作
如果值為 1(即,系統記憶體快照剛剛建立,系統已準備好儲存它)
_除非_要取消整個掛起過程,否則掛起實用程式不得關閉快照裝置,在這種情況下,如果快照映像已經儲存,掛起實用程式應該銷燬它,最好是透過破壞其標頭。如果掛起不取消,則在儲存快照映像後必須關閉或重新啟動系統。
掛起實用程式不應嘗試在呼叫 SNAPSHOT_CREATE_IMAGE 之前掛載的檔案系統上執行任何檔案系統操作(包括讀取)。但是,它可以掛載當時未掛載的檔案系統並在其上執行一些操作(例如,使用它來儲存映像)。
如果值為 0(即,系統狀態剛剛從快照映像恢復),則掛起實用程式必須關閉快照裝置。之後,它將被視為常規使用者空間程序,因此不需要退出。
恢復實用程式不應嘗試掛載任何在掛起之前可能已掛載的檔案系統,並且不應嘗試執行任何涉及此類檔案系統的操作。
有關詳細資訊,請參閱原始碼。