Exemplo n.º 1
0
        /// <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());
        }
Exemplo n.º 2
0
        /// <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));
            }
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        /// <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));
            }
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
 internal Disk(DiskImageFile file, Ownership ownsStream)
 {
     _files = new List <Tuple <DiskImageFile, Ownership> >();
     _files.Add(new Tuple <DiskImageFile, Ownership>(file, ownsStream));
     ResolveFileChain();
 }
Exemplo n.º 8
0
 /// <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));
 }
Exemplo n.º 9
0
 internal static Disk Initialize(FileLocator fileLocator, string path, DiskParameters parameters)
 {
     return(new Disk(DiskImageFile.Initialize(fileLocator, path, parameters), Ownership.Dispose));
 }
Exemplo n.º 10
0
 /// <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));
 }
Exemplo n.º 11
0
 /// <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));
 }
Exemplo n.º 12
0
 /// <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));
 }
Exemplo n.º 13
0
        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);
        }
Exemplo n.º 14
0
 internal Disk(DiskImageFile file, Ownership ownsStream)
 {
     _files = new List<DiscUtils.Tuple<VirtualDiskLayer, Ownership>>();
     _files.Add(new DiscUtils.Tuple<VirtualDiskLayer, Ownership>(file, ownsStream));
     ResolveFileChain();
 }
Exemplo n.º 15
0
        /// <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);
            }
        }
Exemplo n.º 16
0
 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;
 }
Exemplo n.º 17
0
 internal Disk(DiskImageFile file, Ownership ownsStream)
 {
     _files = new List <DiscUtils.Tuple <VirtualDiskLayer, Ownership> >();
     _files.Add(new DiscUtils.Tuple <VirtualDiskLayer, Ownership>(file, ownsStream));
     ResolveFileChain();
 }