---
title: VHDX+COW+CASでTB級のリポジトリを秒でクローンする話
tags:  #events #azure #windows  
author: [Takeshi Yaegashi](https://docswell.com/user/yaegashi)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/GE8D4RXGED.jpg?width=480
description: Kernel/VM探検隊@東京 No19 https://kernelvm.connpass.com/event/395390/
published: August 22, 26
canonical: https://docswell.com/s/yaegashi/5X2QXN-kernelvm-19
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/GE8D4RXGED.jpg)

VHDX+COW+CASでTB級のリポジトリを秒でクローンする話
株式会社バンダイナムコスタジオ
八重樫 剛史 Takeshi Yaegashi
Kernel/VM探検隊@東京 No19
2026/08/22


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LELM6K8X7R.jpg)

自己紹介
• 名前: 八重樫 剛史 Takeshi Yaegashi
• 組織: 株式会社バンダイナムコスタジオ (BNS)
• 部署: テックスタジオ 第２グループ 共通基盤開発部
インフラテック課
• 肩書: テクニカルディレクター
• Microsoft MVP for Microsoft Azure, M365 (2023-2026)
https://mvp.microsoft.com/ja-jp/PublicProfile/5005134
• Linux・Unix・Go言語とかでレベルが低いことが好き
• 今回のイベントは2日前に10分枠が空いているのを見つけたので飛び入りでエントリーしました
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4JMY5263JW.jpg)

低レベルな昔話
• 2006年くらいまでいろいろなガジェットに GNU/Linux を移植して遊んでいました
• eCos+RedBoot (Real-time OS as a bootloader for Dreamcast) [1]
• SEGA Dreamcast (SH-4 based game console)
• shlo.exe (Linux kernel bootloader for Windows CE on SH-3)
• HP Jornada 620/680/690 (SH-3 based Windows CE HPC)
• Debian-Installer for PLAYSTATION 3 Linux
• muslstack (2019)
• Binary patch utility to set default thread stack size for musl libc [2]
• golang.tokyo #25: golang binary hacks [3]
• 最近はレベルが低いことができていない
• クラウドとか AI 導入推進とかレベルが高い仕事に忙殺されている
[1] https://web.archive.org/web/20060714130559/http://www.m17n.org/linux-sh/dreamcast/index.ja.html
[2] https://github.com/yaegashi/muslstack
[3] https://www.slideshare.net/slideshow/golang-binary-hacks-150386886/150386886
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/PJR93MPR79.jpg)

高レベルな今日の話
• Linux・Unix がホームグラウンドな私ですが今日は Windows OS の話をします！
• タイトル: VHDX+COW+CASでTB級のリポジトリを秒でクローンする話
• VHDX
• COW
• CAS
• TB級
• リポジトリ
→ Windowsで使える仮想ディスクファイルフォーマット
→ Copy-on-write ファイルシステム: Windows 11 or Windows Server 2025 で使える Dev Drive (ReFS)
→ Content-Addressable Storage: casync/desync
→ Terabyte-scale = 1012 bytes くらい
→ 実際には P4/Git リポジトリからチェックアウトしたワークスペースのこと
• 秒で
• クローン
→ ベストケースで1秒
→ リモートサーバーのリポジトリからローカルマシンにワークスペースをとってくる
• 2026/07/23(木) CEDEC 2026
TB級アセット時代の開発基盤再構成――COWファイルシステム・コンテンツアドレス型差分配布・コ
ンテナ技術で実現するAIワークフロー
https://www.docswell.com/s/yaegashi/K27JN6-CEDEC2026
• 2026/08/13(木) LinkedIn Article
What If Your Build Machines Never Ran p4 sync Again?
https://www.linkedin.com/pulse/what-your-build-machines-never-ran-p4-sync-again%E5%89%9B%E5%8F%B2-%E5%85%AB%E9%87%8D%E6%A8%AB-hx0lc/
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/PEXQ4V3YJX.jpg)

社内プロジェクトの紹介
• 社内ゲーム開発プロジェクト: Project1 (仮称)
• Unreal Engine を採用した大規模プロジェクト
• Perforce Helix Core (P4) リポジトリを採用
リポジトリ総容量は数 TB に達する
• CI/CDパイプラインのビルド1回で取り扱うコード+アセット:
総容量 約600GB、約230万ファイル
• マルチプラットフォーム大型タイトルとしては一般的な規模
• 社内技術研究プロジェクト: Cairn (コードネーム)
• ケルン (Cairn) とは登山用語で、登山道などで見られる、
石や岩を積み上げて作られた目印・道標のこと
• 配布物を構成するチャンク (Chunk) を石や岩の塊になぞらえ、
多数のチャンクで組み立てられていることから命名
Microsoft 365 Copilot が生成した Cairn と Chunk のイラスト
• Project1 のような大規模ゲーム開発プロジェクトを
対象として CI/CD パイプラインの効率化を目指す
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/3EK9ZQY4ED.jpg)

230万ファイルの「後始末」がクラウド利用を阻む
• p4 clean: ビルド後のワークスペースを最初の状態に戻す
• P4クライアント・ワークスペースに加えられた変更を解消し、リポジトリに登録された状態に戻すコマンド
• ビルドが終わったあと、次のビルドを行う前に実行することが多い
• Project1 のワークスペース: 600GB・2.3Mファイル の p4 clean が遅い
• オンプレPC (NVMe): 数十分
→ ベースライン
• Azure VM Local NVMe: 数十分
→ オンプレPCと同じくらい (ただしVMを止めるとLocal NVMeは消える)
• Azure VM Premium SSD v2: 数時間 → 遅すぎる Azure でのビルドは諦めざるを得ないレベル
• ビルドではなく、ワークスペースの走査・メタデータ操作がボトルネックになる
• ストレージ性能の問題からクラウドVMでのビルドを断念するケースがある
• 問題はディスクを速くするだけでは解決しない 数百万ファイルをそのまま扱う方式を見直す必要がある
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/L73WDP9D75.jpg)

VHDX+COW+CAS Workspace Publishing ワークフローの考案
• Content-Addressable Storage (CAS) を活用したワークフロー
• VHDX を 1MB 固定長ブロックに分割、各ブロック内容のハッシュを計算し、圧縮したチャンクを作る
すべてのチャンクおよびインデックスを VHDX WS CAS に格納
• 初回の VHDX の復元はインデックスに記録されたすべてのチャンクのダウンロードが必要
2回目以降の復元は、VHDX内の更新されたチャンクのみダウンロードすれば復元できる
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/87DKPLG2JG.jpg)

VHDX+COW+CAS Workspace Publishing のねらい
• リポジトリとビルドサーバーの間に
CAS を設けるとなにがうれしいのか？
従来: クラウドVMが
オンプレミスの P4 に接続する
Workspace Publishing:
クラウドストレージから受け取る
• オンプレリポジトリサーバーとクラウドビ
ルドサーバーでE2Eの接続性を確保する必要
がなくなる (固定IPアドレスも不要になる)
• クラウドストレージ (AWS S3 や Azure Blob
や CDN など) のファイル配信能力により、
多数のサーバーに対して、TBスケールの
ワークスペースを固定長ブロックのチャン
クに分割して並列・高速に配布できる
• 10台のCI/CDビルドサーバー
• 100台の開発者・テスタのワークステーション
• 1000台のQA自動化AIエージェントマシン
• ビルドサーバーからリポジトリに書き戻す
必要がないワークロードなら最強
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/VJPKN23LE8.jpg)

OSS Content-Addressable Storage 実装の系譜: casync → desync → cairn-desync
• casync: Content-Addressable Data Synchronization Tool (2017) [1]
• A tool for distributing file system images [2]
• Lennart Poettering (systemd の作者) による C 実装・Linux/Posix でしか動かない
• desync: Alternative casync implementation (2017) [3]
• Frank Olbricht 氏による casync の Go 再実装
• 並列化・マルチプラットフォーム (Windows含む)・S3/GCS対応
• cairn-desync (v1.0.3-cairn.17.1)
• Cairn プロジェクトで desync を VHDX のフォーマットに最適化したフォーク
• v1.0.3 に存在する固定長ブロックのチャンクが作れないバグを修正
→ VHDXは1MB単位で成長するデータ構造なので1MBの固定長ブロックが最適
• マルチスレッド実行時、各ワーカー開始オフセット位置を固定長ブロックのアライ
ンメントに合わせる
→ 従来は単純に「VHDXサイズ÷スレッド数」で開始オフセットを計算していた
→ 開始オフセットを 1MB アラインメントに合わせることで大きく性能改善
• Azure Blob に置かれたプライベート CAS チャンクストアの対応を追加
• Windows ReFS 対応
[1] https://github.com/systemd/casync
[2] https://0pointer.net/blog/casync-a-tool-for-distributing-file-system-images.html
[3] https://github.com/folbricht/desync
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/2EVVKD46EQ.jpg)

cairn-desync の使い方・チャンクストア仕様
• 基本的な使い方
• CAS チャンクストアに格納・復元するVHDXファイルごとに、CASインデックスのCAIBXファイルが存在する
• 格納 (IN:VHDX, OUT:CAIBX) → desync.exe make -s /path/to/castr CL1234.caibx CL1234.vhdx
• 復元 (IN:CAIBX, OUT:VHDX) → desync.exe extract -s /path/to/castr CL1234.caibx CL1234.vhdx
• CAS チャンクストア レイアウト
• caibx/*.caibx と castr/*.cacnk に分けて格納されている
• Azure Blob や AWS S3 に配置したチャンクストアから直接復元ができる
https://cairn.blob.core.windows.net/desync/store/caibx/CL1234.caibx
https://cairn.blob.core.windows.net/desync/store/caibx/CL1235.caibx
https://cairn.blob.core.windows.net/desync/store/caibx/CL1236.caibx
https://cairn.blob.core.windows.net/desync/store/castr/0000/00002a75a97e91acc4abc2f024dbb5698076c3f28cf456832923284e65da0266.cacnk
https://cairn.blob.core.windows.net/desync/store/castr/0000/000032a90aadcda89e34daa8fa0f0f60ef5333f455e47e99cc680f538bd3d455.cacnk
https://cairn.blob.core.windows.net/desync/store/castr/0001/0000...
https://cairn.blob.core.windows.net/desync/store/castr/0001/0001...
https://cairn.blob.core.windows.net/desync/store/castr/0002/0002...
https://cairn.blob.core.windows.net/desync/store/castr/0002/0003...
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/57GLQY12EL.jpg)

cairn-desync の性能測定
• チャンクストアの性能測定 (P4-UE-Project1 VHDX WS 600GB, Standard_D32ads_v7)
• 100 CL の VHDX サイズ合計
60,597.98 GB
• チャンクストアサイズ
443.53 GB (100 indexes, 674,561 unique chunks)
• 圧縮率
136.7
• Local NVMe チャンクストアへの格納
平均 574.95s (n=5)
• Local NVMe チャンクストアからの復元
平均 411.29s (n=5, SD=1.85)
• Azure Blob チャンクストアからの復元
平均 549.73s (n=5, SD=8.41)
• cairn-desync による VHDX Workspace Publishing ワークフローは成立するか？
• 保存量・転送量・費用は良好な成績だが、処理時間にはさらなる改善が必要である
• 格納: 毎回 600GB VHDXの1MBブロック全体に対してハッシュ計算を行っている。過去に格納したVHDXから更新のない
ブロックはチャンクストアに存在するためハッシュ計算は無駄である。なんとかスキップすることはできないか？
• 復元: 毎回 600GB VHDXの1MBブロック全体に対してチャンク取得を行っている。過去に復元したVHDXから更新のない
ブロックはローカルに存在するためチャンク取得は無駄である。なんとかスキップすることはできないか？
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/4EQYKMD9JP.jpg)

cairn-desync の改善: P4-UE-Project1 VHDX WS CAS 差分の観察
• P4-UE-Project1 VHDX WS 600GB (2TB NTFS)
• 隣接CLの1ファイルの更新だけで、NTFS の複数箇所の更新を生み、それが 20 前後のチャンクの更新として現れる
• 99CL離れた 385915→386069 では、P4 上では 16016 MiB の変更となっているが、14950 チャンクの更新で済んでいる
Old CL
New CL
CL Distance
P4 Change Files P4 Change Bytes
385915
385917
1
1
4,937
577,092
576,084
17
385917
385919
1
1
1,864,105
577,092
576,087
19
385919
385920
1
78
1,116,687
577,092
576,086
99
385920
385921
1
2
79,555
577,092
576,087
18
385921
385923
1
2
44,881
577,092
576,088
21
385923
385924
1
1
6,211
577,092
576,088
16
Old CL
New CL
385915
386069
99
122,923
16,794,260,271
578,404
577,136
14,950
385917
386069
98
122,922
16,794,255,334
578,404
577,136
14,948
385919
386069
97
122,921
16,792,391,229
578,404
577,136
14,945
CL Distance
P4 Change Files P4 Change Bytes
Total Chunks
Total Chunks
Unique Chunks
Unique Chunks
Diff Chunks
Diff Chunks
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/KJ4WPVGR71.jpg)

cairn-desync の改善: ReFS Trusted Base 拡張
• VHDX WS CAS 差分を観察して気づくこと
• VHDX WS CAS の格納や復元を行うとき、旧CLのVHDX・CAIBXが手元にあれば、
新しく生成するVHDX・CAIBXのほとんどのチャンクは、旧CLのVHDX・CAIBXから再利用できるはずである
• cairn-desync に ReFS Trusted Base 拡張を実装
• Trusted Base = 信頼できる既存の状態
• ReFSの低レベルCOW機能を利用し、不変ベースブロックを検出してハッシュ計算やチャンク処理をスキップする
• FSCTL_DUPLICATE_EXTENTS_TO_FILE
→ Linux の FICLONERANGE (reflink)
→ ファイル内のブロック単位のクローンを行う (Copy-Item と異なり任意ブロック範囲をクローンできる)
• FILE_SUPPORTS_BLOCK_REFCOUNTING / FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT
→ Linux の FIEMAP の refcount 付きなやつ
→ ファイル内クラスタ (VCN) が、どのファイルシステム内クラスタ (LCN) を参照しているかがわかる
→ 新旧VHDX内の VCN が、 同一の LCN を参照しているなら、同一内容の VCN であると判定する
• FILE_SUPPORTS_SPARSE_VDL / FSCTL_QUERY_FILE_REGIONS
→ ファイル内クラスタの未初期化範囲 (VDL) を調べることができる
→ 新旧VHDX内の VCN の片方が VDL に含まれるなら、同一の LCN を参照していても、その内容は一致しないと考える
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/LE1Y93DV7G.jpg)

cairn-desync の改善: ReFS Trusted Base Store (VHDX→チャンクストア)
• 旧VHDXを新VHDXにクローンして、マウント・p4 sync・アンマウントによりワークスペースを更新する
• 新旧のVHDXを見比べて (FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT を使用)、変化があったブロックのみ、
ハッシュを計算して新CAIBXに格納し、新チャンクを生成してチャンクストアに格納する
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/GEWGQPY3J2.jpg)

cairn-desync の改善: P4-UE-Project1 Store 実測 (VHDX→チャンクストア)
• Dataset: P4-UE-Project1 (600GB・2.3M)
• Azure VM Size: Standard_D32ads_v7 (CPU 32コア・Memory 128GB・4×440GB Local NVMe)
• Local NVMe (2GB/s) の Dev Drive で Trusted Base 復元された 3 CL の VHDX から新規のチャンクストアを作成
• まず CL00385915 を普通に格納し、それを Trusted Base として CL00385917 CL00386069 を順に格納する
# CL00385915 普通の格納
desync.exe make -n 8 -s /path/to/castr CL00385915.caibx CL00385915.vhdx
# CL00385917 (CL00385915) 格納
desync.exe make -n 8 -s /path/to/castr --trusted-base-file CL00385915.vhdx --trusted-base-index CL00385915.caibx CL00385917.vhdx
# CL00386069 (CL00385915) 格納
desync.exe make -n 8 -s /path/to/castr --trusted-base-file CL00385915.vhdx --trusted-base-index CL00385915.caibx CL00386069.vhdx
格納CL (ベースCL)
CL距離
Total Chunks
Read Chunks
Store Chunks
CL00385915
-
577,092
577,092
576,083
574.95s (n=5)
CL00385917 (CL00385915)
1
577,092
233
17
15.24s (n=6)
CL00386069 (CL00385915)
99
578,404
15,438
14,947
18.88s (n=6)
平均所要時間
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/47ZLWKXGJ3.jpg)

cairn-desync の改善: ReFS Trusted Base Restore (チャンクストア→VHDX)
• 旧VHDXを新VHDXにクローンする (一瞬で終了)
• 新旧のCAIBXを見比べて、変化があったブロックのみ、
チャンクストアから新チャンクを取得して新VHDXを書き換える
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YJ6WGQ4QJV.jpg)

cairn-desync の改善: P4-UE-Project1 Restore 実測 (チャンクストア→VHDX)
• Dataset: P4-UE-Project1 (600GB・2.3M)
• Azure VM Size: Standard_D32ads_v7 (CPU 32コア・Memory 128GB・4×440GB Local NVMe)
• Local NVMe (2GB/s) の Dev Drive にチャンクストアと VHDX 復元先が所在する
• まず CL00385915 を普通に復元し、それを Trusted Base として CL00385917 CL00386069 を順に復元する
# CL00385915 普通の復元
desync.exe extract -n 32 -s /path/to/castr CL00385915.caibx CL00385915.vhdx
# CL00385917 (CL00385915) 復元
Copy-Item CL00385915.vhdx CL00385917.vhdx (ブロッククローン、1s未満)
desync.exe extract -n 32 -s /path/to/castr --in-place --trusted-base-index CL00385915.caibx CL00385917.caibx CL00385917.vhdx
# CL00386069 (CL00385915) 復元
Copy-Item CL00385915.vhdx CL00386069.vhdx (ブロッククローン・1s未満)
desync.exe extract -n 32 -s /path/to/castr --in-place --trusted-base-index CL00385915.caibx CL00386069.caibx CL00386069.vhdx
復元CL (ベースCL)
CL距離
Total Chunks
Get Chunks
平均所要時間
CL00385915
-
577,092
576,156
411.29s (n=5)
CL00385917 (CL00385915)
1
577,092
17
1.07s (n=3)
CL00386069 (CL00385915)
99
578,404
14,950
23.16s (n=3)
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GJ5MVRQ2J4.jpg)

cairn-desync による VHDX WS Publishing の総括
• P4ワークスペースVHDX (600GB) 連続 100 CL を格納した高効率なチャンクストアが実現できた
• 100 CL の VHDX サイズ合計
60,597.98 GB
• チャンクストアサイズ
443.53 GB (100 indexes, 674,561 unique chunks)
• 圧縮率
136.7
• チャンクストアに格納する CL が増えていけば、圧縮率はさらに増加する (新規の差分チャンク数に依存)
• チャンクストアは単純なオブジェクトストレージ (Azure Blob) なので実際の CL 総数 (数十万) でも容易にスケールする
• desync の ReFS Trusted Base 拡張により大幅な性能改善を果たした
• VHDX (600GB) 復元
フル実行 411.29 秒 → Trusted Base Restore 最速1秒〜
• VHDX (600GB) 格納
フル実行 574.95 秒 → Trusted Base Store 最速15秒〜
• 1 CL ごとに 1 VHDX を作成するのに十分な所要時間が達成できる
• 所要時間は線形に増加するのでTB規模のVHDXでも現実的な時間に収まる見込み
• VHDX WS Publishing ワークフローの成立要件: 保存量・転送量・費用・時間をクリアし、
VHDX+COW+CAS CI/CD パイプラインが実用化できる見込みが立った
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LE3WDPV1E5.jpg)

今後の展望 1
• VHDX+COW+CAS ベースの CI/CD パイプラインを実際の製品開発プロジェクトへ組み込む
• 実製品プロジェクトのP4リポジトリ(600GB規模)と Azure による検証で良好な結果が得られた
• 既存のP4リポジトリのパイプラインに影響を与えることなく部分的な導入が可能
• TB規模のP4リポジトリでもリーズナブルなコストで実現可能
• VHDX+COW+CAS ベースのワークスペース配布に加えてビルド・アセット配布
• P4リポジトリに配布経路を依存した UnrealGameSync の置き換え
• ビルドしたバイナリ・DDCアセットをVHDXでパッケージ化する
• 数百〜数千人規模の開発者・テスターにCDN経由でVHDXを配布する
• cairn-desync を desync upstream にフィードバック
• 固定チャンクの不具合修正・並列処理性能向上 (VHDX フォーマット最適化)
• ReFS Trusted Base 拡張: Windows での変更ブロック検出および クローン後のインプレース更新対応
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/8EDKPL8K7G.jpg)

今後の展望 2
• ゲーム開発環境は Windows が中心なのでワークスペースには VHDX + NTFS を使わざるを得ないが、
これをそのまま Linux/Kubernetes の世界でも活用できるようにしたい
• MSVC や UnrealEd バイナリを Wine で動かす BuildCookRun が並列処理できる K8s クラスタができるかもしれない
• TensorWorks: Blog: Unreal Engine C++ compilation for Windows under Linux with Wine [1]
• NTFS が入った VHDX イメージを Linux カーネルで直接マウントする
• 可変 VHDX イメージは Block Allocation Table (BAT) を備えており、
これを dm-linear に入力すれば NTFS のイメージが直接見えてカーネルの ntfs3 でマウントできる
• RO NTFS + RW tmpfs の overlayfs で、使い捨て・書き込み可能なワークスペースが Linux カーネルでマウントできる
• K8s Node にマウントする CSI ドライバ: PVC に CAIBX の URL を指定すれば Pod にマウント可能にできる
• VHDX + NTFS ライターの実装
• VHDX 内の NTFS を更新するためにマウント・アンマウントを繰り返すとデータ以外の部分のノイズが増える
• ホストのワークスペースのディレクトリツリーから、クリーンな VHDX + NTFS イメージを直接書き出す
ユーザーランドツールを開発する → 感覚としては mkisofs とか mksquashfs と一緒
• ReFS, ZFS, Btrfs, APFS など各種 COW ファイルシステムのブロッククローンを活用してデータコピーをなくす
[1] https://tensorworks.com.au/blog/unreal-engine-cpp-compilation-for-windows-under-wine/
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/V7PKN283J8.jpg)

Thank You!!
21


