예제 #1
0
        public static VolumeManagerDatabase ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            VolumeManagerDatabaseHeader databaseHeader = VolumeManagerDatabaseHeader.ReadFromDisk(disk, privateHeader, tocBlock);

            if (databaseHeader == null || !databaseHeader.IsVersionSupported)
            {
                return(null);
            }

            // The first VBLK entry is the subsequent entry to the VMDB header.
            // Note: On a disk with 4KB sectors, VBLKs will reside in the same sector as the VMDB header.
            ulong firstSector    = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart; // we skip the VMDB
            int   databaseLength = (int)(databaseHeader.HeaderSize + databaseHeader.NumberOfVBlks * databaseHeader.BlockSize);
            int   sectorCount    = (int)Math.Ceiling(databaseLength / (double)disk.BytesPerSector);

            byte[] databaseBytes     = disk.ReadSectors((long)firstSector, sectorCount);
            int    numberOfFragments = (int)(databaseHeader.NumberOfVBlks - FirstSequenceNumber);
            List <DatabaseRecord> databaseRecords = ReadDatabaseRecords(databaseBytes, (int)databaseHeader.HeaderSize, (int)databaseHeader.BlockSize, numberOfFragments);

            // read all KLog blocks
            KernelUpdateLog kernelUpdateLog = KernelUpdateLog.ReadFromDisk(disk, privateHeader, tocBlock);
            DynamicDisk     dynamicDisk     = new DynamicDisk(disk, privateHeader, tocBlock);

            return(new VolumeManagerDatabaseCopy(dynamicDisk, databaseHeader, databaseRecords, kernelUpdateLog));
        }
예제 #2
0
 public VolumeManagerDatabaseCopy(DynamicDisk disk, VolumeManagerDatabaseHeader databaseHeader, List <DatabaseRecord> databaseRecords, KernelUpdateLog kernelUpdateLog) :
     base(databaseHeader, databaseRecords, kernelUpdateLog)
 {
     m_disk            = disk;
     m_databaseHeader  = databaseHeader;
     m_databaseRecords = databaseRecords;
     m_kernelUpdateLog = kernelUpdateLog;
 }
예제 #3
0
        public VolumeManagerDatabase(VolumeManagerDatabaseHeader databaseHeader, List <DatabaseRecord> databaseRecords, KernelUpdateLog kernelUpdateLog)
        {
            m_databaseHeader  = databaseHeader;
            m_databaseRecords = databaseRecords;
            m_kernelUpdateLog = kernelUpdateLog;

            m_nextRecordID = m_databaseHeader.CommitTransactionID + 1;
        }
        public static VolumeManagerDatabase ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            VolumeManagerDatabaseHeader databaseHeader = VolumeManagerDatabaseHeader.ReadFromDisk(disk, privateHeader, tocBlock);

            if (databaseHeader == null)
            {
                return(null);
            }
            List <DatabaseRecord> databaseRecords = new List <DatabaseRecord>();

            // The first VBLK entry is the subsequent entry to the VMDB, which located at (ConfigurationStartLBA + Item1Start)
            ulong firstSector = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart + 1;  // we skip the VMDB
            int   sectorCount = (int)Math.Ceiling((long)databaseHeader.NumberOfVBlks * databaseHeader.BlockSize / (decimal)disk.BytesPerSector);

            byte[] databaseBytes = disk.ReadSectors((long)firstSector, sectorCount);

            // read all VBLK blocks:
            // Note: fragments are not necessarily contiguous!
            Dictionary <uint, List <DatabaseRecordFragment> > fragments = new Dictionary <uint, List <DatabaseRecordFragment> >();

            for (uint index = 0; index < databaseHeader.NumberOfVBlks - 4; index++)
            {
                byte[] fragmentBytes = new byte[databaseHeader.BlockSize];
#warning long array index not supported
                Array.Copy(databaseBytes, (int)(index * databaseHeader.BlockSize), fragmentBytes, 0, (int)databaseHeader.BlockSize);
                DatabaseRecordFragment fragment = DatabaseRecordFragment.GetDatabaseRecordFragment(fragmentBytes);

                if (fragment != null) // null fragment means VBLK is empty
                {
                    if (fragments.ContainsKey(fragment.GroupNumber))
                    {
                        fragments[fragment.GroupNumber].Add(fragment);
                    }
                    else
                    {
                        List <DatabaseRecordFragment> recordFragments = new List <DatabaseRecordFragment>();
                        recordFragments.Add(fragment);
                        fragments.Add(fragment.GroupNumber, recordFragments);
                    }
                }
            }

            // We have all the fragments and we can now assemble the records:
            // We assume that fragments with lower FragmentNumber appear in the database before fragments
            // of the same group with higher FragmentNumber.
            foreach (List <DatabaseRecordFragment> recorFragments in fragments.Values)
            {
                DatabaseRecord databaseRecord = DatabaseRecord.GetDatabaseRecord(recorFragments);
                databaseRecords.Add(databaseRecord);
            }

            // read all KLog blocks
            KernelUpdateLog kernelUpdateLog = KernelUpdateLog.ReadFromDisk(disk, privateHeader, tocBlock);
            DynamicDisk     dynamicDisk     = new DynamicDisk(disk, privateHeader, tocBlock);
            return(new VolumeManagerDatabase(dynamicDisk, databaseHeader, databaseRecords, kernelUpdateLog));
        }
예제 #5
0
        List <DynamicDisk> m_disks = new List <DynamicDisk>(); // when updating the database, all dynamic disks in the group should be added

        public DiskGroupDatabase(List <DynamicDisk> disks, VolumeManagerDatabaseHeader databaseHeader, List <DatabaseRecord> databaseRecords, KernelUpdateLog kernelUpdateLog)
            : base(databaseHeader, databaseRecords, kernelUpdateLog)
        {
            m_disks = disks;
        }