虛擬磁盤格式1:VMDK


參考文檔:Virtual Disk Format 5.0

虛擬磁盤格式:VMDK

vmware設計VMDK的文件格式來模擬物理磁盤,使得虛擬機的操作系統讀寫虛擬磁盤時使用與物理磁盤相應的接口
虛擬磁盤作為一個或多個文件存儲在主機或遠程設備上

  • 在vmware workstation或mware pusion上:存在底層主機操作系統(win,Linux.,mac)提供的文件系統上
  • 在數據中心平台上:存在Esxi主機存儲或網絡連接的存儲上
  • 在Exi主機上:存在VMES(虛擬機文件系統)分區上

總體結構

開始VMDK僅包含一個虛擬盤(base disk),如果拍攝虛擬機快照,會產生增量鏈接(delta link,可能有多個)
每個鏈接由多個區段(extent)組成,每個段對應一個物理存儲區域,即對應一個文件(通常)
下圖中link B,C的區段是開始較小,隨時間變大的區段,稱為稀疏區段(sparse)
linkA的區段可以是稀疏區段,也可以是預先分配好大小的區段(flat,創建時已經預先分配好空間),甚至可以直接由物理設備支持。

描述符文件

VMDK有文本描述符文件,用於描述磁盤中數據布局。該文件可以是單獨文件,也可以包含到虛擬磁盤其它文件內。
下圖為一個ubuntu虛擬機的描述文件。#開頭的為注釋信息。

header部分

更詳細內容見文檔Virtual Disk Format 5.0

字段 說明
version 表示描述文件的版本,默認為1
CID 內容ID值,一個32位隨機值。當磁盤被打開,第1次修改內容后就會更新
paratCID 父鏈接內容ID值,如linkB的parantCID就是likA的CID,如果沒有父鏈接,則值設為ffffffff
createType 描述虛擬碰盤的類型。如果值含有flat就表示已預先分配空間,包含sparse表示按需分配是稀疏磁盤,包含vmfs表示用於Esxi上的存儲,如圖中的2GbMaxExtentsparse表示2GB或更小的稀疏磁盤

extent部分

每行描述一個區段
如上圖中第一行RW 4192256 SPARSE "ubuntu-sever-10.10-i386-s001.vmdk"

字段 說明
RW 訪問權限,這里為可讀可寫
4192256 占幾個扇區,一個扇區512B,這里換算下來約為2GB
SPARSE 區段的存儲分配方式,這里為稀疏的
"ubuntu-sever-10.10-i386-s001.vmdk" 文件名,表示區段相對於描述符文件的路徑

disk database部分

存儲虛擬磁盤的其它信息,格式為ddb.<名字>="值"
如ddb.adapterType="lsilogic"表示適配器類型為SCSI,用於SCSI磁盤。
以下表示由適配器初始化的磁盤的每道扇區數,磁頭數,柱面數。
ddb.geometry.sectors = "63"
ddb.geometry.heads = "255"
ddb.geometry.cylinders = "2610"
搜索disk database信息時由底部向頂部開始(即由link C開始)

稀疏區段

這里主要介紹vmware workstation等主機平台的稀疏區段的格式,結構如下圖所示

spare header稀疏頭部分

結構以小端存儲,定義為sectortype的類型是以扇區為單位

字段 類型 意義
magicNumber uint32 用於驗證每個區段的有效性,vmdk文件的就初始化為0×564d444(即VMDK)
version uint32 版片號,1或2
flags uint32 每比特為一標記。如第16比特表分頁(grains)是否被壓縮
capacity sectortype(uint64) 該區段的大小,必須是分頁大小的整數倍
grainsize sectortype 一個頁的大小、必須為2的冪次,次數大於8
descriptoroffset sectortype 嵌入在段中的描述符文件的偏移量,偏移為幾個扇區,如果沒都為0
descriptrsize sectortype 當描述符的偏移量不為0是才有效,描述符文件大小
numGTEsPerGT uint32 頁表中條目的數量,虛擬磁盤中為512
rgdOffset sectortype 冗余元數據第0層偏移,偏移為幾個扇區
gdOffset sectortype 元數據第0層偏移(在下一小節介紹這一概念),偏移為幾個扇區,
overHead sectortype 元數據所占扇區數
uncleanShutdown bool(uint8) 關閉區段時設置為false,打開時設置為true,如果打開后發現為true,就要進行一致性檢測
sigleEndLineChar char(uint8) 當用FTP傳輸時,用以下4個進行檢測是否被損壞,初始值為'\n'
nonEndLineChar char 初始值為' '
doubleEndLineChar1 char 初始值為'\r'
doubleEndLineChar2 char 初始值為'\n'
compressAlgorithm uint16 磁盤中每一頁的壓縮算法
pad[433] uint8 433B的填充,加上前面的79B,所以頭信息共占512B,一個扇區

當vsersion=2,flags第2比特被設置時,表示采用zeroed-grain GTE,一般是快照或磁盤被壓縮時設置

下面結合實際看一看,如下圖,為一個區段的第一個扇區的數據

顏色 意義
黃色 就是KDMV
綠色 版本號
藍色 flag
粉色 因為小端存儲,所以為3FF800,化為10進制為4192256,因為是sectortype,再乘以512B,約為2GB,即該區段有2GB
紅色 頁的大小,同樣化下來為64KB
紫色 描述符在段中的偏移量,都為0,說明該段不包含
白色 描述符文件大小也為0
橘色 頁表中條目數量為512
灰色 冗余元數據第0層偏移,為1,即1個扇區
黑色 元數據第0層偏移,為258,即258個扇區
青色 元數據占扇區數640*512
黑框 false
四個紅框 '\n',' ','\r','\n'四個字符
紅線 壓縮算法,沒有壓縮

稀疏區段元數據(grain directory, grain table)部分

grain directory頁目錄(GD)是第0層元數據,grain table頁表(GT)是第1層元數據,頁目錄中的每一個條目指向一個頁表區塊,如下圖所示
redundancy grain directory,redundancy grain table為保存的副本

頁目錄中的條目(GDE)指頁表在稀疏區段中的偏移量,條目的數量取決於段的大小,一個條目占32位
頁表中的條目(GTE)指一個頁在稀疏區段中的偏移量,每個頁表有512個條目,每個條目占32位,所以一個頁表占2KB
在頭中的grainsize表示頁的大小為64KB,區段的大小是頁的大小的整數倍,所以也可知道VMDK采用的是段頁式的存儲結構

下面再結合實際看一看
首先找頁目錄
冗余頁目錄為1扇區處(由頭信息知),即偏移512B,冗余頁目錄如下

再找冗余頁表
只看上圖冗余頁目錄第一個32位 02 00 00 00,小端存儲,就是2,2扇區偏移1024B,所以第一個冗余頁表如下圖
那么冗余頁表第一個32比特80 02 00 00表示第一個頁在640扇區偏移處

再看看頁目錄和頁表是否與冗余頁目錄頁表一致:
頁目錄在258扇區處(由頭信息知),即偏移132096B,頁目錄如下

頁目錄第一個32位 03 01 00 00,為259,即偏移132608B,第一個頁表如下
那么第一個頁表第一個32比特80 02 00 00表示第一個頁在640扇區偏移處,可見冗余頁表頁目錄與頁表,頁目錄一致

下面再看看第一個數據的頁,偏移在640*512,即偏移327680,這里因為是MBR的分區結構,我們可以看到陰影處為第一個分區表,在陰影中00 08 00 00表示第一個分區的起始扇區號為2048,更多見


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM