2013年10月30日 星期三

[Linux] 監控記憶體使用量,以 python 為例 @ Ubuntu 12.04

監控方式就...去翻 /proc/pid/status 來看

粗略測試方式:
  • 寫一隻程式,最後一行跑 loop 讓程式不會結束,或是讀 io卡住也行
  • 用 ps 得知此程式 pid,接著翻 /proc/pid/status 出來
例如我想知道 python 記憶體使用上會不會 copy by reference 或 copy by reference,那就重複把某個 string data 設值給別人看看,最後用一個 loop 卡住,讓程式不會結束,接著就用 ps aux | grep 'test.py' 去找出來 PID ,再去 cat /proc/PID/status 出來。

test.py:

import time

data = open('tmp').read()
i = 1000
co = []
while i > 0 :
        #co.append(str(data)+"1")
        #co.append(str(data)+"")
        co.append(str(data))
        i -= 1
print "Done:", len(co)
while True:
        time.sleep(1)


連續動作:

$ ps aux | grep test.py | grep -v "grep\|vim" | awk '{system("cat /proc/"$2"/status");}' | grep -i "pid\|vm\|name"

當 co.append(str(data)) 跟 co.append(str(data)+"") 時,i 數值變大對記憶體增加不多:

Name:   python
Pid:    12180
PPid:   11910
TracerPid:      0
VmPeak:    32532 kB
VmSize:    32532 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      5676 kB
VmRSS:      5676 kB
VmData:     2700 kB
VmStk:       136 kB
VmExe:      2496 kB
VmLib:      5240 kB
VmPTE:        72 kB
VmSwap:        0 kB


但 co.append(str(data)+" ") 時,i 數值變大對記憶體就開始噴了:

Name:   python
Pid:    12189
PPid:   11910
TracerPid:      0
VmPeak:   340532 kB
VmSize:   340532 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    313496 kB
VmRSS:    313496 kB
VmData:   310700 kB
VmStk:       136 kB
VmExe:      2496 kB
VmLib:      5240 kB
VmPTE:       680 kB
VmSwap:        0 kB

2013年10月26日 星期六

[Linux] 研究 c-icap modules 與 Squid 相關設定 @ Ubuntu 12.04

前鎮子剛用 pyicap 完成簡單的 ICAP 實作,但 pyicap 還是有一點不順,所以就來試試 c-icap 吧!盡管在 wikipeida 上查閱了幾種 icap server 的實作,但不少已經說不繼續維護,然後就叫大家去看 c-icap 啦,再加上 c-icap 也可以在 apt-get 上方便取得,所以,就來摸摸 so 吧!(據說中國那邊還很盛行,ISP還是會幫忙把網頁加上自家廣告)

先聊一下 c-icap 的部分,它是一隻用 C 實作 ICAP server 的角色,而 Squid 本身就內建 ICAP client 的角色了。使用 c-icap 的理由,則是他提供模組的方式,將你想做的事寫成 module ,設定後可變成 c-icap 的一個 service ,僅需依照 c-icap 的框架實作必要的函式,可省去實作 ICAP 協定。

此篇記錄著重在如何實作 c-icap module ,而網路資料不多,最佳解就是看程式碼 :P

$ apt-get source c-icap libc-icap-mod-urlcheck

此過程會產生兩個目錄:c-icap-0.1.6 和 c-icap-modules-0.1.6,其中 c-icap-modules-0.1.6 環境可以專門拿來編 c-icap modules,但其實最簡單的 c-icap-module 是在 c-icap-0.1.6/services/echo/srv_echo.c,如其名,echo 這只是個範例,但註解非常豐富,看他就夠啦。

其中比較特別的,就是查看 c-icap-module 框架,請參考這段:

CI_DECLARE_MOD_DATA ci_service_module_t service =
{
"echo", /* mod_name, The module name */
"Echo demo service", /* mod_short_descr,  Module short description */
ICAP_RESPMOD | ICAP_REQMOD, /* mod_type, The service type is responce or request modification */
echo_init_service, /* mod_init_service. Service initialization */
NULL, /* post_init_service. Service initialization after c-icap configured. Not used here */                                            
echo_close_service, /* mod_close_service. Called when service shutdowns. */
echo_init_request_data, /* mod_init_request_data */
echo_release_request_data, /* mod_release_request_data */
echo_check_preview_handler, /* mod_check_preview_handler */
echo_end_of_data_handler, /* mod_end_of_data_handler */
echo_io, /* mod_service_io */
NULL,
NULL
};


各項簡介:
  • 此 c-icap module service 啓動與關閉:echo_init_service, echo_close_service
  • 當 request 進來:echo_init_request_data
  • 取得 request preview:echo_check_preview_handler
  • 當 request 處理中:echo_io
  • 當 request 處理完:echo_release_request_data

舉個例來說,如果要用 PCRE 去做處理,一開始要初始化 PCRE 的項目可以擺在 echo_init_service ,而釋放 PCRE 的資源可以擺在 echo_close_service,而每次處理 request 前需要初始化資源則擺在 echo_init_request_data,釋放在 echo_release_request_data。

至於更深的應用就要去 c-icap-modules-0.1.6/service 翻 clamav 和 url_check,這兩項都跟資安相關,前者是掃毒軟體,後者則是可以拿來過濾惡意網站。有興趣可以翻一輪,比較特別的是處理 request 進來的資料,有用到 ci_simple_file_* 和 ci_membuf_* 系列的函式庫,簡言之就是記憶體擺不下就放檔案,或是有些函式只支援掃檔,那就先擺在檔案去進行。這邊便就不多講了。

設定 c-icap:

$ sudo cp output/changyy.so /usr/lib/c_icap/
$ sudo vim /etc/c-icap/c-icap.conf
Service changyy changyy.so
$ sudo /etc/init.d/c-icap restart


設定 squid:

icap_enable on
icap_send_client_ip on
icap_send_client_username on
icap_client_username_encode off
icap_client_username_header X-Authenticated-User
icap_preview_enable on
icap_preview_size 1024

icap_service service_req reqmod_precache bypass=1 icap://localhost:1344/changyy
adaptation_access service_req allow all
icap_service service_resp respmod_precache bypass=1 icap://localhost:1344/changyy
adaptation_access service_resp allow all


其中 icap://localhost:1344/changyy 在此的意義就是 c-icap 中的 Service changyy 啦,最後一提的是 c-icap.conf 有 DebugLevel ,這個數字攸關 debug 訊息,在 c-icap-modules 中許多實作都會用 ci_debug_printf 來印訊息,其中第一個數字若小於等於 DebugLevel 才會被印出來。而輸出的 log 可以在 /var/log/c-icap/server.log 查到。

2013年10月24日 星期四

[OSX] 製作 Mac OS X Mavericks USB 安裝碟 @ Mac 10.9

既然 Mac OS X Mavericks 已經大方到變成免費了!那製作 USB 安裝碟也是必要的技能啊

首先,在先從 App Store 下載 OS X Mavericks 安裝程式,下載完時,先不要去安裝他,可以用以下指令製作 USB 安裝碟,此處假設隨身碟是在 /Volumns/8GB:

$ sudo /Applications/Install\ OS\ X\ Mavericks.app/Contents/Resources/createinstallmedia --volume /Volumes/8GB --applicationpath /Applications/Install\ OS\ X\ Mavericks.app --nointeraction

如此一來就完成啦。

2013年10月23日 星期三

[OSX] 使用 Command line 啓動 VNC 和設定連線密碼 @ Mac OSX 10.8

如果說,都用 Mac OS X 遠端 Mac OS X,那的確不太需要設定 VNC 密碼,因為會轉換到 Mac OS X 自己的協定,但如果是從 Windows/Linux 連到 Mac OS X 的話,設定密碼還是安全一點點。

啓動 VNC:

$ sudo defaults write /var/db/launchd.db/com.apple.launchd/overrides.plist com.apple.screensharing -dict Disabled -bool false
$ sudo launchctl load /System/Library/LaunchDaemons/com.apple.screensharing.plist


設定 VNC 密碼:

$ sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -off -restart -agent -privs -all -allowAccessFor -allUsers -clientopts -setvncpw -vncpw VNC_PASSWORD
Starting...
bind(): Address already in use
com.apple.screensharing: Already loaded
Activated Remote Management.
Stopped ARD Agent.
Stopped VNC Privilege Proxy
buffalo: Set user remote access.
macports: Set user remote access.
ookon: Set user remote access.
Set the client options.
Setting allow all users to YES.
Setting all users privileges to ##########.
Done.

[Linux] 使用 virsh 建立 snapshot (管理KVM) @ Ubuntu 12.04

繼上一篇 [Linux] 安裝 Kernel Virtual Machine (KVM) 與純文字操作 後,接著是想著該如何使用 virsh 指令管理 VM,如建立 snapshot 、恢復等。

$ virsh list --all
 Id Name                 State
----------------------------------
  1 vmlinux               running

$ virsh snapshot-list vmlinux
 Name                 Creation Time             State
------------------------------------------------------------


接著嘗試建立 snapshot:

$ sudo virsh snapshot-create vmlinux
error: Requested operation is not valid: Disk '/var/lib/libvirt/images/vmlinux.img' does not support snapshotting

發現目前的格式不支援,接著登入 vmlinux 把機器關掉,進行格式轉換並且更新原本 VM 的敘述檔:

$ sudo qemu-img convert -f raw -O qcow2 /var/lib/libvirt/images/vmmail.img /var/lib/libvirt/images/vmmail.qcow2

$ virsh dumpxml vmlinux
...
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/vmlinux.img'/>
...
$ sudo virsh edit vmlinux
...
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vmlinux.qcow2'/>
...


重新啟動VM:

$ sudo virsh start vmlinux
$ virsh list --all
 Id Name                 State
----------------------------------
  1 vmlinux               running


建立 snapshot:

$ sudo virsh snapshot-create vmlinux
Domain snapshot 1382549415 created

$ virsh snapshot-list vmlinux
 Name                 Creation Time             State
------------------------------------------------------------
 1382549415           2013-10-23 20:30:15 +0800 running


指定回復:

$ sudo virsh snapshot-revert vmlinux
error: --snapshotname or --current is required

$ sudo virsh snapshot-revert vmlinux --snapshotname 1382549415
$ virsh list --all
 Id Name                 State
----------------------------------
  1 vmlinux               running


上述操作過程中,沒有把 VM 關掉,唯一的差別是連到 VM 的 putty 斷線了而已,也算挺方便的。