According to below link.
http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1332851,00.html
星期六, 10月 04, 2008
星期三, 9月 10, 2008
Linux下的Hibernate(Suspend to Disk) – ACPI定義的睡眠模式之一
延續上一篇“電源管理—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”。
從上圖中可以發現,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”。
星期五, 8月 29, 2008
第二本書完成了 -- Linux系統架構與目錄之解析
http://www.delightpress.com.tw/book.aspx?book_id=SKNS00002
這本書寫了大概快一年的時間, 一開始寫這本書主要的目的, 是為了讓Linux的使用者, 當操作時遇到問題或是卡在某一些檔案無法進行或運作下去, 卻無法知道這些目錄或檔案的作用為何時, 可以用來查詢的一本實用工具書, 當然也是因為市面上一直找不到類似的書, 所以只好自己寫一本, 雖然花了很多時間, 但看到成品出來, 還是很值得的.
只是這本書, 怕會有一些爭議, 畢竟每一個版本的Linux多少會有不同的地方, 因為我個人覺得大多數初學者應該都會以Redhat的系統為一開始的作業系統, 所以就以Fedora為整本書的範例, 實在沒辦法顧到每一個版本, 但主要的幾個常用目錄, 像設定檔/etc, VFS /proc, /sys, /dev等等, 這些相當重要的目錄就不會是哪一個Linux版本, 一定都是一致的, 所以對真正核心的重要性, 我想是一樣的, 只怕慣用不同版本的讀者, 會不習慣裡面的某些目錄檔案.
其實有了出書的經驗, 會知道讀者的反應是真得很重要的, 因為不然根本無法得知自己寫出來的成品, 是不是讓大家真的有所收穫, 畢竟在台灣寫這些資訊相關的"店頭書", 說真的是沒啥賺頭的, 除非像鳥哥知名度大開的, 應該就可以賺個好幾翻, 不然像我這樣, 大概也只是做一些讓自己開心, 可以留做回憶的事情, 再來就是可以吃幾頓大餐...所以重點...真的是在讀者的反應, 第一本書"Linux作業系統之奧義"讓我知道有用心是會有回報的(可不是$$唷, 雖然是有一些些啦...^^), 現在也在等看看, 看第二本是不是也可以讓我看到一些讀者的反應, 又要緊張幾個星期囉.
這本書寫了大概快一年的時間, 一開始寫這本書主要的目的, 是為了讓Linux的使用者, 當操作時遇到問題或是卡在某一些檔案無法進行或運作下去, 卻無法知道這些目錄或檔案的作用為何時, 可以用來查詢的一本實用工具書, 當然也是因為市面上一直找不到類似的書, 所以只好自己寫一本, 雖然花了很多時間, 但看到成品出來, 還是很值得的.
只是這本書, 怕會有一些爭議, 畢竟每一個版本的Linux多少會有不同的地方, 因為我個人覺得大多數初學者應該都會以Redhat的系統為一開始的作業系統, 所以就以Fedora為整本書的範例, 實在沒辦法顧到每一個版本, 但主要的幾個常用目錄, 像設定檔/etc, VFS /proc, /sys, /dev等等, 這些相當重要的目錄就不會是哪一個Linux版本, 一定都是一致的, 所以對真正核心的重要性, 我想是一樣的, 只怕慣用不同版本的讀者, 會不習慣裡面的某些目錄檔案.
其實有了出書的經驗, 會知道讀者的反應是真得很重要的, 因為不然根本無法得知自己寫出來的成品, 是不是讓大家真的有所收穫, 畢竟在台灣寫這些資訊相關的"店頭書", 說真的是沒啥賺頭的, 除非像鳥哥知名度大開的, 應該就可以賺個好幾翻, 不然像我這樣, 大概也只是做一些讓自己開心, 可以留做回憶的事情, 再來就是可以吃幾頓大餐...所以重點...真的是在讀者的反應, 第一本書"Linux作業系統之奧義"讓我知道有用心是會有回報的(可不是$$唷, 雖然是有一些些啦...^^), 現在也在等看看, 看第二本是不是也可以讓我看到一些讀者的反應, 又要緊張幾個星期囉.
星期四, 5月 08, 2008
點(dot) (.)對目錄及shell scirpt的意義
###目錄中###
cd . 代表進入"目前這目錄"
###script file中###
. /etc/init.d/functions 代表在"同一個shell"中執行
這意思是, 原本
shell                                                                                           --> shell
           --> sub shell --> functions --> kill sub shell
變為
shell --> functions --> shell
差別在於所有執行後的變數及結果都會留在原本的shell中
在functions檔案中有一些函式, 像pidofproc() (系統原本只有pidof程式)
原本無法執行, 經過". /etc/init.d/functions"就變為區域變數, 就可以執行了
可以用"setgrep pidofproc", 看到所有functions留在shell中的資訊
當然在登出後或其他shell中是沒有的
cd . 代表進入"目前這目錄"
###script file中###
. /etc/init.d/functions 代表在"同一個shell"中執行
這意思是, 原本
shell                                                                                           --> shell
           --> sub shell --> functions --> kill sub shell
變為
shell --> functions --> shell
差別在於所有執行後的變數及結果都會留在原本的shell中
在functions檔案中有一些函式, 像pidofproc() (系統原本只有pidof程式)
原本無法執行, 經過". /etc/init.d/functions"就變為區域變數, 就可以執行了
可以用"setgrep pidofproc", 看到所有functions留在shell中的資訊
當然在登出後或其他shell中是沒有的
socket與協定的觀念 - 以nc與http為例
port這東西有時候好像很難解釋, 但如果透過實際的操作就很好理解
先在該台主機上要產生一個192.1.1.1:1111的門,也就是socket, 讓大家可以連線
nc -l 192.1.1.1 1111
可以在另一台主機上使用
telnet 192.1.1.1 1111
這樣就可以雙方進行對話
因此協定的目的, 就在讓雙方可以透過socket進行"對話", 對話的規範就叫協定
像Web Server, 其實是可以透過telnet的方式將網頁抓回來
只是要知道HTTP協定的對話模式, 以及對方應有的網頁檔名
簡單的可以用下面的範例
telnet 192.1.1.1 80
進入後再輸入
GET /index.html
就可以看到index.html的內容
先在該台主機上要產生一個192.1.1.1:1111的門,也就是socket, 讓大家可以連線
nc -l 192.1.1.1 1111
可以在另一台主機上使用
telnet 192.1.1.1 1111
這樣就可以雙方進行對話
因此協定的目的, 就在讓雙方可以透過socket進行"對話", 對話的規範就叫協定
像Web Server, 其實是可以透過telnet的方式將網頁抓回來
只是要知道HTTP協定的對話模式, 以及對方應有的網頁檔名
簡單的可以用下面的範例
telnet 192.1.1.1 80
進入後再輸入
GET /index.html
就可以看到index.html的內容
星期一, 5月 05, 2008
一些shell script的小技巧
Shell script真的是蠻好用的, 一行字就可以做很多的事情, 這邊舉一些常用的當例子:
1.
for i in filename*; do echo "123" > $i;done
假設要修改的是stu開頭的檔案, 這樣每一個檔案的內容都會變成123
2.
while [ 1 ]; do echo "1" ; done
會不間斷的列印"1"這字串, 這方式可以將single core的CPU操到100%的使用率, 若是multi core的, 就多跑幾個吧.
3.
萬用字元與正規表示法的差異
grep ^[^#] filename
代表要尋找 "非" # "開頭" 的內容
^ 開頭
$ 尾巴
[^#] 非#開頭的
[] 裡面代表的只有一個字元
所以在使用grep時要注意, 因為grep所接的字串是使用正規表示法
grep a..ther filename
正規表示法和萬用字元的差異
.代表單一字元....
*代表a或多個a
.*代表0或多個任意字元
1.
for i in filename*; do echo "123" > $i;done
假設要修改的是stu開頭的檔案, 這樣每一個檔案的內容都會變成123
2.
while [ 1 ]; do echo "1" ; done
會不間斷的列印"1"這字串, 這方式可以將single core的CPU操到100%的使用率, 若是multi core的, 就多跑幾個吧.
3.
萬用字元與正規表示法的差異
grep ^[^#] filename
代表要尋找 "非" # "開頭" 的內容
^ 開頭
$ 尾巴
[^#] 非#開頭的
[] 裡面代表的只有一個字元
所以在使用grep時要注意, 因為grep所接的字串是使用正規表示法
grep a..ther filename
正規表示法和萬用字元的差異
.代表單一字元....
*代表a或多個a
.*代表0或多個任意字元
星期五, 3月 14, 2008
一本書把自己用瘋了
在煩的時候也已經想過Linux的領域有哪些應該要有人跳出來, 卻遲遲沒有人要做的事情, 其實也不知道是沒人寫還是大家都不想做這些事, 反正看起來我的能力還可以幫很多人整理出一些頭緒, 就繼續完成.
只是經過這兩本書, 我肯定的說, 要完成一本從無到有的書(自己想出的題材), 除了理想還是理想, 要是沒了這動力, 大概也不會想寫下去吧.
訂閱:
文章 (Atom)