/// <summary> /// Initiates the build process. /// </summary> /// <param name="baseName">The base name for the VMDK, for example 'foo' to create 'foo.vmdk'.</param> /// <returns>A set of one or more logical files that constitute the VMDK. The first file is /// the 'primary' file that is normally attached to VMs.</returns> public override DiskImageFileSpecification[] Build(string baseName) { if (string.IsNullOrEmpty(baseName)) { throw new ArgumentException("Invalid base file name", "baseName"); } if (Content == null) { throw new InvalidOperationException("No content stream specified"); } if (_diskType != DiskCreateType.Vmfs && _diskType != DiskCreateType.VmfsSparse) { throw new NotImplementedException("Only Vmfs and VmfsSparse disks implemented"); } List <DiskImageFileSpecification> fileSpecs = new List <DiskImageFileSpecification>(); Geometry geometry = Geometry ?? DiskImageFile.DefaultGeometry(Content.Length); Geometry biosGeometry = BiosGeometry ?? Geometry.LbaAssistedBiosGeometry(Content.Length); DescriptorFile baseDescriptor = DiskImageFile.CreateSimpleDiskDescriptor(geometry, biosGeometry, _diskType, _adapterType); if (_diskType == DiskCreateType.Vmfs) { ExtentDescriptor extent = new ExtentDescriptor(ExtentAccess.ReadWrite, Content.Length / 512, ExtentType.Vmfs, baseName + "-flat.vmdk", 0); baseDescriptor.Extents.Add(extent); MemoryStream ms = new MemoryStream(); baseDescriptor.Write(ms); fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vmdk", new PassthroughStreamBuilder(ms))); fileSpecs.Add(new DiskImageFileSpecification(baseName + "-flat.vmdk", new PassthroughStreamBuilder(Content))); } else if (_diskType == DiskCreateType.VmfsSparse) { ExtentDescriptor extent = new ExtentDescriptor(ExtentAccess.ReadWrite, Content.Length / 512, ExtentType.VmfsSparse, baseName + "-sparse.vmdk", 0); baseDescriptor.Extents.Add(extent); MemoryStream ms = new MemoryStream(); baseDescriptor.Write(ms); fileSpecs.Add(new DiskImageFileSpecification(baseName + ".vmdk", new PassthroughStreamBuilder(ms))); fileSpecs.Add(new DiskImageFileSpecification(baseName + "-sparse.vmdk", new VmfsSparseExtentBuilder(Content))); } return(fileSpecs.ToArray()); }
/// <summary> /// Creates a new virtual disk that is a linked clone of an existing disk. /// </summary> /// <param name="path">The path to the new disk</param> /// <param name="type">The type of the new disk</param> /// <param name="parent">The disk to clone</param> /// <returns>The new virtual disk</returns> public static DiskImageFile InitializeDifferencing(string path, DiskCreateType type, string parent) { if (type != DiskCreateType.MonolithicSparse && type != DiskCreateType.TwoGbMaxExtentSparse && type != DiskCreateType.VmfsSparse) { throw new ArgumentException("Differencing disks must be sparse", "type"); } using (DiskImageFile parentFile = new DiskImageFile(parent, FileAccess.Read)) { DescriptorFile baseDescriptor = CreateDifferencingDiskDescriptor(type, parentFile, parent); FileLocator locator = new LocalFileLocator(Path.GetDirectoryName(path)); return(DoInitialize(locator, Path.GetFileName(path), parentFile.Capacity, type, baseDescriptor)); } }
public void InitializeDifferencingRelPath() { DiscFileSystem fs = new InMemoryFileSystem(); DiskImageFile baseFile = DiskImageFile.Initialize(fs, @"\dir\subdir\base.vmdk", 16 * 1024L * 1024 * 1024, DiskCreateType.MonolithicSparse); using (Disk disk = Disk.InitializeDifferencing(fs, @"\dir\diff.vmdk", DiskCreateType.MonolithicSparse, @"subdir\base.vmdk")) { Assert.IsNotNull(disk); Assert.That(disk.Geometry.Capacity > 15.8 * 1024L * 1024 * 1024 && disk.Geometry.Capacity < 16 * 1024L * 1024 * 1024); Assert.That(disk.Content.Length == 16 * 1024L * 1024 * 1024); Assert.AreEqual(2, new List <VirtualDiskLayer>(disk.Layers).Count); } Assert.Greater(fs.GetFileLength(@"\dir\diff.vmdk"), 2 * 1024 * 1024); Assert.Less(fs.GetFileLength(@"\dir\diff.vmdk"), 4 * 1024 * 1024); }
/// <summary> /// Creates a new virtual disk that is a linked clone of an existing disk. /// </summary> /// <param name="fileSystem">The file system to create the VMDK on.</param> /// <param name="path">The path to the new disk.</param> /// <param name="type">The type of the new disk.</param> /// <param name="parent">The disk to clone.</param> /// <returns>The new virtual disk.</returns> public static DiskImageFile InitializeDifferencing(DiscFileSystem fileSystem, string path, DiskCreateType type, string parent) { if (type != DiskCreateType.MonolithicSparse && type != DiskCreateType.TwoGbMaxExtentSparse && type != DiskCreateType.VmfsSparse) { throw new ArgumentException("Differencing disks must be sparse", "type"); } string basePath = Utilities.GetDirectoryFromPath(path); FileLocator locator = new DiscFileLocator(fileSystem, basePath); FileLocator parentLocator = locator.GetRelativeLocator(Utilities.GetDirectoryFromPath(parent)); using (DiskImageFile parentFile = new DiskImageFile(parentLocator, Utilities.GetFileFromPath(parent), FileAccess.Read)) { DescriptorFile baseDescriptor = CreateDifferencingDiskDescriptor(type, parentFile, parent); return(DoInitialize(locator, Utilities.GetFileFromPath(path), parentFile.Capacity, type, baseDescriptor)); } }
private static DiskCreateType DiffDiskCreateType(VirtualDiskLayer layer) { DiskImageFile vmdkLayer = layer as DiskImageFile; if (vmdkLayer != null) { switch (vmdkLayer.CreateType) { case DiskCreateType.FullDevice: case DiskCreateType.MonolithicFlat: case DiskCreateType.MonolithicSparse: case DiskCreateType.PartitionedDevice: case DiskCreateType.StreamOptimized: case DiskCreateType.TwoGbMaxExtentFlat: case DiskCreateType.TwoGbMaxExtentSparse: return(DiskCreateType.MonolithicSparse); default: return(DiskCreateType.VmfsSparse); } } return(DiskCreateType.MonolithicSparse); }
protected override List <BuilderExtent> FixExtents(out long totalLength) { List <BuilderExtent> extents = new List <BuilderExtent>(); ServerSparseExtentHeader header = DiskImageFile.CreateServerSparseExtentHeader(_content.Length); GlobalDirectoryExtent gdExtent = new GlobalDirectoryExtent(header); long grainTableStart = header.GdOffset * Sizes.Sector + gdExtent.Length; long grainTableCoverage = header.NumGTEsPerGT * header.GrainSize * Sizes.Sector; foreach (Range <long, long> grainTableRange in StreamExtent.Blocks(_content.Extents, grainTableCoverage)) { for (int i = 0; i < grainTableRange.Count; ++i) { long grainTable = grainTableRange.Offset + i; long dataStart = grainTable * grainTableCoverage; GrainTableExtent gtExtent = new GrainTableExtent(grainTableStart, new SubStream(_content, dataStart, Math.Min(grainTableCoverage, _content.Length - dataStart)), header); extents.Add(gtExtent); gdExtent.SetEntry((int)grainTable, (uint)(grainTableStart / Sizes.Sector)); grainTableStart += gtExtent.Length; } } extents.Insert(0, gdExtent); header.FreeSector = (uint)(grainTableStart / Sizes.Sector); byte[] buffer = header.GetBytes(); extents.Insert(0, new BuilderBufferExtent(0, buffer)); totalLength = grainTableStart; return(extents); }
internal Disk(DiskImageFile file, Ownership ownsStream) { _files = new List <Tuple <DiskImageFile, Ownership> >(); _files.Add(new Tuple <DiskImageFile, Ownership>(file, ownsStream)); ResolveFileChain(); }
/// <summary> /// Creates a new virtual disk as a thin clone of an existing disk. /// </summary> /// <param name="fileSystem">The file system to contain the disk</param> /// <param name="path">The path to the new disk.</param> /// <param name="type">The type of disk to create</param> /// <param name="parentPath">The path to the parent disk.</param> /// <returns>The new disk.</returns> public static Disk InitializeDifferencing(DiscFileSystem fileSystem, string path, DiskCreateType type, string parentPath) { return(new Disk(DiskImageFile.InitializeDifferencing(fileSystem, path, type, parentPath), Ownership.Dispose)); }
internal static Disk Initialize(FileLocator fileLocator, string path, DiskParameters parameters) { return(new Disk(DiskImageFile.Initialize(fileLocator, path, parameters), Ownership.Dispose)); }
/// <summary> /// Creates a new virtual disk at the specified location on a file system. /// </summary> /// <param name="fileSystem">The file system to contain the disk</param> /// <param name="path">The file system path to the disk</param> /// <param name="capacity">The desired capacity of the new disk</param> /// <param name="type">The type of virtual disk to create</param> /// <param name="adapterType">The type of virtual disk adapter</param> /// <returns>The newly created disk image</returns> public static Disk Initialize(DiscFileSystem fileSystem, string path, long capacity, DiskCreateType type, DiskAdapterType adapterType) { return(new Disk(DiskImageFile.Initialize(fileSystem, path, capacity, type, adapterType), Ownership.Dispose)); }
/// <summary> /// Creates a new virtual disk at the specified path. /// </summary> /// <param name="path">The name of the VMDK to create.</param> /// <param name="capacity">The desired capacity of the new disk</param> /// <param name="geometry">The desired geometry of the new disk, or <c>null</c> for default</param> /// <param name="type">The type of virtual disk to create</param> /// <param name="adapterType">The type of virtual disk adapter</param> /// <returns>The newly created disk image</returns> public static Disk Initialize(string path, long capacity, Geometry geometry, DiskCreateType type, DiskAdapterType adapterType) { return(new Disk(DiskImageFile.Initialize(path, capacity, geometry, type, adapterType), Ownership.Dispose)); }
/// <summary> /// Creates a new virtual disk at the specified path. /// </summary> /// <param name="path">The name of the VMDK to create.</param> /// <param name="parameters">The desired parameters for the new disk.</param> /// <returns>The newly created disk image</returns> public static Disk Initialize(string path, DiskParameters parameters) { return(new Disk(DiskImageFile.Initialize(path, parameters), Ownership.Dispose)); }
private static DescriptorFile CreateDifferencingDiskDescriptor(DiskCreateType type, DiskImageFile parent, string parentPath) { DescriptorFile baseDescriptor = new DescriptorFile(); baseDescriptor.ContentId = (uint)_rng.Next(); baseDescriptor.ParentContentId = parent.ContentId; baseDescriptor.ParentFileNameHint = parentPath; baseDescriptor.CreateType = type; return(baseDescriptor); }
internal Disk(DiskImageFile file, Ownership ownsStream) { _files = new List<DiscUtils.Tuple<VirtualDiskLayer, Ownership>>(); _files.Add(new DiscUtils.Tuple<VirtualDiskLayer, Ownership>(file, ownsStream)); ResolveFileChain(); }
/// <summary> /// Creates a new virtual disk that is a linked clone of an existing disk. /// </summary> /// <param name="fileSystem">The file system to create the VMDK on</param> /// <param name="path">The path to the new disk</param> /// <param name="type">The type of the new disk</param> /// <param name="parent">The disk to clone</param> /// <returns>The new virtual disk</returns> public static DiskImageFile InitializeDifferencing(DiscFileSystem fileSystem, string path, DiskCreateType type, string parent) { if (type != DiskCreateType.MonolithicSparse && type != DiskCreateType.TwoGbMaxExtentSparse && type != DiskCreateType.VmfsSparse) { throw new ArgumentException("Differencing disks must be sparse", "type"); } string basePath = Path.GetDirectoryName(path); FileLocator locator = new DiscFileLocator(fileSystem, basePath); FileLocator parentLocator = locator.GetRelativeLocator(Path.GetDirectoryName(parent)); using (DiskImageFile parentFile = new DiskImageFile(parentLocator, Path.GetFileName(parent), FileAccess.Read)) { DescriptorFile baseDescriptor = CreateDifferencingDiskDescriptor(type, parentFile, parent); return DoInitialize(locator, Path.GetFileName(path), parentFile.Capacity, type, baseDescriptor); } }
private static DescriptorFile CreateDifferencingDiskDescriptor(DiskCreateType type, DiskImageFile parent, string parentPath) { DescriptorFile baseDescriptor = new DescriptorFile(); baseDescriptor.ContentId = (uint)_rng.Next(); baseDescriptor.ParentContentId = parent.ContentId; baseDescriptor.ParentFileNameHint = parentPath; baseDescriptor.CreateType = type; return baseDescriptor; }
internal Disk(DiskImageFile file, Ownership ownsStream) { _files = new List <DiscUtils.Tuple <VirtualDiskLayer, Ownership> >(); _files.Add(new DiscUtils.Tuple <VirtualDiskLayer, Ownership>(file, ownsStream)); ResolveFileChain(); }