Suspend 與 Hibernate 的差別#
Suspend(睡眠)
- 暫停所有程序,並用微量電流維持記憶體中的程序狀態。
- 當喚醒時,接續先前的程序狀態繼續運作。
Hibernate(休眠)
- 與 suspend 類似,暫停所有程序,但轉而將程序狀態從記憶體傾印到硬碟上儲存,並將電腦關機。
- 當喚醒時,電腦先進行正常開機,然後偵測到先前有程序狀態被記錄在硬碟中,將硬碟中的狀態再傾印回記憶體中作為程序繼續運作。
兩者都可以做到接續先前程序狀態繼續運作,但 suspend 比 hibernate 更耗電,但喚醒速度也更快。
確認 SWAP 大小#
以上述的原理來說,要實現 hibernate 就必須要有個硬碟區塊用於存放記憶體的工作狀態,而這塊區塊通常就是 linux 底下的 SWAP 分區。
首先檢查 SWAP 大小,建議大於 RAM 1.5 倍以上:
1free -h
萬一大 SWAP 小小於 RAM 的話,就必須要先擴增。
(視情況)調整 SWAP 大小#
擴增的方式有分兩種常見情況(分區、檔案),這需要一照你的 SWAP 的格式來決定。
分區#
若你的 SWAP 是一般的分區管理,則同一般分區一樣,可以先用指令lsblk
找出分區名稱,然後透過以下指令先關閉 SWAP 運作:
1sudo swapoff -a
接著就可以調整分區大小了。
LVM 管理
:如果你是使用 LVM 管理分區的話,那麼可以參考我以前寫的教學「LVM 邏輯卷管理(Logical Volume Manager)」中關於「擴增 LV」的章節。
檔案#
若是以檔案方式管理 SWAP,則先透過以下指令關閉 SWAP 運作:
1sudo swapoff /swapfile
p.s. 上述的/swapfile
請自行換成你的 SWAP 檔案位置。(以下範例亦是如此,將不再贅述)
接著刪除舊檔案:
1sudo rm /swapfile
建立新檔案:
(以 8 GB 為例,以下8192
為8 GB
對應的MB 單位
(1 GB = 1024 MB),具體情況請依照你的 RAM 大小而定)
1sudo dd if=/dev/zero of=/swapfile bs=1M count=8192 status=progress
設定權限:
1sudo chmod 600 /swapfile
建立 SWAP 格式:
1sudo mkswap /swapfile
啟用 SWAP:
1sudo swapon /swapfile
查看:
1swapon --show
p.s. 如果還沒有在/etc/fstab
寫入 SWAP 的話則需要更新,若已經有的話則不需要更動。
設定 GRUB#
分區#
如果是分區則直接將 SWAP 分區的 UUID 設定到 GRUB 即可。
編輯/etc/default/grub
,將GRUB_CMDLINE_LINUX_DEFAULT
寫成以下格式:
1GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=abcd-1234-ef56-7890"
p.s. 該 UUID 記得換成你自己的 SWAP 分區。你可以透過指令blkid /dev/<分區>
來查詢 UUID,例如blkid /dev/sda2
。
檔案#
與分區大同小異,只不過需要多設定一個offset
。
可以透過以下指令來計算 offset:
1filefrag -v /swapfile | grep " 0:"
會得到一個類似這樣的回應:
1 0: 0.. 2047: 92086272.. 92088319: 2048:
以上述例子來說,92086272
便是 offset。
接著編輯/etc/default/grub
,將GRUB_CMDLINE_LINUX_DEFAULT
寫成以下格式:
1GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=abcd-1234-ef56-7890 resume_offset=92086272"
p.s. 一樣記得 UUID 跟 offset 要改成你自己的。
更新 GRUB#
更改完畢後記得更新:
1sudo update-grub
2sudo update-initramfs -u
重新開機並測試 hibernate 功能#
在重新啟動後,可以輸入指令:
1systemctl hibernate
接著電腦應該要看起來很像關機,沒有任何一點動靜,接著按下開機鍵就能喚醒休眠。
未知的原因而無法執行休眠,替代方案#
這是我自己遇到的狀況,當輸入休眠的指令時,出現以下錯誤:
1Failed to hibernate system via logind: Not enough swap space for hibernation
及便 SWAP 大小已經確定足夠,但仍然顯示這樣的訊息。
而我的替代方案是用一種比較直接的作法:
1echo disk | sudo tee /sys/power/state
這樣可以直接向 Linux 的電源管理介面輸入"disk"作為休眠的訊號。
至於為什麼…
問題應該出在systemd logind
本身的限制,可以用指令嘗試忽略限制:
1sudo loginctl lock-session
2sudo systemctl hibernate --force
或者檢查/etc/systemd/logind.conf
是否有設定:
1HandleHibernateKey=hibernate
2HibernateMode=platform
編輯後重啟:
1sudo systemctl restart systemd-logind
但,以上方是對我的情況無效,有興趣的朋友可以自行深入研究。
References#
- 《What is the difference between Hibernate and Suspend - Ask Ubuntu》https://askubuntu.com/questions/3369/what-is-the-difference-between-hibernate-and-suspend
- 《Linux 核心設計: Power Management(3): 測試工具 - HackMD》https://hackmd.io/@RinHizakura/rkhIzLcjT