qemu-img將qcow2轉換為塊裝置(openstackimage2volume)中的瘦供給

marshalzxy發表於2017-07-05

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命令,此時資料也不會被真正被寫入;此時核心意識得到寫入的零沒有真正寫入。


相關文章