Beispiel #1
0
        /// <summary>
        /// Gets the logical volumes held across the set of managed disks.
        /// </summary>
        /// <returns>An array of logical volumes.</returns>
        public LogicalVolumeInfo[] GetLogicalVolumes()
        {
            List <LogicalVolumeInfo> result = new List <LogicalVolumeInfo>();

            foreach (var vg in _volumeGroups)
            {
                foreach (var lv in vg.LogicalVolumes)
                {
                    var  pvs                   = new Dictionary <string, PhysicalVolume>();
                    bool allPvsAvailable       = true;
                    bool segmentTypesSupported = true;
                    foreach (var segment in lv.Segments)
                    {
                        if (segment.Type != SegmentType.Striped)
                        {
                            segmentTypesSupported = false;
                        }
                        foreach (var stripe in segment.Stripes)
                        {
                            var pvAlias = stripe.PhysicalVolumeName;
                            if (!pvs.ContainsKey(pvAlias))
                            {
                                var pvm = GetPhysicalVolumeMetadata(pvAlias);
                                if (pvm == null)
                                {
                                    allPvsAvailable = false;
                                    break;
                                }
                                var pv = GetPhysicalVolume(pvm.Id);
                                if (pv == null)
                                {
                                    allPvsAvailable = false;
                                    break;
                                }
                                pvs.Add(pvm.Name, pv);
                            }
                        }
                        if (!allPvsAvailable || !segmentTypesSupported)
                        {
                            break;
                        }
                    }
                    if (allPvsAvailable && segmentTypesSupported)
                    {
                        LogicalVolumeInfo lvi = new LogicalVolumeInfo(
                            lv.Identity,
                            null,
                            lv.Open(pvs, vg.ExtentSize),
                            lv.ExtentCount * (long)vg.ExtentSize * PhysicalVolume.SECTOR_SIZE,
                            0,
                            DiscUtils.LogicalVolumeStatus.Healthy);
                        result.Add(lvi);
                    }
                }
            }
            return(result.ToArray());
        }
Beispiel #2
0
        private void GetChildren(string path, bool recurse, bool namesOnly)
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            object obj = FindItemByPath(path, false, true);

            if (obj is VirtualDisk)
            {
                VirtualDisk vd = (VirtualDisk)obj;
                EnumerateDisk(vd, path, recurse, namesOnly);
            }
            else if (obj is LogicalVolumeInfo)
            {
                LogicalVolumeInfo lvi = (LogicalVolumeInfo)obj;

                bool           dispose;
                DiscFileSystem fs = GetFileSystem(lvi, out dispose);
                try
                {
                    if (fs != null)
                    {
                        EnumerateDirectory(fs.Root, path, recurse, namesOnly);
                    }
                }
                finally
                {
                    if (dispose && fs != null)
                    {
                        fs.Dispose();
                    }
                }
            }
            else if (obj is DiscDirectoryInfo)
            {
                DiscDirectoryInfo ddi = (DiscDirectoryInfo)obj;
                EnumerateDirectory(ddi, path, recurse, namesOnly);
            }
            else
            {
                WriteError(new ErrorRecord(
                               new InvalidOperationException("Unrecognized object type: " + (obj != null ? obj.GetType() : null)),
                               "UnknownObjectType",
                               ErrorCategory.ParserError,
                               obj));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Dump the FileEntries from a Logical Volume asynchronously
        /// </summary>
        /// <param name="volume">The Volume to dump</param>
        /// <param name="parentPath">The Path to the parent Disc</param>
        /// <param name="options">Extractor Options to use</param>
        /// <param name="governor">Resource Governor to use</param>
        /// <param name="Context">Extractor context to use</param>
        /// <param name="parent">The Parent FilEntry</param>
        /// <returns></returns>
        public static async IAsyncEnumerable <FileEntry> DumpLogicalVolumeAsync(LogicalVolumeInfo volume, string parentPath, ExtractorOptions options, ResourceGovernor governor, Extractor Context, FileEntry?parent = null)
        {
            DiscUtils.FileSystemInfo[]? fsInfos = null;
            try
            {
                fsInfos = FileSystemManager.DetectFileSystems(volume);
            }
            catch (Exception e)
            {
                Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message);
            }

            foreach (var fsInfo in fsInfos ?? Array.Empty <DiscUtils.FileSystemInfo>())
            {
                using var fs = fsInfo.Open(volume);
                var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList();

                foreach (var file in diskFiles)
                {
                    Stream?      fileStream = null;
                    DiscFileInfo?fi         = null;
                    try
                    {
                        fi = fs.GetFileInfo(file);
                        governor.CheckResourceGovernor(fi.Length);
                        fileStream = fi.OpenRead();
                    }
                    catch (Exception e)
                    {
                        Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity);
                    }
                    if (fileStream != null && fi != null)
                    {
                        var newFileEntry = await FileEntry.FromStreamAsync($"{volume.Identity}{Path.DirectorySeparatorChar}{fi.FullName}", fileStream, parent);

                        var entries = Context.ExtractAsync(newFileEntry, options, governor);
                        await foreach (var entry in entries)
                        {
                            yield return(entry);
                        }
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Gets the logical volumes held across the set of managed disks.
        /// </summary>
        /// <returns>An array of logical volumes.</returns>
        public LogicalVolumeInfo[] GetLogicalVolumes()
        {
            List <LogicalVolumeInfo> result = new List <LogicalVolumeInfo>();

            foreach (DynamicDiskGroup group in _groups.Values)
            {
                foreach (DynamicVolume volume in group.GetVolumes())
                {
                    LogicalVolumeInfo lvi = new LogicalVolumeInfo(
                        volume.Identity,
                        null,
                        volume.Open,
                        volume.Length,
                        volume.BiosType,
                        volume.Status);
                    result.Add(lvi);
                }
            }

            return(result.ToArray());
        }
Beispiel #5
0
        public IEnumerable <FileEntry> DumpLogicalVolume(LogicalVolumeInfo volume, string parentPath, FileEntry parent = null)
        {
            DiscUtils.FileSystemInfo[] fsInfos = null;
            try
            {
                fsInfos = FileSystemManager.DetectFileSystems(volume);
            }
            catch (Exception e)
            {
                Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message);
            }

            foreach (var fsInfo in fsInfos ?? new DiscUtils.FileSystemInfo[] { })
            {
                using (var fs = fsInfo.Open(volume))
                {
                    var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList();

                    foreach (var file in diskFiles)
                    {
                        Stream       fileStream = null;
                        DiscFileInfo fi         = null;
                        try
                        {
                            fi         = fs.GetFileInfo(file);
                            fileStream = fi.OpenRead();
                        }
                        catch (Exception e)
                        {
                            Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity);
                        }
                        if (fileStream != null && fi != null)
                        {
                            yield return(FileEntry.FromStream($"{volume.Identity}{Path.DirectorySeparatorChar}{fi.FullName}", fileStream, parent));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Gets the logical volumes held across the set of managed disks.
        /// </summary>
        /// <returns>An array of logical volumes</returns>
        public LogicalVolumeInfo[] GetLogicalVolumes()
        {
            List<LogicalVolumeInfo> result = new List<LogicalVolumeInfo>();
            foreach (var group in _groups.Values)
            {
                foreach (var volume in group.GetVolumes())
                {
                    LogicalVolumeInfo lvi = new LogicalVolumeInfo(
                        volume.Identity,
                        null,
                        volume.Open,
                        volume.Length,
                        volume.BiosType,
                        volume.Status);
                    result.Add(lvi);
                }
            }

            return result.ToArray();
        }
Beispiel #7
0
        /// <summary>
        /// Dump the FileEntries from a Logical Volume
        /// </summary>
        /// <param name="volume">The Volume to dump</param>
        /// <param name="parentPath">The Path to the parent Disc</param>
        /// <param name="options">Extractor Options to use</param>
        /// <param name="governor">Resource Governor to use</param>
        /// <param name="Context">Extractor context to use</param>
        /// <param name="parent">The Parent FilEntry</param>
        /// <returns></returns>
        public static IEnumerable <FileEntry> DumpLogicalVolume(LogicalVolumeInfo volume, string parentPath, ExtractorOptions options, ResourceGovernor governor, Extractor Context, FileEntry?parent = null)
        {
            DiscUtils.FileSystemInfo[]? fsInfos = null;
            try
            {
                fsInfos = FileSystemManager.DetectFileSystems(volume);
            }
            catch (Exception e)
            {
                Logger.Debug("Failed to get file systems from logical volume {0} Image {1} ({2}:{3})", volume.Identity, parentPath, e.GetType(), e.Message);
            }

            foreach (var fsInfo in fsInfos ?? Array.Empty <DiscUtils.FileSystemInfo>())
            {
                using var fs = fsInfo.Open(volume);
                var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList();
                if (options.Parallel)
                {
                    var files = new ConcurrentStack <FileEntry>();

                    while (diskFiles.Any())
                    {
                        var  batchSize   = Math.Min(options.BatchSize, diskFiles.Count);
                        var  range       = diskFiles.GetRange(0, batchSize);
                        var  fileinfos   = new List <(DiscFileInfo, Stream)>();
                        long totalLength = 0;
                        foreach (var r in range)
                        {
                            try
                            {
                                var fi = fs.GetFileInfo(r);
                                totalLength += fi.Length;
                                fileinfos.Add((fi, fi.OpenRead()));
                            }
                            catch (Exception e)
                            {
                                Logger.Debug("Failed to get FileInfo from {0} in Volume {1} @ {2} ({3}:{4})", r, volume.Identity, parentPath, e.GetType(), e.Message);
                            }
                        }

                        governor.CheckResourceGovernor(totalLength);

                        fileinfos.AsParallel().ForAll(file =>
                        {
                            if (file.Item2 != null)
                            {
                                var newFileEntry = new FileEntry($"{volume.Identity}{Path.DirectorySeparatorChar}{file.Item1.FullName}", file.Item2, parent);
                                var entries      = Context.ExtractFile(newFileEntry, options, governor);
                                files.PushRange(entries.ToArray());
                            }
                        });
                        diskFiles.RemoveRange(0, batchSize);

                        while (files.TryPop(out var result))
                        {
                            if (result != null)
                            {
                                yield return(result);
                            }
                        }
                    }
                }
                else
                {
                    foreach (var file in diskFiles)
                    {
                        Stream?fileStream = null;
                        try
                        {
                            var fi = fs.GetFileInfo(file);
                            governor.CheckResourceGovernor(fi.Length);
                            fileStream = fi.OpenRead();
                        }
                        catch (Exception e)
                        {
                            Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity);
                        }
                        if (fileStream != null)
                        {
                            var newFileEntry = new FileEntry($"{volume.Identity}{Path.DirectorySeparatorChar}{file}", fileStream, parent);
                            var entries      = Context.ExtractFile(newFileEntry, options, governor);
                            foreach (var entry in entries)
                            {
                                yield return(entry);
                            }
                        }
                    }
                }
            }
        }