2010年12月21日 星期二

udp checksum的計算

UDP

udp checksum的計算

提示:
1.UDP的Pseudo Header會用到 IP 封包中的 Sorurce Address, Destination Address, 與 Protocol。
2.UDP Length會在Pseudo Header與UDP Header中各出現1次,也就是說會被計算2次。
3.若Data的長度若非Word(2 Bytes)的倍數,則必須在最後面補一個 byte的padding「0」。
假設有一封包資料如下
// ------- BEGIN Ethernet HEADER ----------------------------
00 09 5b 4f 64 72 // Destination HW address
00 07 95 e7 79 2d // Src HW address
08 00 // Type (not really sure what this octet's for)
// ------- BEGIN IP HEADER ----------------------------
45 // IP version (IPv4)
00 // Differentiated Services Code Point (i have no idea what this octet is for)
00 38 // Total Length (of the packet?)
5d 02 // ID (not really sure what this octet's for)
00 00 // Fragmentation offset
80 // Time To Live (in network hops)
11 // Protocol (UDP)
33 d6 // IP Header Checksum
c0 a8 00 02 // Source IP
c0 f6 28 3c // Destination IP
// ------- BEGIN UDP HEADER ---------------------------
6d 38 // Source Port
6d 2e // Destination Port
00 24 // Length (of the UDP Packet?)
29 b5 // UDP Checksum
ff ff ff ff // Marker (part of the packet data, no idea what it's for)
67 65 74 73 65 72 76 65 72 73 20 38 32 20 66 75 6c 6c 20 65 6d 70 74 79 // Packet Data
將上述資料以2byte為一組(16 bits)予以加總(Pseudo Header, UDP Header, UDP Data)
c0a8 + 0002 + c0f6 + 283c + // Source IP, Dest IP
0011 + // Protocol
0024 + // UDP length
6d38 + 6d2e + // Source Port, Dest Port
0024 + // UDP length
0000 + // empty checksum
ffff + ffff + 6765 + 7473 + 6572 + 7665 + 7273 + 2038 + 3220 + 6675 + 6c6c + 2065 + 6d70 + 7479 // Data
= 8d642
進位的LSB必須再加回來
8 + d642 = d64a
對結果求補數,即為checksum值
~d64a = 29b5

VMware 虛擬機各種Guest OS 虛擬硬碟擴大的方法

要對VMware 虛擬機的虛擬硬碟擴大,可以使用 VMware 自帶的命令:vmware-vdiskmanager.exe
範例:
cd “\Program Files\VMware\VMware Server”\
vmware-vdiskmanager -x 10Gb “E:\VMStorage\VMVHD001.vmdk”
-x 參數後跟擴大後的大小,第 2 個參數引號裡面是要擴大的虛擬硬碟的完整路徑名
下面針對不同 Guest 操作系統範例說明具體的操作方法!
這裡我們忽略 Host OS 的類型,因為 vmware-vdiskmanager.exe 命令在各平台上是通用的。
案例目錄:
1. Guest OS 系統為 Windows
2. Guest OS 系統為 Linux 分區使用 ext2 或 ext3 的文件系統
3. Guest OS 系統為 Solaris

1. Guest OS 系統為 Windows

系統配置:
windows XP SP2
VMWare 5.5 中文破解版
虛擬機配置:
Windows 2003 企業版
建立了一個快照
注意:擴大是針對原始磁碟檔案(副檔名為 *.vmdk )進行的操作,且擴大前要刪除所有在該磁碟上建立的快照(可能高版本不需要刪除快照)

我 們用的工具是 VMWare 安裝目錄下的 vmware-vdiskmanager.exe;在 DOS 命令提示符下鍵入:vmware-vdiskmanager.exe /? 後按 Enter ,可以看到幫助訊息,最下面還有幾個例子。我們用到的是 -X 參數。
首先要進入 C:\Program Files\VMware\VMware Workstation(VMWare 的安裝目錄)目錄,把
vmware-vdiskmanager.exe 文件和所有副檔名為 *.dll 的檔案(因為不知道哪個是vmware-vdiskmanager.exe 需要的 DLL ,所以拷貝所有的)拷貝到虛擬機文件目錄中,我在這裡要擴大的虛擬機檔案在 D:\My Document\My VirtualMachines\Windows2003Enterprise ,然後點「開始」-「執行」,輸入 cmd 後點「確定」,打開 DOS 窗口,在 DOS 窗口中切換到 D:\My Document\My VirtualMachines\Windows2003Enterprise 目錄,輸入下面的命令 vmware-vdiskmanager.exe -x 12Gb Windows2003Enterprise.vmdk 後按 Enter ,開始擴大,同時以百分比顯示擴大進度。(注意:12Gb 是擴大後的總容量)
如果你想為多個虛擬機擴容,但又覺得拷貝 文件很麻煩,你可以在 C:\ProgramFiles\VMware\VMwareorkstation(VMWare 的安裝目錄)目錄下直接執行上面的 DOS 命令,但這裡最關鍵的是如何得到 Windows2003Enterprise.vmdk 的位置,因為如果使用下面的命令 vmware-vdiskmanager.exe -x 12Gb D:\My Document\My Virtual Machines\Windows2003Enterprise.vmdk
會因為 D:\My 後的空格,而無法正確執行,所以下面說說如何得到正常的路徑。

大 家都知道 DOS 的命名採用的是 8.3 命名規則,即檔案名占 8 個字元,副檔名占 3 個字元,目錄同樣也不超過 8 個字元,這樣我們想訪問超過 8 個字元長度的目錄時,只取目錄名稱的前 6 位字符,再加上「~數字」,就可以了,例如想進入 D:\MyDocument 目錄,可以在 DOS 窗口中鍵入 cd mydocu~1 後按 Enter 就可以了,如果一個目錄內有多個長度超過 8 個字元的目錄,而它們的前 6 個字符都是相同的,該怎麼辦呢,別急,~後的數字就有用了,例如我的 D:\My Document\MyVirtual Machines 目錄下有 Windows2003Enterprise 和 WindowsXP 兩個目錄(分別對應兩個虛擬機系統),如果這時想進行Windows2003Enterprise 目錄,則需要輸入 cd Window~1 後按 ENter ,但還沒有完,用 dir 命令查看進到的目錄裡的檔案是不是 Windows2003Enterprise 中的檔案,如果不是還需要返回上級目錄,再鍵入
cd Window~2 再按 Enter ,這回應該是了吧,所以通過這種方法,我們獲得虛擬檔案的目錄是不帶空格的,如下 D:\MYDOCU~1\MYVIRT~1\WINDOW~2\Windows2003Enterprise.vmdk 這時,在 DOS 窗口中鍵入 vmware-vdiskmanager.exe -x 12Gb D:\MYDOCU~1\MYVIRT~1\WINDOW~2\Windows2003Enterprise.vmdk 後,按 Enter ,擴大程序就可以正確執行了。
完成上而把操作以後,進入虛擬系統,看我們的硬碟並沒有變大呀,這裡還需要一些改變分區大小的工具,比如用 Partition Magic。

2.Guest OS 系統為 Linux 分區使用 ext2 或 ext3 的文件系統

一、系統環境
操作系統:紅旗 DC Server 5.0
原VMware虛擬機磁盤空間是 8G ,使用其自帶命令 vmware-vdiskmanager.exe 進行擴大:

cd “\Program Files\VMware\VMware Server”\
vmware-vdiskmanager -x 10Gb “D:\VMware\RedFlag\myLinux.vmdk”
-x 參數後跟擴大後的大小,上面命令把原磁碟空間擴容到10Gb。
進入系統後,看到的情況如下:
[root@mail ~]# df -B 4k
Filesystem 4K-塊 已用 可用 已用% 掛載點
/dev/sda1 2000255 1837860 60785 97% /
none 64271 0 64271 0% /dev/shm
[root@mail ~]# df
Filesystem 1K-塊 已用 可用 已用% 掛載點
/dev/sda1 8001020 7351788 242792 97% /
none 257084 0 257084 0% /dev/shm
[root@mail ~]# df -h
Filesystem 容量 已用 可用 已用% 掛載點
/dev/sda1 7.7G 7.1G 227M 97% /
none 252M 0 252M 0% /dev/shm
[root@mail ~]# fdisk -l
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 1012 8128858+ 83 Linux
/dev/sda2 1013 1044 257040 82 Linux swap
二、操作步驟

我 們要進行操作的是 /dev/sda1 這個根分區,該分區目前大小是 8G 左右,經 VMware 擴大後,該分區所在硬碟剩餘空間約有 2G 。但需要注意的是,剩餘空間並不是在 /dev/sda1 分區的後面(右面),而是在硬盤的最後。所以,我們在進行擴大工作的時候,必須先把 swap 刪掉,把剩餘空間連接到 /dev/sda1 的後面,才能進行擴大的操作。(若用過PQmagic的朋友,應該明白這一點)
另外,雖然 resize2fs 支持在線擴大,但為了安全起見,我還是建議用 umount 的離線方式進行會更好。
1、進入拯救模式
因我要操作的是系統根分區,而又需要在 umount 狀態下,故只能由拯救模式進行了。
使用系統安裝光碟啟動後,進入拯救模式:
boot: linux rescue
並選擇不要掛載本地磁碟分區。
2、刪除swap分區
# fdisk /dev/sda

3、準備擴大
檢查分區,及去掉索引,恢復到 ext2 狀態:

4、修改分區表
在擴大的時候,需要先刪除原來的 sda1 分區,然後在原扇區的基礎上重建分區,並增加其大小。(放心,雖然期間有刪除分區表的操作,但磁碟數據並不會丟失的)
# fdisk /dev/sda


重建 swap 分區:

改為 swap 分區格式:

激活啟動選項,並保存分區表:

5、擴大分區
使用 resize2fs 進行擴大:

給 ext2 增加索引,升級為 ext3 格式:

6、格式化 swap 分區

最後,重新啟動並確認系統是否正常。
7、結果
[root@mail ~]# df -B 4k
Filesystem 4K-塊 已用 可用 已用% 掛載點
/dev/sda1 2518272 1839511 576428 77% /
none 64271 0 64271 0% /dev/shm
[root@mail ~]# df
Filesystem 1K-塊 已用 可用 已用% 掛載點
/dev/sda1 10073088 7358044 2305712 77% /
none 257084 0 257084 0% /dev/shm
[root@mail ~]# df -h
Filesystem 容量 已用 可用 已用% 掛載點
/dev/sda1 9.7G 7.1G 2.2G 77% /
none 252M 0 252M 0% /dev/shm
[root@mail ~]# fdisk -l
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 1274 10233373+ 83 Linux
/dev/sda2 1275 1305 249007+ 82 Linux swap

3. Guest OS 系統為 Solaris


參考:(轉)使用 ZFS 在 VMware Fusion 中擴大 Solaris 虛擬磁碟 By Jim Laurent
在本文中,您會找到我折騰了數小時都未能嘗試向 Solaris 虛擬機磁碟映像添加磁碟空間的記錄。原來是需要某些「新思維」。如果您需要正確的解決方案,就直接轉到文章結束部分。
我正在 MacBook Pro 上的 VMware Fusion 中運行我的 Solaris 映像。現在的問題的是如何擴大虛擬磁碟大小。
* 下載用於 MacOS X 的 VMware 虛擬磁碟管理器。這是隨 Fusion 一起提供的命令行工具的一個GUI。如果您確實喜歡使用命令行,則可以在以下位置找到它:/Library/Application\Support /VMware\Fusion/vmware-vdiskmanager。自己來權衡。我相信您的能力!
* 複製您的虛擬機。僅對副本進行操作!在 Finder 中選中它,然後選擇「編輯」>「複製」(Apple-D)。在製作副本時,虛擬機不能正在運行,甚至不能在使用中和處於掛起狀態。Fusion 會對此提示操作不當。
* 啟動 Fusion
* 「檔案打開…」新的虛擬機副本
* Fusion 會注意到檔案名已更改並提示您是否已複製該檔案。
* 掛起虛擬機
* 在擴大此磁碟前您必須先丟棄任何快照。虛擬機 > 丟棄快照。
* 啟動 Vdiskmanager GUI
* 單擊「擴大」,然後在虛擬機中查找 vmdk 檔案。選擇所需的大小。
* 單擊「運行」(該 GUI 將在窗口底部回顯它所使用的命令行,以檢查欺騙行為)
* 該 GUI 不會顯示此活動的進度。
* 完成時如果具有此狀態則將打開「結果」選項卡。
現在,真正有趣的就要開始了。但是,Format 顯示我的磁碟為其初始大小 10 GB,而非新大小 18 GB。此時 fdisk 將派上用場。

fdisk /dev/rdsk/c8t0d0p0 顯示我的磁碟有一個佔整個磁碟 56%的分區。這證明該操作發揮了作用。現在我們嘗試刪除該分區,然後在操作系統運行時重新創建一個空間較大的分區(屏息)。遺憾的是,此嘗試失敗了,如 果您不樂意從我的失敗中汲取教訓,請跳到下一部分。
* fdisk /dev/rdsk/c8t0d0p0
* 選擇 3 刪除該分區,選擇分區 1 並確認
* 選擇 1 創建一個分區。指定占磁碟的 100%。
* 選擇 5 退出,但願能成功!
* 運行 Format,崩潰了(哦,慘了!慶幸的是這只是個副本!)
* 系統重新引導並且 Grub 沒有菜單。引導內核的所有嘗試均告失敗。哎。再試一次。
好了,可以看出 Solaris 在運行時不希望我移除和重新創建其 fdisk分區。如何創建單獨的分區並裝載它呢?摒棄此核心此虛擬機並創建原件的另一個副本。重複這些步驟來增加磁碟大小,然後…此嘗試也告失敗,如果您不樂意從我的失敗中汲取教訓,請跳到下一部分。
* 需要重新引導,以使 fdisk 識別新的較大大小
* fdisk /dev/rdsk/c8t0d0p0
* 選擇 1 創建新分區,輸入大小,不要使其處於活動狀態
現在,我又卡殼了。我找不到獲取格式的方法來識別磁碟以便構建碟片。newfs 拒絕寫入沒有分區表的新文件系統。
在 SunSolve 中,我發現了 6307998 這個錯誤,已附有以下註釋。
我已經驗證,基本上 Solaris 的限制在於
它不允許同一個磁碟上有多個 Solaris 物理分區。
功能的這種缺乏超過了安裝程序,總的來說這是
Solaris 中所缺少的東西。Solaris 不支持同一個磁碟上有 2 個 Solaris 分區,
原因是磁碟驅動程序假定每個磁碟僅有一個
Solaris 分區。例如,如果我們引用 /dev/dsk/c0d0s0,則我們
如何確定需要在 c0d0 上訪問的 Solaris 分區。
救助的 ZFS
當您有 ZFS 時有誰會需要那種討厭的舊格式和 mkfs 材料呢!

* 需要重新引導,這樣 fdisk 才能識別新的較大磁碟
* fdisk /dev/rdsk/c8t0d0p0
* 選擇 1 創建新分區,輸入大小,不要使其處於活動狀態
* zpool 創建 mypool /dev/dsk/c8t0d0p1
* zfs 創建 mypool/jim
我已經成功增加了虛擬存儲!
備選方法:為映像中添加第二個磁碟
為了通過 Fusion 添加第二個硬碟。
* solaris 必須停止運行。
* 虛擬機必須關閉。
* 單擊 + 號,添加磁碟並輸入大小。
* devfsadm(差點鍵入了重新引導 — -r,但這是「舊思維」,以便 format 可以看到新設備)。
format
搜索磁碟…完成
可用的磁碟選擇:
0. c1t0d0
/pci@0,0/pci1000,30@10/sd@0,0
1. c1t1d0
/pci@0,0/pci1000,30@10/sd@1,0
# zpool create mypool /dev/dsk/c1t1d0
# zfs create mypool/jim
# zpool status
pool: mypool
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
c1t1d0 ONLINE 0 0 0
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
mypool 4.97G 116K 4.97G 0% ONLINE -

參考:Solaris ZFS 雙硬碟 RAIDZ 換碟實驗

我用虛擬機做了也一一次實驗,來驗證 2 塊硬碟做 RAIDZ ,壞一塊碟時的可用性以及可修復性。
環境介紹:


如圖: 原來系統 Labdb001.spruce.cn 的硬碟配置為:
IDE 0 Master Solaris-1-VHDD01.vid 18.2GB (c0d0)
IDE 1 Master Solaris-1-VHDD02.vid 18.2GB (c0d1)
IDE 1 Slave Solaris-1-VHDD03.vid 18.2GB (c1d1)
現在的系統是 Solaris 10 X86 05/08
C0d0 是系統碟,UFS.
C0d1 和 c1d1 創建了一個名為 ora的RAIDZ 存儲池(zpool ora)
Zpool ora 上我建了兩個ZFS檔案系統 oracle 和 oracle data
Oracle 被設定mount到 /u01
Oradate 被設定mount到 /u01/oracle
現在系統中有一個用戶 Q.Ho ,其主目錄被設定為 /u01/Q.Ho
上面現在有1個600多M的檔案,Oracle 10.1.0.3 DB的cpio.gz
現在我把 c1d1 的磁碟控制器改為STAT 接口為#7.
因為 Solaris 不可識別 SATA控制器,所以這樣做之後這塊碟在系統中將不可識別。
然後我再增加1塊碟:
Solaris-1-VHDD7SATA.vid 18.2GB
從名字上大家可以看出這塊碟是原來計劃掛在 STAT #7 上用的。
現在 VirtualBox 默認把它掛到 IDE 1 Slave
下面我示範換碟的具體步驟

首先我啟動我的虛擬機。
以 root 登入後打開一個終端,然後查看當前 zfs 存儲池(zpool)的信息
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
ora 36.2G 1.18G 35.1G 3% DEGRADED -
# zpool status
pool: ora
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using ‘zpool online’.
see: http://www.sun.com/msg/ZFS-8000-D3
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
ora DEGRADED 0 0 0
raidz1 DEGRADED 0 0 0
c0d1 ONLINE 0 0 0
c1d1 UNAVAIL 0 0 0 cannot open
errors: No known data errors
現在系統檢測到 raidz 卷 ora 兩塊碟中的一塊已經損壞,我們來看看碟上的數據是任然可用:
# pwd
/
# cd /u01
# ls
Q.Ho ora10g
# cd q.ho
q.ho: does not exist
# cd !.Ho
!.Ho: does not exist
# cd Q.Ho
# ls
solarisx86_DB_10_1_0_3_Disk1.cpio.gz

通過複製檔案 solarisx86_DB_10_1_0_3_Disk1.cpio.gz 到其他目錄,證明 RAIDZ 卷的數據任然可以正確讀取。
接下來真是換碟:
首先查看系統中現有的磁碟
#format
Searching for disks…done
AVAILABLE DISK SELECTIONS:
0. c0d0
/pci@0,0/pci-ide@1,1/ide@0/cmdk@0,0
1. c0d1
/pci@0,0/pci-ide@1,1/ide@0/cmdk@1,0
2. c1d1
/pci@0,0/pci-ide@1,1/ide@1/cmdk@1,0
Specify disk (enter its number):

大家可以看到系統已經看到新換的磁碟 c1d1 ,現在它還是裸碟。
此時 c1d1 未經過存儲池的格式化處理,所以對池任然不可用。
這時使用 online 命令啟用磁碟 c1d1 是無效的。
# zpool online ora c1d1
Bringing device c1d1 online
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
ora 36.2G 1.18G 35.1G 3% DEGRADED -
# zpool status
pool: ora
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using ‘zpool online’.
see: http://www.sun.com/msg/ZFS-8000-D3
scrub: resilver completed with 0 errors on Sat Aug 23 17:31:37 2008
config:
NAME STATE READ WRITE CKSUM
ora DEGRADED 0 0 0
raidz1 DEGRADED 0 0 0
c0d1 ONLINE 0 0 0
c1d1 UNAVAIL 0 0 0 cannot open
errors: No known data errors

正確的方法是使用 zpool replace 命令來替換存儲池中的設備:
我在同一物理位置替換新的磁碟到存儲池 ora
# zpool replace ora c1d1
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
ora 36.2G 1.18G 35.1G 3% DEGRADED -
# zpool status
pool: ora
state: DEGRADED
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scrub: resilver in progress, 59.01% done, 0h0m to go
config:
NAME STATE READ WRITE CKSUM
ora DEGRADED 0 0 0
raidz1 DEGRADED 0 0 0
c0d1 ONLINE 0 0 0
replacing DEGRADED 0 0 0
c1d1s0/o UNAVAIL 0 0 0 cannot open
c1d1 ONLINE 0 0 0
errors: No known data errors
大家可以看到池正在同步 RAIDZ 卷中兩塊硬碟上的數據

一分鐘後再次查看存儲池的狀態
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
ora 36.2G 1.18G 35.1G 3% ONLINE -
# zpool status
pool: ora
state: ONLINE
scrub: resilver completed with 0 errors on Sat Aug 23 17:40:51 2008
config:
NAME STATE READ WRITE CKSUM
ora ONLINE 0 0 0
raidz1 ONLINE 0 0 0
c0d1 ONLINE 0 0 0
c1d1 ONLINE 0 0 0
errors: No known data errors
新的硬碟已經被成功替換,RAIDZ 存儲池 ora 已經被修復。
通過這個實驗,證明2塊碟的 RAIDZ 壞一塊碟的情況下是可以很方便的進行換碟恢復的。
擴大開來,我們還可以通過換碟的方式更換更大容量的硬碟為存儲池擴大。