延續上一篇“電源管理—Linux下的ACPI”,這次談談更深入的Linux Hibernate的作法。Linux在許多使用上,其實都已經做到Desktop所需要的功能,像我所要介紹的Hibernate功能就是其中之一。
從上圖中可以發現,Hibernate和關機的差異是非常大的,可以說是完全不一樣的事情,在一般看得到的書中,Hibernate就是一般我們在ACPI中所謂的G1S4。
G1指得是“Sleeping”,也就是睡眠狀態,一般會用到G1的情況有兩種,Standby或Hibernate,分別為G1S3與G1S4,這兩種的差異主要在於Suspend to RAM(STR)及Suspend to Disk(STD)。
因此S4指得則是第四個階段,也就是Suspend to Disk(STD),所以G1S4整體的意思就是讓系統睡得程度到“Hibernate”階段。之前使用者較常會用到的應該是S3,因此電源都無法完全關掉,會有些許的電源用來供應記憶體,但S4則可以做到將電源完全關掉,而保留住系統目前的狀態。
但Hibernate的動作在Linux中是如何達到,以及到底做了哪些事情,當Hibernate進行時又是參考哪些檔案,是這篇文章中要介紹給各位的。
1. Hibernate所參考的檔案
Hibernate所參考檔案都是由pm-utils套件所提供的,pm-utils是一套電源管理的工具軟體,在2.6的kernel之後,都已經支援ACPI的功能,所以可以做到像Hibernate的省電模式,但這些動作在啟動時,若還有硬體(像USB設備)在系統上該如何處理,就可以透過pm-utils來做一些關閉硬體的動作,但其實pm-utils是透過一個『HAL』的服務程式(在Redhat中此服務的檔案名稱為haldaemon)在控制,所以一般看不到pm的字眼。不過雖然是透過HAL在操作,但使用者一樣可以加一些自己的動作在其中,做細部的調整。
基本上pm-utils除了【/etc/pm】這一個目錄外,【/usr/lib/pm-utils】也是主要的目錄之一,其實如果細看【/etc/pm】,裡面是空無一物,因為這是預留給使用者自行使用的地方,系統真正在執行的,是在【/usr/lib/pm-utils】底下的檔案,不過【/etc/pm】是可以使用的,只是檔案要自行產生。
在【/usr/lib/pm-utils】下,最好用的目錄就要屬sleep.d這一個(如下圖所示),因為當使用者在進行Hibernate(休眠模式)時,就會依據這目錄中的檔名前兩碼數字的大小(由小到大),依序進行執行的動作(正常應該說是關閉的動作,但因為可以自行設定,不在這邊定義為關閉);相同的,在【/etc/pm】的目錄下,也有和這邊類似的目錄,只是都是空的,這在上面有提過。不過這邊有幾點是要特別注意的:
a. 系統在進行Hibernate時,是先執行【/etc/pm】的目錄,再執行【/usr/lib/pm-utils】目錄中的檔案;但啟動是相反的,會先執行【/usr/lib/pm-utils】後,再執行【/etc/pm】目錄下的檔案。
b. 系統在進行Hibernate時,會從目錄中檔名的前兩碼數字由小到大進行執行動作;但再開機時,是相反的,也就是會由數字大到小執行。
這兩點要注意的原因,主要是一般預設立場是要進行關閉的動作,所以往往會忽略開機時是要進行啟動,剛好目的是相反的,自然順序也就跟著變動,在細節的設計上要特別注意。
2. Hibernate所進行的方式
最簡單要進行Hibernate的方式,就是在X Window關機時,不要用原本關機的選項,而改用『Hibernate』的方式(如下圖所示),只要點選下去,系統就會自動進行Hibernate,但要注意,若系統中的“haldaemon”沒有啟動,是不會有這選項的。
如果需要比較進階的使用,就必需要參考到/sys/power目錄,該目錄是主要Hibernate在進行時的“開關”,這一個目錄只存放和電源模式有關的檔案,更正確的說法,是只有電源管理機制的檔案。裡面只有幾個屬性檔案在其中,屬性名稱(也就是檔案名稱)及其值都請參考下圖
每個屬性的意義介紹如下:
1. disk:當使用者在做休眠模式中S4的STD(suspend to disk,或稱為Hibernate)時,要將系統的狀況寫入到硬碟中,因此這邊是在定義當狀態寫入到硬碟後,“系統”該如何運作。基本上目前2.6的kernel支援以下五種模式:
a. platform:不知其運作方式,但只有在該平台有支援時才可使用。
b. shutdown:當進入休眠時進入關機狀態。
c. reboot:當進入休眠時進入重新開機狀態。
d. testproc:testproc與下一個test,這兩者的模式比較特別,都是屬於即時測試休眠功能所可可以使用的狀態,也就是可以讓使用者進入模擬的休眠模式,再自動回複到原本的系統狀態,所以一直都在原本的使用狀態下。
testproc主要有以下幾個步驟(系統訊息如下圖所示):
關閉未使用的CPU 凍結所有的工作 等五秒鐘 將原本的工作還原 打開原本未啟動的CPU
e. test:和前一個testproc的不同,是在測試時更完整,連記憶體和硬體設備的部份也加入模擬的階段。
test主要有以下幾個步驟(系統訊息如下圖所示):
關閉未使用的CPU 凍結所有的工作 壓縮記憶體 關閉設備 等五秒鐘 恢復設備的狀態 將原本的工作還原 打開原本未啟動的CPU
這五種中最常被使用的就是“shutdown”(a不知其作用為何,但一定要系統有支援才可使用),後三者(“reboot”、“testproc”、“test”)則較少為人知,因為這三種大部份是在測試單位(可能也只在專門測試休眠功能的單位)才有機會被使用到,不然使用的機會少之又少,但實在是一個造福測試者的功能。不過使用上真的很簡單,如筆者電腦的“disk”檔案預設設定為“shutdown”,如果更改為“reboot”,當休眠完成後,將不會關機,而是“重開”。
所以想當然,誰會在做休眠時的下一步要“重新開機”,這樣完全無法省電,所比這一個機制其實是還是為了測試休眠模式所定義的,只是可能會將測試的範圍擴大到整個系統的流程,而不是像“testproc”和“test”僅限於測試休眠的部份功能,畢竟完整的動作是包含關機與開機。
2. image_size:目前系統可接受的最大image大小,預設為512MB。
3. pm_trace:這是一個控制開關,可比決定是否要記錄在多次的重新開機後,最後一次存在RTC中的事件點,預設值為“0”,代表不記錄,若改為“1”,則可進行記錄的動作。
4. resume:當系統進行S4(suspend to disk)時,系統要將系統狀態寫入的位置。所以這屬性其實是代表某一個分割區的major及minor ID(一般都是SWAP分割區),若需要使用resume分割區,就必須在開機時先在GRUB的開機參數中,加入resume=/dev/xxxx的參數,才可以讓系統知道要使用該分割區當寫入的分割區。在下圖中的resume值之所以為“0:0”,是因為主機中沒有設定該參數(SuSE在預設就會加入該參數)。
5. state:目前系統可支援的休眠模式,一般只會有以下三種(或只有其中一兩種)狀態(S2一般電腦都不會支援):
a. standby:就是一般所謂的S1,S1是在睡眠狀態中最吃電的一種狀態,CPU中的cache都持續供電,但停止執行指令。在CPU及記憶體的部份都有電力在供應,但其他的裝置就沒有硬性規定,可斷電也可供電。
b. mem:就是S3(suspend to ram),在此狀態下,只有主記憶體有接受供電的權利。但值得注意的是,雖然大部份的資料都會回寫到記憶體,但硬碟本身的Buffer有可能來不及回寫到硬碟,這樣就會造成資料流失。
c. disk:就是S4(suspend to disk),俗稱休眠狀態(Hibernet,或稱冬眠狀態),其技術上的名稱則為Suspend to Disk (STD),這一階段會將所有執行中的資料全部寫入到硬碟中,而之所以要寫入硬碟,就是因為要完全的斷電,但也因為如此,在回覆到原本工作狀態所使用的時間會比S3來得久。
更簡單的說,其實如果將“state”檔案以“disk”值寫入(如:【echo “disk” > /sys/power/state】),這動作等於切換“state”開關至“disk”選項,因此系統就會直接進入休眠,並且將休眠模式認定為前面我們提過的“disk”檔案中所記載的方式,像“shutdown”。