読者です 読者をやめる 読者になる 読者になる

Drive 作成前に PageBlob を作成する必要はない

f:id:griefworker:20101013211832p:image

Windows Azure の本番環境で Drive を作成するとき、事前に PageBlob を作成しておく必要はないです。もし PageBlob を作成していたら、Mount するときに

Unknown Error HRESULT=D000000D

というエラーが発生してしまいます。


原因がわからず MSDN フォーラムで質問したところ、id:StateMachine さんがアドバイスをくれました。

Driveを作成するのに、あらかじめPageBlobを作成しておく必要はなかったと思います。

したがってコンテナだけ作成しておいて、PageBlobを作らない状態で、以下のようにすれば動くと思います。CreateでPageBlobの作成とNTFSフォーマット的なことをしているはずです。

例外が出るのは、ゼロページで書き込まれたPageBlobをマウントしようとしたからではないかと推測します。

Windows Azure 実環境上で CloudDrive の Mount メソッドが Unknown Error を発生させる

CloudDrive.Create で本来行われるはずの PageBlob 初期化が、事前に PageBlob を作成したため行われなかったことが原因かもしれません。


本番環境で動いたコードはこちら。

// cscfg ファイルに記述して接続文字列を指定して、アカウント作成
CloudStorageAccount account = CloudStorageAccount.FromConfigurationSetting("MyStorage");

// キャッシュの初期化
// 最大サイズは100MB
LocalResource localCache = RoleEnvironment.GetLocalResource("MyCache");
CloudDrive.InitializeCache(localCache.RootPath + "cache", localCache.MaximumSizeInMegabytes);

// Blob コンテナが無ければ作成する
CloudBlobClient blobClient = account.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference("drives");
blobContainer.CreateIfNotExist();

// Drive を作成
CloudDrive drive = account.CreateCloudDrive("drives/mydrive.vhd");
try
{
    drive.Create(80);
}
catch (CloudDriveException)
{
    // Drive が既に存在すれば例外が発生するので、
    // 今回は握りつぶす
}

// Drive をマウントする
string driveLetter = _drive.Mount(20, DriveMountOptions.None);

// 取得したドライブレターを使ってファイル作成
string path = driveLetter + "Sample.txt";
using (StreamWriter writer = new StreamWriter(path))
{
    writer.Write("Test");
}

// Drive をマウント解除
drive.Unmount();

CloudDrive の Create メソッドで、PageBlob の作成もやってくれます。


それにしても、Development Storage でうっかり動いちゃうのは困りますね。そのまま本番環境にデプロイして、見事にハマってしまいました。ネット上にも事前に PageBlob を作成しているサンプルを結構見かけますが、私以外にハマった人っていないのかな。