qemu-img將qcow2轉換為塊裝置(openstackimage2volume)中的瘦供給
1、背景
qemu-img convert 可以將一個映象裡的資料以raw格式的方式寫入一個塊裝置
這裡一定要注意,如果convert目標是一個塊裝置,一定必須帶-t none(以及上文中的引數)標記。否則後續的has_write_zeros屬性不會開啟。
如果convert目標是一個檔案時刻,那麼不用—t none都會設定discard_zeroes,has_write_zeroes和has _falloccate有了這些屬性,寫入目標檔案時刻使用fallocate來實現檔案的打洞。
2、qemu-img convert
在qemu-img convert函式中,如果配置了-t none(以及前述標記off,direct),那麼目標裝置開啟的時候帶有BDRV_O_NOCACHE。此標記會將目標裝置塊驅動(qemu 的blk驅動)設定has_write_zerors屬性,當linux反饋塊裝置支援discardzero時刻再設定discard—zero屬性;如果不帶 BDRV_O_NOCACHE 那麼設定has_write_zeros, discard_zero均不生效。
當qemu-img convert寫入裝置資料的時候,首先嚐試執行清零動作。
在img-convert()主入口,寫入真正資料之前呼叫:
2.1 判定是否使用清理卷:
bdrv_can_write_zeroes_with_unmap(out_bs),
1)如果qemu-img convert -S 0 那麼就會直接返回false,表示不能通過unmap進行清0動作。
2)在此函式裡通過呼叫bdrv_get_info()—>raw_get_info()取得discard—zero標記判定。
此標記在raw_open_common()裡判定塊裝置沒有設定BDRV_O_NOCACHE標記時刻,設定discard-zero標記為Fasle,其他情況塊裝置如果通過ioctl查linux系統塊裝置設定BLKDISCARDZEROES標記時設定為True。也就是qemu-img convert -t none或者-t off 或者-t direct,discard-zero為False;或者linux查詢裝置狀態反饋不支援discard-zero
如果discard-zero標記為True就需要清理卷,否則就不需要。此標記為真表示linux支援使用ioctl discard命令來格式化卷為全0.
2.2 如果判定無需清除卷:
那麼後續的寫入動作,就必須忠實的寫入0. 對於qemu-img convert -t writethrough ,它在開啟時刻沒有設定BDRV_NONE_CACHE.所以discard-zero標記為false,所以判定無需預先使用discard清0.
2.3 如果判定需要清除卷:
如果判定輸出塊裝置支援bdrv_make_zero(out_bs,BDRV_REQ_MAY_UNMAP)對整個捲走清零動作。此函式使用brdv_write_zero(BDRV_REQ_MAY_UNMAP)
bdrv_co_write_zeroes(),此函式最終呼叫到raw-posix driver的hdev_co_write_zeroes().在此函式中檢測blk驅動
1)如果沒有設定BDRV_REQ_MAY_UNMAP(只有qemu-img convert -s 0此標記才會清理掉,表示不支援unmap清0)
它呼叫handle _aiocb_write_zeroes(),這個函式最終呼叫handle_aiocb_write_zeroes_block(),此函式最終判斷設定了has_write_zeros 標記就呼叫ioctl(BLKZEROOUT)發往核心的scsi block。
Qemu-img convert -t none 和-t off -t direct就走的這個流程。
2)如果設定了BDRV_REQ_MAY_UNMAP且設定了disacard_zeros標記,最終呼叫handle_aiocb_discard()
此函式最終呼叫ioctl(BLKDISCARD)
核心(3.10)
核心收到BLKZEROOUT以後,將呼叫blk_ioctl_zeroout()—>blkdev_issue_zeroout–>blkdev_issue_write_same()
寫入內容全部為零的頁面。blkdev_issue_write_same()生成一個bio(塊io請求),帶REQ_WRITE_SAME.
當這個請求最終由核心的scsi driver驅動處理(ks3200 的iscsi lun在核心中最終體現為一個scsi disk)時,它產生一個WRITE_SAME 的scsi命令。
硬體
總結
qemu-img 轉換為檔案時刻,由於本地檔案系統支援,所以即便目標是raw檔案,原始映象中的連續0也是不會佔用實際物理空間的。
轉換目標可以是一個塊裝置,按照raw格式將資料寫入塊裝置。此時當塊裝置支援discard特性的時候(ssd裝置),qemu 使用裝置的blkdiscardzeros,最終落實到scsi的unmap命令,此時資料也不會被真正被寫入;此時核心意識得到寫入的零沒有真正寫入。
相關文章
- Java 中將 InputStream 轉換為 StreamJava
- Java 中將 Short 轉換為 byte[]Java
- 將圖象列表轉換成裝置無關點陣圖 (轉)
- 如何在Java中將double轉換為int?Java
- 如何在Java中將字串轉換為日期Java字串
- Java中將 Map 轉換為 Spring MultiValueMapJavaSpring
- 轉換vmware的vmdk格式到qcow2或者raw格式
- 字元裝置、塊裝置、裸裝置、RAW裝置 .字元
- 字元裝置、塊裝置與裸裝置字元
- 檔案作為塊裝置訪問
- 如何在Java 8中將List轉換為Map?Java
- Java中將 int[] 陣列 轉換為 List(ArrayList)Java陣列
- 在 AngularJS 中將 XML 轉換為 JSONAngularXMLJSON
- Java中將Excel轉換為JSON的兩種方法JavaExcelJSON
- Java中將XML轉換為PDF的兩種辦法JavaXML
- 字元裝置與塊裝置的區別字元
- 裸裝置與塊裝置的區別
- AIX 共享磁碟中的字元裝置(/dev/rhdiskn)及塊裝置(/dev/hdiskn)AI字元dev
- 裝置元件檔案轉換為EVE-NG環境的支援元件元件
- vmdk 轉 qcow2
- 將網頁轉換為Markdown的免費線上轉換工具網頁
- 將dBm轉換為W的口算方法
- JS中將一個值轉換為字串的3種方法JS字串
- 如何將InputStream轉換為DataSource
- 使用lsblk命令列出系統中的塊裝置命令列
- 如何在Python中將語音轉換為文字Python
- Java中將電話號碼轉換為數字Java
- 不光給蘋果 三星將為寶馬供應透明OLED屏蘋果
- 裸裝置、字元裝置、塊裝置不全面比較字元
- [Object C]object c中完成將xml轉換為jsonObjectXMLJSON
- java將IP地址轉換為數字以及逆向轉換Java
- 將WordPress站點轉換為JoomlaOOM
- js將秒轉換為時分秒JS
- Thymeleaf將字串轉換為數字字串
- Scala 將BigDecimal轉換為LongDecimal
- JavaScript將陣列轉換為字串JavaScript陣列字串
- 將PPT文件轉換為Word文件
- 將FileSystem轉換為ASM儲存ASM