交換掛起¶
首先,一些警告。
警告
重大警告
- 如果在掛起和恢復之間,你修改了磁碟上的任何內容...
...那麼就和你的資料說再見吧。
- 如果在檔案系統掛載後,你從 initrd 恢復...
...再見了,根分割槽。
[這實際上與上面的情況相同]
如果你有不支援( )DMA的裝置,你可能會遇到一些問題。如果你的磁碟驅動程式不支援掛起...(IDE支援),它也可能導致一些問題。如果在掛起和恢復之間更改核心命令列,可能會發生錯誤。如果在系統掛起時更改硬體...嗯,這不是一個好主意;但可能只會崩潰。
需要( )掛起/恢復支援才能使其安全。
如果在軟體掛起之前,你有任何檔案系統掛載在 USB 裝置上,那麼恢復後它們將無法訪問,你可能會丟失資料,就像你拔掉了掛載檔案系統的 USB 裝置一樣;有關詳細資訊,請參見下面的常見問題解答。(對於更傳統的電源狀態(如“待機”)來說,情況並非如此,因為它們通常不會關閉 USB。)
- 交換分割槽
你需要將 resume=/dev/your_swap_partition 追加到核心命令列,或者使用 /sys/power/resume 指定它。
- 交換檔案
如果使用交換檔案,你還可以在核心命令列上使用 resume_offset=<數字> 指定恢復偏移量,或者在 /sys/power/resume_offset 中指定它。
準備好之後,你可以透過以下方式掛起:
echo shutdown > /sys/power/disk; echo disk > /sys/power/state
如果你覺得 ACPI 在你的系統上執行良好,你可以嘗試:
echo platform > /sys/power/disk; echo disk > /sys/power/state
如果你想將休眠映像寫入交換空間,然後掛起至 RAM(如果你的平臺支援),你可以嘗試:
echo suspend > /sys/power/disk; echo disk > /sys/power/state
如果你有 SATA 磁碟,則需要具有 SATA 掛起支援的最新核心。為了使掛起和恢復工作正常,請確保你的磁碟驅動程式已構建到核心中——而不是模組。[有一種方法可以透過模組化磁碟驅動程式進行掛起/恢復,請參閱 FAQ,但你可能不應該這樣做。]
如果你想將掛起映象大小限制為 N 位元組,請執行:
echo N > /sys/power/image_size
在掛起之前(預設情況下,它被限制為可用 RAM 的 2/5 左右)。
恢復過程會檢查恢復裝置是否存在,如果找到,它會檢查內容中是否存在休眠映像簽名。如果兩者都找到,則恢復休眠映像。
可以透過兩種方式觸發恢復過程:
在 lateinit 期間:如果在核心命令列上指定了 resume=/dev/your_swap_partition,lateinit 將執行恢復過程。如果尚未探測到恢復裝置,則恢復過程將失敗,並且啟動將繼續。
手動從 initrd 或 initramfs:可以使用 /sys/power/resume 檔案從 init 指令碼執行。至關重要的是,必須在重新掛載任何檔案系統(即使是隻讀)之前完成此操作,否則資料可能會損壞。
關於 Linux 軟體掛起的 goals 和 implementation 的文章¶
作者:Gábor Kuti 最後修改:2003-10-20,作者:Pavel Machek
要實現的想法和目標¶
如今,在某些筆記型電腦中,它們都有一個掛起按鈕是很常見的。它將機器的狀態儲存到檔案系統或分割槽,並切換到待機模式。稍後恢復機器時,儲存的狀態將載入回 ram,並且機器可以繼續其工作。它有兩個真正的好處。首先,我們節省了機器關閉和稍後啟動的時間,從電池執行時能源成本非常高。另一個好處是,我們不必中斷我們的程式,因此長時間計算某些內容的程序不需要編寫成可中斷的。
swsusp 將機器的狀態儲存到活動的交換分割槽,然後重新啟動或關閉電源。你必須使用 resume= 核心選項顯式指定要從中恢復的交換分割槽。如果找到簽名,它將載入並恢復儲存的狀態。如果選項 noresume 被指定為啟動引數,它將跳過恢復。如果選項 hibernate=nocompress 被指定為啟動引數,它將儲存未壓縮的休眠映像。
在系統掛起的這段時間裡,你不應該新增/刪除任何硬體,寫入檔案系統等等。
睡眠狀態摘要¶
你可以使用三種不同的介面,/proc/acpi 應該像這樣工作:
在一個真正完美的世界裡:
echo 1 > /proc/acpi/sleep # for standby
echo 2 > /proc/acpi/sleep # for suspend to ram
echo 3 > /proc/acpi/sleep # for suspend to ram, but with more power
# conservative
echo 4 > /proc/acpi/sleep # for suspend to disk
echo 5 > /proc/acpi/sleep # for shutdown unfriendly the system
或許:
echo 4b > /proc/acpi/sleep # for suspend to disk via s4bios
常見問題解答¶
- 問:
嗯,在我看來,掛起伺服器真是一個愚蠢的事情,但是... (Diego Zuccato)
- 答:
你為你的伺服器購買了新的 UPS。你如何在不關閉機器的情況下安裝它?掛起至磁碟,重新佈置電源線,恢復。
你的伺服器在 UPS 上。電源已斷開,UPS 指示還有 30 秒將要失效。你該怎麼辦?掛起至磁碟。
- 問:
也許我遺漏了一些東西,但是為什麼常規的 I/O 路徑不起作用呢?
- 答:
我們確實使用了常規的 I/O 路徑。但是,我們在載入資料時無法將其恢復到原始位置。這將建立一個不一致的核心狀態,這肯定會導致 oops。相反,我們將映像載入到未使用的記憶體中,然後以原子方式將其複製回原始位置。當然,這意味著最大映像大小為記憶體總量的一半。
對此有兩種解決方案:
要求在掛起期間釋放一半的記憶體。這樣你就可以將“新”資料讀取到空閒位置,然後 cli 並複製。
假設我們有一個特殊的“輪詢” ide 驅動程式,它只使用 0-640KB 之間的記憶體。這樣,我必須確保在掛起期間 0-640KB 是空閒的,否則它可以正常工作...
suspend2 共享這個基本限制,但透過預先儲存使用者資料和磁碟快取,不會將它們包含到“已用記憶體”中。這意味著在實踐中,這個限制就消失了。
- 問:
Linux 是否支援 ACPI S4?
- 答:
是的。這就是 echo platform > /sys/power/disk 的作用。
- 問:
什麼是“suspend2”?
- 答:
suspend2 是“Software Suspend 2”,它是掛起至磁碟的派生實現,可以從 swsusp.sourceforge.net 獲得用於 2.4 和 2.6 核心的單獨補丁。它包括對 SMP、4GB highmem 和搶佔的支援。它還具有可擴充套件的架構,允許對映像進行任意轉換(壓縮、加密)以及用於寫入映像的任意後端(例如,交換空間或 NFS 共享[正在進行中])。有關 suspend2 的問題應傳送到透過 suspend2 網站提供的郵件列表,而不是傳送到 Linux 核心郵件列表。我們正在努力將 suspend2 合併到主線核心中。
- 問:
什麼是任務凍結,我們為什麼要使用它?
- 答:
任務凍結是一種機制,透過該機制,在休眠或系統範圍的掛起期間(在某些架構上)控制使用者空間程序和一些核心執行緒。有關詳細資訊,請參見 任務凍結。
- 問:
“platform”和“shutdown”之間有什麼區別?
- 答:
- shutdown
在 Linux 中儲存狀態,然後告訴 bios 關閉電源
- platform
在 Linux 中儲存狀態,然後告訴 bios 關閉電源並閃爍“掛起 LED”
“platform”實際上是在支援的情況下應該做的事情,但“shutdown”是最可靠的(在 ACPI 系統上除外)。
- 問:
我不明白為什麼你對選擇性掛起的想法有如此強烈的反對意見。
- 答:
在執行時電源管理期間進行選擇性掛起是可以的。但對於掛起至磁碟來說,它是無用的。(我不知道你怎麼能用它來進行掛起至 RAM,我希望你不想那樣做)。
讓我們看看,所以你建議:
掛起除了交換裝置及其父裝置以外的所有裝置
快照
將映像寫入磁碟
掛起交換裝置及其父裝置
關閉電源
哦,不,這行不通,如果交換裝置或其父裝置使用 DMA,你已經損壞了資料。你必須這樣做:
掛起除了交換裝置及其父裝置以外的所有裝置
凍結交換裝置及其父裝置
快照
解凍交換裝置及其父裝置
寫入
掛起交換裝置及其父裝置
這意味著你仍然需要 FREEZE 狀態,並且你會得到更復雜的程式碼。(我還沒有介紹像系統裝置這樣的細節)。
- 問:
在 SUSPEND 和 FREEZE 之間似乎沒有任何通常有用的行為區別。
- 答:
當你被要求執行 FREEZE 時,執行 SUSPEND 始終是正確的,但它可能會不必要地慢。如果你想讓你的驅動程式保持簡單,那麼緩慢可能對你來說並不重要。它可以稍後修復。
對於像磁碟這樣的裝置來說,這很重要,你不希望在 FREEZE 時停止旋轉。
- 問:
恢復後,系統正在大量分頁,導致非常糟糕的互動性。
- 答:
嘗試執行:
cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u | while read file do test -f "$file" && cat "$file" > /dev/null done
恢復後。swapoff -a; swapon -a 也可能有用。
- 問:
在 swsusp 期間裝置會發生什麼?它們似乎在系統掛起期間恢復了?
- 答:
沒錯。如果我們想將映像寫入磁碟,我們需要恢復它們。整個序列如下所示:
掛起部分
執行系統,使用者請求掛起至磁碟
使用者程序被停止
suspend(PMSG_FREEZE):裝置被凍結,以便它們不干擾狀態快照
狀態快照:在停用中斷的情況下獲取整個已用記憶體的副本
resume():裝置被喚醒,以便我們可以將映像寫入交換空間
將映像寫入交換空間
suspend(PMSG_SUSPEND):掛起裝置,以便我們可以關閉電源
關閉電源
恢復部分
(實際上非常相似)
執行系統,使用者請求掛起至磁碟
使用者程序被停止(在常見情況下沒有,但是透過從 initrd 恢復,沒有人知道)
從磁碟讀取映像
suspend(PMSG_FREEZE):裝置被凍結,以便它們不干擾映像恢復
映像恢復:使用映像重寫記憶體
resume():裝置被喚醒,以便系統可以繼續
解凍所有使用者程序
- 問:
“加密掛起映像”是做什麼用的?
- 答:
首先:它不能替代 dm-crypt 加密的交換空間。它無法在你的計算機掛起時保護它。相反,它可以防止在從掛起恢復後洩露敏感資料。
考慮以下情況:你在一個應用程式執行時掛起,該應用程式將敏感資料儲存在記憶體中。應用程式本身會阻止資料被交換出去。但是,掛起必須將這些資料寫入交換空間才能稍後恢復。如果沒有掛起加密,你的敏感資料將以純文字形式儲存在磁碟上。這意味著在恢復後,所有可以直接訪問用於掛起的交換裝置的應用程式都可以訪問你的敏感資料。如果你在恢復後不需要交換空間,這些資料幾乎可以永遠保留在磁碟上。因此,可能會發生你的系統在幾周後被入侵,並且你認為已加密和保護的敏感資料從交換裝置中被檢索和竊取。為了防止這種情況發生,你應該使用“加密掛起映像”。
在掛起期間,會建立一個臨時金鑰,並且該金鑰用於加密寫入磁碟的資料。當在恢復期間將資料讀回記憶體時,臨時金鑰會被銷燬,這僅僅意味著在掛起期間寫入磁碟的所有資料都無法訪問,因此無法被竊取。然後,你必須注意的唯一一件事是,在常規啟動期間儘早為用於掛起的交換分割槽呼叫“mkswap”。這可以確保從 oops 掛起或從失敗或中止的恢復中獲得的任何臨時金鑰都將從交換裝置中刪除。
根據經驗,使用加密的交換空間來保護你的資料,而你的系統處於關閉或掛起狀態。此外,使用加密的掛起映像來防止在恢復後竊取敏感資料。
- 問:
我可以掛起至交換檔案嗎?
- 答:
通常,是的,你可以。但是,它要求你使用“resume=”和“resume_offset=”核心命令列引數,因此無法從 initrd 或 initramfs 映像啟動從交換檔案恢復。有關詳細資訊,請參見 將交換檔案與軟體掛起 (swsusp) 一起使用。
- 問:
swsusp 支援的最大系統 RAM 大小是多少?
- 答:
它應該可以在 highmem 上正常工作。
- 問:
swsusp(掛起至磁碟)是否僅使用一個交換分割槽,還是可以使用多個交換分割槽(將它們聚合成一個邏輯空間)?
- 答:
僅一個交換分割槽,對不起。
- 問:
如果我的應用程式導致大量記憶體和交換空間被使用(超過系統總 RAM 的一半),那麼在應用程式執行時嘗試掛起至磁碟可能沒用,這是正確的嗎?
- 答:
不,它應該可以正常工作,只要你的應用程式不 mlock() 它。只需準備足夠大的交換分割槽。
- 問:
哪些資訊對於除錯掛起至磁碟問題很有用?
- 答:
嗯,螢幕上的最後訊息總是有用的。如果某些東西壞了,通常是某些核心驅動程式,因此嘗試儘可能少地載入模組會有很大幫助。我也喜歡人們從控制檯掛起,最好不要執行 X。使用 init=/bin/bash 啟動,然後 swapon 並手動啟動掛起序列通常可以解決問題。然後,嘗試使用最新的 vanilla 核心是個好主意。
- 問:
發行版如何使用模組化磁碟驅動程式(尤其是 SATA)釋出支援 swsusp 的核心?
- 答:
嗯,可以做到,載入驅動程式,然後從 initrd 回顯到 /sys/power/resume 檔案。確保不要掛載任何東西,甚至不要進行只讀掛載,否則你將丟失資料。
- 問:
如何使掛起更詳細?
- 答:
如果想在核心在掛起期間切換到的虛擬終端上看到任何非錯誤的核心訊息,則必須將核心控制檯日誌級別設定為至少 4 (KERN_WARNING),例如,透過執行:
# save the old loglevel read LOGLEVEL DUMMY < /proc/sys/kernel/printk # set the loglevel so we see the progress bar. # if the level is higher than needed, we leave it alone. if [ $LOGLEVEL -lt 5 ]; then echo 5 > /proc/sys/kernel/printk fi IMG_SZ=0 read IMG_SZ < /sys/power/image_size echo -n disk > /sys/power/state RET=$? # # the logic here is: # if image_size > 0 (without kernel support, IMG_SZ will be zero), # then try again with image_size set to zero. if [ $RET -ne 0 -a $IMG_SZ -ne 0 ]; then # try again with minimal image size echo 0 > /sys/power/image_size echo -n disk > /sys/power/state RET=$? fi # restore previous loglevel echo $LOGLEVEL > /proc/sys/kernel/printk exit $RET- 問:
如果我在 USB 裝置上掛載了檔案系統並且我掛起至磁碟,除非檔案系統已使用“sync”掛載,否則我可能會丟失資料,這是真的嗎?
- 答:
這是正確的...如果你斷開該裝置的連線,你可能會丟失資料。事實上,即使使用“-o sync”,如果你的程式在它們尚未寫入你斷開連線的磁碟的緩衝區中有資訊,或者如果你在裝置完成儲存你寫入的資料之前斷開連線,你也可能會丟失資料。
軟體掛起通常會關閉 USB 控制器的電源,這相當於斷開連線到你係統的所有 USB 裝置。
你的系統很可能支援在系統處於睡眠狀態時 USB 控制器的低功耗模式,從而使用真正的睡眠模式(如“掛起至 RAM”或“待機”)來維持連線。(不要將“disk”寫入 /sys/power/state 檔案;寫入“standby”或“mem”。)我們還沒有看到任何可以透過軟體掛起使用這些模式的硬體,儘管理論上某些系統可能支援不會破壞 USB 連線的“平臺”模式。
請記住,拔下包含已掛載檔案系統的磁碟驅動器始終是一個壞主意。即使你的系統處於睡眠狀態也是如此!最安全的方法是在掛起之前解除安裝可移動媒體上的所有檔案系統(例如 USB、Firewire、CompactFlash、MMC、外部 SATA 甚至 IDE 熱插拔托架);然後在恢復後重新掛載它們。
有一個解決此問題的方法。有關更多資訊,請參見 系統掛起期間的 USB 裝置永續性。
- 問:
我可以使用 LVM 下的交換分割槽掛起至磁碟嗎?
- 答:
是也不是。你可以成功掛起,但是核心將無法自行恢復。你需要一個可以識別恢復情況的 initramfs,啟用包含交換卷的邏輯卷(但不接觸任何檔案系統!),並最終呼叫
echo -n "$major:$minor" > /sys/power/resume
其中 $major 和 $minor 分別是交換卷的主裝置號和次裝置號。
uswsusp 也可以與 LVM 一起使用。請參閱 http://suspend.sourceforge.net/
- 問:
我將核心從 2.6.15 升級到 2.6.16。兩個核心都是使用類似的配置檔案編譯的。無論如何,我發現與 2.6.15 相比,在 2.6.16 上掛起至磁碟(和恢復)要慢得多。有什麼原因或我如何加快它的速度嗎?
- 答:
這是因為掛起映像的大小現在大於 2.6.15(透過儲存更多資料,我們可以在恢復後獲得更快的系統響應)。
有一個 /sys/power/image_size knob 控制映像的大小。如果將其設定為 0(例如,透過以 root 身份執行 echo 0 > /sys/power/image_size),則應恢復 2.6.15 的行為。如果仍然太慢,請檢視 suspend.sf.net -- 使用者空間掛起速度更快,並支援 LZF 壓縮以進一步加快速度。