2010/05/03

vmci error on VMware Tools install on Ubuntu 10.04 (Linux 2.6.32) / ESXi 4

Reference: VMware Communities: Can't install latest VMware Server 2.0.2 on 2.6.32.8

Problem


升級 Ubuntu 10.04 LTS (內核 2.6.32) 後嘗試重新編譯 VMware Tools 卻發生如下的問題:
When OS kernel upgrade into Linux 2.6.32 (like Ubuntu 10.04 LTS), compiling VMware Tools will occur some problems like the below:

CC [M] /tmp/vmware-config1/vmci-only/vmciQueuePair.o
In file included from /tmp/vmware-config1/vmci-only/vmci_queue_pair.h:36,
from /tmp/vmware-config1/vmci-only/vmciQueuePair.c:36:
/tmp/vmware-config1/vmci-only/vm_atomic.h:996:7: warning: "_MSC_VER" is not defined
/tmp/vmware-config1/vmci-only/vm_atomic.h:1081:7: warning: "_MSC_VER" is not defined
In file included from /tmp/vmware-config1/vmci-only/vmci_queue_pair.h:36,
from /tmp/vmware-config1/vmci-only/vmciQueuePair.c:36:
/tmp/vmware-config1/vmci-only/vm_atomic.h:996:7: warning: "_MSC_VER" is not defined
/tmp/vmware-config1/vmci-only/vm_atomic.h:1081:7: warning: "_MSC_VER" is not defined
......

vmci 模組無法編譯成功,也無法載入至系統,更新失敗。
And vmci module will not be load into system.

Solution


1. cd /usr/lib/vmware-tools/modules/source
2. tar xvf vmci.tar (Extract it)
3. mv vmci.tar vmci.tar.bak (Backup)
4. cd vmci-only
5. vi pgtbl.h (Patch pgtbl.h)
--- vmci-only.old/include/pgtbl.h    2009-10-21 03:43:27.000000000 +0200
+++ vmci-only/include/pgtbl.h    2010-02-12 19:00:50.277528449 +0100
@@ -24,6 +24,7 @@
 #include "compat_pgtable.h"
 #include "compat_spinlock.h"
 #include "compat_page.h"
+#include "compat_sched.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 11)
 # define compat_active_mm  mm

把 #include "compat_sched.h" 加在 #include "compat_page.h" 後面一行。存檔離開。
Add "#include "compat_sched.h"" after "#include "compat_page.h"" and save. Quit.

6. vi Makefile (Patch Makefile)
--- vmci-only.old/Makefile    2009-10-21 03:43:27.000000000 +0200
+++ vmci-only/Makefile    2010-02-12 17:59:21.470529639 +0100
@@ -113,7 +113,7 @@
 
 vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
     $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) \
-    $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \
+    $(EXTRA_CFLAGS) -I$(HEADER_DIR) -Iinclude2/asm/mach-default \
     -DKBUILD_BASENAME=\"$(DRIVER)\" \
     -Werror -S -o /dev/null -xc $(1) \
     > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi)

找到這行
Replace this line:
$(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \
取代成
With:
$(EXTRA_CFLAGS) -I$(HEADER_DIR) -Iinclude2/asm/mach-default \
一樣存檔退出。
Then save and quit.

7. cd .. (Quit this folder)
8. tar cvf vmci.tar vmci-only/ (Repack the source)
9. rm vmci-only -r (Delete the entire folder)
10. /usr/bin/vmware-config-tools.pl (Re-run config tool to recompile modules)

重新執行之後應該就可以順利編譯成功並載入至系統,檢查看看是否載入:
Alter all, check if these modules are loaded perfectly:
$ lsmod|grep "^v"
vsock                  38646  0
vmmemctl                8768  0
vmxnet                 15992  0
vga16fb                12757  1
vgastate                9857  1 vga16fb
vmci                   29828  1 vsock    <-- Here, good
vmw_pvscsi             15744  0
vmxnet3                30709  0

2010/03/26

Sometimes can't access Guest OS from outside in ESXi

很奇怪的問題,在專題期間如果發生了我們肯定氣死,不過現在換學弟妹痛苦了就是。

環境


描述情況,簡單說明一下 ESXi 伺服器的狀況:

ESXi Server [192.168.0.2]
├ Ubuntu Server [192.168.0.3]
└ Windows XP Pro [192.168.0.4]

ESXi 伺服器運作兩台虛擬機器,且兩台虛擬機器都直接設定靜態IP位置 (Static IP),原本是 140 開頭的為了保護我就先以 192 代替。

原本在只有 ESXi 和 Ubuntu 的時候相安無事,一切都很順。最近新灌了一個 XP,要給學弟妹用,架設完成給定 MAC Address 和對應的 IP Address,從外面連接也能瀏覽架設的網頁伺服器。

問題


但運作幾天後,從外面分別連 Ubuntu Server 和 Windows XP Pro 都出現逾時錯誤 (Connection Timeout),更扯的是 ESXi 甚至連不上管理了,感覺好像整個網路被鎖了一樣。但可能等個一段時間,又突然正常。正常的機器也不一定,可能是 Windows、Ubuntu、ESXi 其中一台,也可能一次多台。

後來有機會能夠透過同網域的電腦來連線 (即 192.168.0.1/24 網域) 發現這些伺服器都能正常連線!可是從外面連不進去,將 ESXi 更新到最新版本仍舊有此問題,因為以往都能正常連線排除網路線路問題,開始懷疑可能是網卡驅動的問題。

進一步發現,出問題的 Guest OS 一開始會無法對外瀏覽,查詢 DNS 階段就發生錯誤,但是只要進行網路操作 (Windows 是選修復網路;Ubuntu 是 ping 外面的機器),奇妙的是連線又恢復正常了。

PING XXX.XXX.XXX.XXX (---------) 56(84) bytes of data.
64 bytes from XXX.XXX.XXX.XXX: icmp_seq=1, ttl=224, time=600.59ms
64 bytes from XXX.XXX.XXX.XXX: icmp_seq=2, ttl=224, time=5.59ms
64 bytes from XXX.XXX.XXX.XXX: icmp_seq=3, ttl=224, time=4.82ms
64 bytes from XXX.XXX.XXX.XXX: icmp_seq=4, ttl=224, time=5.35ms

會有這種第一次查詢爆慢,後面查詢開始正常的狀況。

類似案例


說真的不知道要用什麼關鍵字來找這種問題,但是還是被我搜到類似的東西:

- Minix 上的 AMD Lance 网卡驱动问题
使用静态 IP 地址以后,外部网络无法 ping 通 Minix,必须 Minix 先 ping 外面,然后外面才能 ping 通它
簡直是一模一樣的狀況!不同的是OS不一樣,所以解決方案就沒有效了。不過可推測問題可能就是OS載入的網路驅動出問題。

- [other] In ESXi can't access guest OS (Ubuntu 8.10) from outside
Ubuntu 官方論壇,描述跟我的情況是最相近的了。可惜沒多少人注意並回答這個問題,回應提到可能跟 ESXi 的 vSwitch 或 VLAN 設定有關?但我都沒有更動過,完全是預設值。至少虛擬機器只有一台的時候,非常順。

結論


總之,目前無解。茲紀錄如下希望能有其他有相同問題的人、或是有能力解決的人解惑了。

土砲解法


問題不能就這樣放著,所以我想出奇招。

既然機器ping外部的時候,網路會暫時回復一陣子,那我就定時ping外面的機器,讓線路保持動作。這樣就可以確保連線正常了。聽起來很蠢,但是實際使用確實有效。需要搭配 cron 作定期工作。

/etc/crontab 加一行
*/2 * * * * root python /usr/bin/randomping.py >> /var/log/ping.log

其中 >> 後面的意思是附加輸出 STDOUT 到檔案,觀察用,與ping無關。關鍵程式 randomping.py:
import random, os

pingHosts = ["168.95.1.1", "168.95.192.1", "139.175.150.20", "139.175.55.244", "8.8.8.8", "8.8.4.4"]

Host = random.sample(pingHosts, 1)[0]
os.system("date")
os.system("ping " + Host + " -c 2")
因為怕定期ping某單一機器會被鎖之類的,所以設定了多組名單來ping。而這些Server都是公開的DNS,應該沒有問題。

存到 /usr/bin/randomping.py 後,就讓它自動運作吧。真是爛方法,但是確實有效,唉。

2010/03/14

Install/Upgrade VMware Tools on ESXi Guest OS

這麼重要的流程竟然沒做紀錄,作一下免得日後忘記。

ESXi 裡的 Guest OS 最好裝一下 VMware Tools 以取得更佳的效能,和 VMware 自家其他虛擬機器程式一樣。安裝方式首先要從 ESXi 管理介面設定 Install/Upgrade VMware Tools。



按下選項後,Guest OS 的光碟機就好像放了一片驅動程式光碟一般,*nix 系的安裝方式比較麻煩,需要手動操作:

0. 首先先切換到 root 帳號取得必要權限
sudo -s

1. 安裝必要編譯套件及檔頭檔
apt-get update
apt-get install build-essential
apt-get install linux-headers-`uname -r`

第二行是安裝所需的編譯套件 (gcc, make 等),第二行是安裝 VMware Tools 需要的 Linux 檔頭檔。

2. 建立暫存目錄,掛載 CD-ROM
cd /tmp

mkdir /tmp/vm
mount /dev/cdrom /tmp/vm

3. 取出 VMware Tools 並解壓編譯
cp /tmp/vm/VMwareTools* /tmp
umount /tmp/vm

tar xzf VMwareTools*
/tmp/vmware-tools-distrib/vmware-install.pl

過程中會看到許多訊息跑出來,大概就是要問你安裝的位置和是否手動編譯之類的,一路按下 Enter 採用預設值即可,到最後會編譯各個組件,然後設定完成。

出現如下的成功訊息就表示整個安裝/升級的程序完成了!


檢查一下 Guest OS 的面板顯示狀態。


記得只要更新了 Linux Kernel 版本 (uname -r 可得知版本),就必須重作一次升級的動作,因為 VMware Tools 是針對 Kernel 作更動以達成最佳化,舊有的版本在新版的 Kernel 是沒有用的。另外升級的話 apt-get install build-essential 可以不必再作,因為要安裝時就已經有這個套件了吧。但是 linux-headers 記得要裝!上面的指令會自動抓取與 Kernel 相同版本的 Header 檔。

2009/12/31

WPF Frame.NavigationFailed 正確捕捉方式

我們的程式用到了 Frame 當作瀏覽器視窗,可以接受使用者輸入的 URL 顯示網頁。但如果使用者隨便輸入或鍵入一個不存在的網址要求 (使用 frame.Navigate(Uri)),Frame 會跳出 WebException。

因為這樣會強制結束程式,所以我加個 try ... catch 來攔截,這下總沒有問題了吧?

try{
    frame.Navigate(new Uri(url));
}catch{
    // show something ...
}

結果程式一跑,相同的 Exception 一樣憑空跳出,讓我丈二金剛摸不著頭腦,究竟是怎麼一回事呢?查了MSDN發現,原來 Frame 有專屬的 NavigationFailed 事件,要撰寫事件來抓這個錯誤才行,Navigate 方法本身不丟出錯誤的。

frmBrowser.NavigationFailed += new NavigationFailedEventHandler(this.NavigationFailedEventHandler);

private void NavigationFailedEventHandler(object sender, NavigationFailedEventArgs e) {
    // show something ...
}

好,我按照 MSDN 的說明,用了事件捕捉,這下總沒事了吧?事情通常沒我們想的簡單,Exception 還是偷偷的跑出來打斷了我們的程式,怎麼會這樣?

注意看 MSDN,尋找可能的問題,後來發現事件的其中一個參數 NavigationFailedEventArgs 非常可疑,一看才知道原來它隱藏著本篇的解藥!其實就是它的 Handled 屬性。說明是這樣寫的:
當處理 NavigationFailed 以處理因巡覽失敗所擲回的例外狀況,而您也不想 WPF 繼續處理例外狀況時,應該將 Handled 屬性設定為 true。
private void NavigationFailedEventHandler(object sender, NavigationFailedEventArgs e) {
    // show something ...
    e.Handled = true; // 已處理,不再擲出錯誤
}

結果加了一行,例外就乖乖的不出現了。如此重要的參數竟然在事件裡或範例中隻字未提,如果沒有發現 NavigationFailedEventArgs 參數的玄機,我想會卡非常久。特此將此經驗公諸於世,希望能救到後來人。

WPF ListView + GridView Items.Add

我們的程式用到了 ListView,而且又用了 GridView 分欄,讓清單看起來比較美觀,結果就像是Windows檔案總管的詳細資料那樣。


<ListView x:Name="listView1" Margin="178,29,35,51" SelectionMode="Single">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="FileName" Width="230" DisplayMemberBinding="{Binding Path=FileName}" />
            <GridViewColumn Header="Date" Width="140" DisplayMemberBinding="{Binding Path=Date}" />
        </GridView>
    </ListView.View>
</ListView>

但是加上了GridView的ListView,不再可以容易的以 物件名.Items.Add("String") 直接新增一條資料,這樣許多欄位的資料都會一樣。網路上的做法是使用資料繫結的方式,維護一個物件然後 Bind 上去即可,但是我還是習慣以程式動態新增,可不可以達成呢?當然可以。

因為是 WPF,所以沒有 Windows Form 的 ListViewItem 物件和物件名.SubItem 等屬性可以用。查了一下網路說明,需要建立一個物件而不是文字傳入 Items.Add()。

因為我是多欄,所以物件也要有多個屬性值,我建立一個結構來儲存:
private struct FileStructure{
    public string FileName { get; set; }
    public String Date { get; set; }
}
值得一提的是 { get; set; } 要加上,如果沒有加上這個繫結將會失敗。

然後在 WPF 的 GridView 的 DisplayMemberBinding 屬性設定 Binding,讓程式知道物件的哪個值對應到哪個欄位。請參考一開始的 WPF 原始碼。雖然我的方法還是有用到 Bind,但那是告訴 ListView 我的東西要怎樣呈現。

最後,以程式新增:

listView1.Items.Add(new FileStructure{ FileName = "test.zip", Date = "2009/12/21" });
listView1.Items.Add(new FileStructure{ FileName = "test.rar", Date = "2009/12/22" });
...

這樣就可以動態新增ListView的資料,而且每一欄的資料都正確的填進去了。
---
參考文獻:
http://stackoverflow.com/questions/1305406/wpf-listview-how-to-bind-single-items

2009/11/26

小論文格式

一.摘要
二.Abstract
三.前言
1.研究動機
四.使用者需求分析
五.研究與方法(文獻探討)
1.RFID技術
2.PKI技術
六.系統架構
七.系統評估
八.結論
九.參考文獻
-------------------------
大概這樣吧!要改再討論吧

2009/10/11

資通PKI應用競賽 時程表

活動網站:
http://csim.tca.org.tw/
http://www.ares.com.tw/pki_pk2009/a.php

1. 報名日期:98年10月1日(四)至11月19日(四) 下午六點截止
2. 初賽日期:98年11月23日(一)至11月27日(五)
3. 決賽日期:98年12月5日(六)
4. 競賽地點:台灣大學綜合體育館(台北市羅斯福路四段一號)

別忘了還有這個活動啊XD
---
報名還要錄製VCD,且邊操作邊說明,所以這系統一定要在期限內完成啊。