Ejemplo n.º 1
0
 public override void WriteDatabaseRecordFragment(DatabaseRecordFragment fragment)
 {
     foreach (DynamicDisk disk in m_disks)
     {
         VolumeManagerDatabase.WriteDatabaseRecordFragment(disk, fragment, (int)this.DatabaseHeader.BlockSize);
     }
 }
        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));
        }
Ejemplo n.º 3
0
        public static void WriteDatabaseRecordFragment(DynamicDisk disk, DatabaseRecordFragment fragment, int blockSize)
        {
            if (fragment.SequenceNumber < FirstSequenceNumber)
            {
                throw new ArgumentException("VBLK SequenceNumber must start from 4");
            }

            PrivateHeader privateHeader      = disk.PrivateHeader;
            TOCBlock      tocBlock           = disk.TOCBlock;
            ulong         sectorIndex        = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart;
            int           fragmentsPerSector = (int)(disk.Disk.BytesPerSector / blockSize);

            sectorIndex += (ulong)(fragment.SequenceNumber / fragmentsPerSector);
            byte[] sectorBytes   = disk.Disk.ReadSector((long)sectorIndex);
            byte[] fragmentBytes = fragment.GetBytes(blockSize); // should we use the same database header?
            int    indexInSector = (int)(fragment.SequenceNumber % fragmentsPerSector);

            Array.Copy(fragmentBytes, 0, sectorBytes, indexInSector * blockSize, blockSize);
            disk.Disk.WriteSectors((long)sectorIndex, sectorBytes);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Return record fragments containing updated record data.
        /// SequenceNumber and GroupNumber have to be set before writing these fragments to the database.
        /// </summary>
        private static List <DatabaseRecordFragment> GetUpdatedFragments(int blockSize, byte[] data)
        {
            int fragmentDataLength = blockSize - DatabaseRecordFragment.HeaderLength;
            int fragmentCount      = (int)Math.Ceiling((double)data.Length / fragmentDataLength);

            List <DatabaseRecordFragment> result = new List <DatabaseRecordFragment>();
            int dataOffset = 0;

            for (int numberInGroup = 0; numberInGroup < fragmentCount; numberInGroup++)
            {
                DatabaseRecordFragment fragment = new DatabaseRecordFragment();
                fragment.NumberInGroup = (ushort)numberInGroup;
                fragment.FragmentCount = (ushort)fragmentCount;

                fragment.Data = new byte[fragmentDataLength];
                int currentDataLength = Math.Min((int)fragmentDataLength, data.Length - dataOffset);
                Array.Copy(data, dataOffset, fragment.Data, 0, currentDataLength);
                dataOffset += currentDataLength;
                result.Add(fragment);
            }
            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Will read all VBLK blocks and assemble the database records
        /// </summary>
        /// <param name="numberOfFragments">number of fragments excluding the database header</param>
        private static List <DatabaseRecord> ReadDatabaseRecords(byte[] databaseBytes, int headerSize, int fragmentSize, int numberOfFragments)
        {
            // Note: fragments are not necessarily contiguous!
            Dictionary <uint, List <DatabaseRecordFragment> > fragments = new Dictionary <uint, List <DatabaseRecordFragment> >();

            for (uint index = 0; index < numberOfFragments; index++)
            {
                byte[] fragmentBytes  = new byte[fragmentSize];
                int    fragmentOffset = (int)(headerSize + index * fragmentSize);
                Array.Copy(databaseBytes, fragmentOffset, fragmentBytes, 0, fragmentSize);
                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.
            List <DatabaseRecord> databaseRecords = new List <DatabaseRecord>();

            foreach (List <DatabaseRecordFragment> recordFragments in fragments.Values)
            {
                DatabaseRecord databaseRecord = DatabaseRecord.GetDatabaseRecord(recordFragments);
                databaseRecords.Add(databaseRecord);
            }
            return(databaseRecords);
        }
Ejemplo n.º 6
0
 public override void WriteDatabaseRecordFragment(DatabaseRecordFragment fragment)
 {
     WriteDatabaseRecordFragment(m_disk, fragment, (int)m_databaseHeader.BlockSize);
 }
Ejemplo n.º 7
0
 public abstract void WriteDatabaseRecordFragment(DatabaseRecordFragment fragment);
 virtual protected void WriteDatabaseRecordFragment(DatabaseRecordFragment fragment)
 {
     WriteDatabaseRecordFragment(m_disk, fragment, (int)m_databaseHeader.BlockSize);
 }