2014年8月14日 星期四

活用從 userspace 發送 signal 的技巧

在 Linux 核心運作的方式中,有採用到所謂「 signal 」的方式。大體上來說,這種機制就是直接針對一個程序或是很多程序,發送一個信號,而所有具有傾聽信號能力的程序,會回應某些信號,而做出某些行為。

所謂 user space ,指的是 Linux 架構下,分類程序性質的觀點之一。這個詞是相對於 kernel space 去稱呼的。一個不嚴謹的說法,可以概略地陳述為:「 user space 的程序是使用者可以直接觸及、更動、修改的,而 kernel space 則否。kernel space 的程序控制權完全掌握在核心程序本身。」

以下是 signal 在 user space 的應用的一個例子:

有的時候我們想要把自己使用過的硬碟給他人使用,但是又不希望對方有機會回復並取得自己曾經留在這顆硬碟上的資料。下面這個指令是一個常見的銷毀硬碟資料的作法:

dd if=/dev/zero of=/dev/sdX bs=1M

其中 sdX 表示硬碟裝置編號,依照實際情況可以是 sda 、 sdb 、 sdc ......etc. 。這個指令的意思就是指請把空的資料寫滿整個硬碟裝置 sdX ,並且一次寫入 1Mb 的大小。一次要寫入多少大小的 size 則 case by case ,這個參數的最佳化依照不同的環境有不同的值。

dd 這個指令本身在完成工作的時候才會回報結果統計,在這之前都是「默默地」做事。可是現代的硬碟動輒數百 Gb 或甚至是數T,依照電腦效能,藉由上面的指令,有時候需要花上數十分鐘甚至數小時來抹除資料。有些使用者可能會想問:「有沒有可能請 dd 工作到一半的時候,請 dd 回報他的工作進度?」答案是:可以。

dd 這支程式有能力傾聽 signal ,並且會對 USR1 這個 signal 做出反應,因而回報進度。 dd 的使用手冊中提到:

$ man dd

......

       Sending a USR1 signal to a running 'dd' process makes it print I/O sta‐

       tistics to standard error and then resume copying.



              $ dd if=/dev/zero of=/dev/null& pid=$!

              $ kill -USR1 $pid; sleep 1; kill $pid



              18335302+0  records  in  18335302+0 records out 9387674624 bytes

              (9.4 GB) copied, 34.6279 seconds, 271 MB/s


仿照手冊中的例子,我們採用下面的指令來請 dd 回報進度:

sudo kill -USR1 `pgrep ^dd`


延伸閱讀:
http://askubuntu.com/questions/215505/how-do-you-monitor-the-progress-of-dd