/// <summary> /// Tries to resize the VHD file, using the parameters specified. /// </summary> /// <param name="newSizeInGb">The new size of the VHD file, in gigabytes.</param> /// <param name="blobUri">The <see cref="Uri"/> to locate the VHD in the Azure Storage account.</param> /// <param name="accountName">The name of the Azure Storage account.</param> /// <param name="accountKey">The key of the Azure Storage account.</param> /// <returns>Returns <see cref="ResizeResult.Error"/> if there were issues while trying to do the resize operation. /// Returns <see cref="ResizeResult.Shrink"/> if this is a shrink operation which needs user confirmation. /// Returns <see cref="ResizeResult.Success"/> if everything went fine.</returns> public ResizeResult ResizeVhdBlob(int newSizeInGb, Uri blobUri, string accountName, string accountKey) { NewSize = ByteSize.FromGigaBytes(newSizeInGb); // Check if blob exists blob = new CloudPageBlob(blobUri); if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) { blob = new CloudPageBlob(blobUri, new StorageCredentials(accountName, accountKey)); } try { if (!blob.Exists()) { Console.WriteLine("The specified blob does not exist."); return(ResizeResult.Error); } } catch (StorageException ex) { Console.WriteLine("The specified storage account credentials are invalid. " + ex.ToString()); return(ResizeResult.Error); } // Determine blob attributes Console.WriteLine("[{0}] Determining blob size...", DateTime.Now.ToShortTimeString()); blob.FetchAttributes(); originalLength = blob.Properties.Length; // Read current footer Console.WriteLine("[{0}] Reading VHD file format footer...", DateTime.Now.ToShortTimeString()); footer = new byte[512]; using (var stream = new MemoryStream()) { blob.DownloadRangeToStream(stream, originalLength - 512, 512); stream.Position = 0; stream.Read(footer, 0, 512); stream.Close(); } footerInstance = Footer.FromBytes(footer, 0); // Make sure this is a "fixed" disk if (footerInstance.DiskType != FileType.Fixed) { Console.WriteLine("The specified VHD blob is not a fixed-size disk. WindowsAzureDiskResizer can only resize fixed-size VHD files."); return(ResizeResult.Error); } if (footerInstance.CurrentSize >= (long)NewSize.Bytes) { // The specified VHD blob is larger than the specified new size. Shrinking disks is a potentially dangerous operation // Ask the user for confirmation return(ResizeResult.Shrink); } return(DoResizeVhdBlob()); }
private static int ResizeVhdBlob(long newSize, Uri blobUri, string accountName, string accountKey) { bool isExpand = true; // Check if blob exists var blob = new CloudPageBlob(blobUri); if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) { blob = new CloudPageBlob(blobUri, new StorageCredentials(accountName, accountKey)); } try { if (!blob.Exists()) { Console.WriteLine("The specified blob does not exist."); return(-1); } } catch (StorageException ex) { Console.WriteLine("The specified storage account credentials are invalid."); return(-1); } // Determine blob attributes Console.WriteLine("[{0}] Determining blob size...", DateTime.Now.ToShortTimeString()); blob.FetchAttributes(); var originalLength = blob.Properties.Length; // Read current footer Console.WriteLine("[{0}] Reading VHD file format footer...", DateTime.Now.ToShortTimeString()); var footer = new byte[512]; using (Stream stream = new MemoryStream()) { blob.DownloadRangeToStream(stream, originalLength - 512, 512); stream.Position = 0; stream.Read(footer, 0, 512); stream.Close(); } var footerInstance = Footer.FromBytes(footer, 0); // Make sure this is a "fixed" disk if (footerInstance.DiskType != FileType.Fixed) { Console.WriteLine("The specified VHD blob is not a fixed-size disk. WindowsAzureDiskResizer can only resize fixed-size VHD files."); return(-1); } if (footerInstance.CurrentSize >= newSize) { Console.WriteLine("The specified VHD blob is larger than the specified new size. Shrinking disks is a potentially dangerous operation."); Console.WriteLine("Do you want to continue with shrinking the disk? (y/n)"); while (true) { var consoleKey = Console.ReadKey().KeyChar; if (consoleKey == 'n') { Console.WriteLine("Aborted."); return(-1); } if (consoleKey == 'y') { isExpand = false; break; } } } Console.WriteLine("[{0}] VHD file format fixed, current size {1} bytes.", DateTime.Now.ToShortTimeString(), footerInstance.CurrentSize); // Expand the blob Console.WriteLine("[{0}] Resizing containing blob...", DateTime.Now.ToShortTimeString()); blob.Resize(newSize + 512); // Change footer size values Console.WriteLine("[{0}] Updating VHD file format footer...", DateTime.Now.ToShortTimeString()); footerInstance.CurrentSize = newSize; footerInstance.OriginalSize = newSize; footerInstance.Geometry = Geometry.FromCapacity(newSize); footerInstance.UpdateChecksum(); footer = new byte[512]; footerInstance.ToBytes(footer, 0); Console.WriteLine("[{0}] New VHD file size {1} bytes, checksum {2}.", DateTime.Now.ToShortTimeString(), footerInstance.CurrentSize, footerInstance.Checksum); // Write new footer Console.WriteLine("[{0}] Writing VHD file format footer...", DateTime.Now.ToShortTimeString()); using (Stream stream = new MemoryStream(footer)) { blob.WritePages(stream, newSize); } // Write 0 values where the footer used to be if (isExpand) { Console.WriteLine("[{0}] Overwriting the old VHD file footer with zeroes...", DateTime.Now.ToShortTimeString()); blob.ClearPages(originalLength - 512, 512); } // Done! Console.WriteLine("[{0}] Done!", DateTime.Now.ToShortTimeString()); return(0); }