コード例 #1
0
        // Initializes the LU registration details from the incoming payload.
        private void InitLURegistration()
        {
            byte[] arrPayload      = new byte[SizePayloadBuffer];
            int    iTotalBytesRead = SFBlockStoreCommunicationListener.FetchDataFromTransport(ClientStream, PipeServer, arrPayload, (int)SizePayloadBuffer);

            // Did we get a buffer of expected size?
            if (iTotalBytesRead != SizePayloadBuffer)
            {
                throw new InvalidOperationException(String.Format("SFBlockstoreService::InitLURegistration: Malformed request of size {0} encountered; expected size is {1}", iTotalBytesRead, SizePayloadBuffer));
            }

            // Create a BinaryReader around the incoming array to parse the data out of it
            MemoryStream msPayload = new MemoryStream(arrPayload);
            BinaryReader reader    = new BinaryReader(msPayload);

            // Read the LU registration information
            LengthLUID = reader.ReadUInt32();

            // Read the Disk size
            DiskSize = reader.ReadUInt32();

            // Read the Disk size unit
            DiskSizeUnit = reader.ReadUInt32();

            // Read the Mount status
            Mounted = reader.ReadUInt32();

            // Read the LUID
            byte[] arrLUID = reader.ReadBytes((int)LengthLUID);
            unsafe
            {
                fixed(byte *pLUID = arrLUID)
                {
                    IntPtr ptrLUID = new IntPtr(pLUID);

                    LUID = Marshal.PtrToStringUni(ptrLUID);
                }
            }

            reader.Close();
        }
コード例 #2
0
        private void FetchRegisteredLUList(IBSManager bsManager, CancellationToken cancellationToken)
        {
            ValidateArgs(false);

            // This request comes with a blockSizeManagementRequest sized empty payload buffer. Fetch that from the stream
            // to get it out of the way so that we have completed reading the header+(empty)payload.
            uint LengthBuffer = SizePayloadBuffer;

            byte[] arrPayload         = new byte[LengthBuffer];
            int    bytesToRead        = (int)LengthBuffer;
            int    iTotalBytesFetched = SFBlockStoreCommunicationListener.FetchDataFromTransport(ClientStream, PipeServer, arrPayload, bytesToRead);

            // Did we get a buffer of expected size?
            if (iTotalBytesFetched != bytesToRead)
            {
                throw new InvalidOperationException(String.Format("SFBlockstoreService::FetchRegisteredLUList: Malformed request of size {0} encountered; expected size is {1}", iTotalBytesFetched, bytesToRead));
            }

            Console.WriteLine("SFBlockstoreService::FetchRegisteredLUList: Fetching registered LUs");

            // Prepare to write the outgoing data
            MemoryStream msPayload = new MemoryStream((int)GatewayPayloadConst.blockSizeManagementRequest);
            BinaryWriter writer    = new BinaryWriter(msPayload);

            // Registrated LU List format is as follows:
            //
            // <Number of Entries>
            // LengthLUID            <-- Entry starts here
            // DiskSize
            // DiskSizeUnit
            // Mounted
            // LUID                  <-- Entry ends here
            //
            // ...repeat

            Task <ArrayList> listLU           = bsManager.FetchLURegistrations(DeviceID, cancellationToken);
            ArrayList        listRegisteredLU = listLU.Result;
            int iLURegistrations = (listRegisteredLU != null)?listRegisteredLU.Count:0;

            if (iLURegistrations > 0)
            {
                // Write the number of registration entries
                if (iLURegistrations > GatewayPayloadConst.maxLURegistrations)
                {
                    Console.WriteLine("SFBlockstoreService::FetchRegisteredLUList: Trimming LU registration list from {0} to {1}", iLURegistrations, GatewayPayloadConst.maxLURegistrations);
                    iLURegistrations = GatewayPayloadConst.maxLURegistrations;
                }

                writer.Write(iLURegistrations);

                // Loop through each registration to compose the payload
                int iIndex = 0;
                foreach (string entry in listRegisteredLU)
                {
                    if (iIndex < iLURegistrations)
                    {
                        // Split the entry into LUID and Registration info
                        string[] arrData = entry.Split(new string[] { "::" }, StringSplitOptions.None);

                        // Add the NULL to the string when sending across the wire.
                        string szLUID = arrData[0] + "\0";

                        // Convert the LUID to byte array
                        byte[] arrLUID = System.Text.Encoding.Unicode.GetBytes(szLUID);

                        // Write the length of LUID in bytes (and not characters)
                        writer.Write(arrLUID.Length);

                        // Get the Disksize and Size unit
                        string[] arrDiskSizeData = arrData[1].Split(new char[] { '_' });

                        // Write the DiskSize
                        writer.Write(Int32.Parse(arrDiskSizeData[0]));

                        // Write the DiskSize Unit
                        writer.Write(Int32.Parse(arrDiskSizeData[1]));

                        // Write the Mounted status
                        writer.Write(Int32.Parse(arrDiskSizeData[2]));

                        // Finally, write the LUID
                        writer.Write(arrLUID);

                        iIndex++;
                    }
                    else
                    {
                        break;
                    }
                }

                Console.WriteLine("SFBlockstoreService::FetchRegisteredLUList: Fetched {0} LU registrations", iLURegistrations);
            }
            else
            {
                iLURegistrations = 0;
                writer.Write(iLURegistrations);
                Console.WriteLine("SFBlockstoreService::FetchRegisteredLUList: No LU registrations found.");
            }

            // Set the payload and its actual length so that
            // the right amount of data is copied from the payload
            // we send (including nothing when the payload is empty).
            PayloadData       = msPayload.GetBuffer();
            SizePayloadBuffer = (uint)msPayload.ToArray().Length;

            Console.WriteLine("SFBlockstoreService::FetchRegisteredLUList: Returned payload size is {0}.", SizePayloadBuffer);

            writer.Close();

            // Set mode to indicate success
            Mode = BlockMode.OperationCompleted;
        }
コード例 #3
0
        private void WriteBlocksToService(IBSManager bsManager)
        {
            ValidateArgs(true);

            ulong OffsetToWriteFrom = OffsetToRW;
            uint  LengthBuffer      = SizePayloadBuffer;
            ulong endOffset         = OffsetToWriteFrom + LengthBuffer;
            bool  fWriteSuccessful  = true;
            ulong bytesToWrite      = 0;
            ulong bytesWritten      = 0;
            uint  iCopyFromIndex    = 0;

            bool fUseDMA = UseDMA;

            Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Writing blocks device, {0}, at offset {1} for length {2}{3}", DeviceID, OffsetToRW, LengthBuffer, UseDMA ? " [DMA]" : String.Empty);

            byte[] arrPayload = new byte[LengthBuffer];

            if (!fUseDMA)
            {
                // Fetch the data from the network in a single go and loop in block aligned size to write to the service.
                int iTotalBytesFetched = SFBlockStoreCommunicationListener.FetchDataFromTransport(ClientStream, PipeServer, arrPayload, arrPayload.Length);
                if (iTotalBytesFetched != arrPayload.Length)
                {
                    throw new InvalidOperationException(String.Format("SFBlockstoreService::WriteBlocksToService: Malformed write-payload of size {0} encountered; expected size is {1}", iTotalBytesFetched, arrPayload.Length));
                }
            }
            else
            {
                // Get the data from the kernel driver to write to the store.
                uint errorDMA = 0;

                // If we are going to use DMA, then get the reference to the SRB's DataBuffer
                unsafe
                {
                    fixed(byte *pBuffer = arrPayload)
                    {
                        fWriteSuccessful = GetPayloadFromSRB(SRBAddress, pBuffer, LengthBuffer, &errorDMA);
                    }
                }

                if (!fWriteSuccessful)
                {
                    Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Failed to read blocks from memory for SRB {3:X} for device, {0}, at offset {1} for length {2} due to error {4}", DeviceID, OffsetToRW, LengthBuffer, SRBAddress.ToUInt64(), errorDMA);
                }
            }

            if (fWriteSuccessful)
            {
                try
                {
                    List <Task> listTasks = new List <Task>();
                    while (OffsetToWriteFrom < endOffset)
                    {
                        // How many bytes do we need to process from the current offset to end of the corresponding block?
                        bytesToWrite = GatewayPayloadConst.blockSizeDisk - (OffsetToWriteFrom % GatewayPayloadConst.blockSizeDisk);
                        if ((bytesToWrite + OffsetToWriteFrom) >= endOffset)
                        {
                            // We cannot go past the intended length, so adjust the length accordingly.
                            bytesToWrite = endOffset - OffsetToWriteFrom;
                        }

                        Task taskWriteBlock = WriteBlockUnderTransaction(bsManager, OffsetToWriteFrom, bytesToWrite, iCopyFromIndex, arrPayload);
                        listTasks.Add(taskWriteBlock);

                        // Update the counters
                        OffsetToWriteFrom += bytesToWrite;
                        bytesWritten      += bytesToWrite;
                        iCopyFromIndex    += (uint)bytesToWrite;
                    }

                    // Wait for all tasks to complete
                    Task.WaitAll(listTasks.ToArray());
                }
                catch (Exception ex)
                {
                    fWriteSuccessful = false;
                    Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Failed to write blocks to device, {0}, at offset {1} for length {2} due to exception: {3} - {4}", DeviceID, OffsetToRW, LengthBuffer, ex.GetType(), ex.Message);
                }

                // Ensure we processed the expected length of data
                if (bytesWritten != LengthBuffer)
                {
                    Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Incomplete block write for device, {0}, at offset {1} for length {2}. Expected: {3}, Read: {4}", DeviceID, OffsetToRW, LengthBuffer, LengthBuffer, bytesWritten);
                    fWriteSuccessful = false;
                }
            }

            // Reset the payload details before sending a response.
            SizePayloadBuffer = 0;
            PayloadData       = null;

            if (fWriteSuccessful)
            {
                Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Blocks successfully written to device, {0}, at offset {1} for length {2}", DeviceID, OffsetToRW, LengthBuffer);
                Mode = BlockMode.OperationCompleted;
            }
            else
            {
                Console.WriteLine("SFBlockstoreService::WriteBlocksToService: Failed to write blocks to device, {0}, at offset {1} for length {2}", DeviceID, OffsetToRW, LengthBuffer);
                Mode = BlockMode.OperationFailed;
            }
        }
コード例 #4
0
        public static GatewayPayload ParseHeader(byte[] arrPayload, NamedPipeServerStream pipeServer, SFBlockStoreCommunicationListener commListener)
        {
            GatewayPayload payload = new GatewayPayload();

            payload.PipeServer            = pipeServer;
            payload.ClientStream          = null;
            payload.CommunicationListener = commListener;

            InitHeader(arrPayload, ref payload);

            return(payload);
        }