コード例 #1
0
        static Expression <Func <TEntity, bool> > BuildPredicate <TEntity>(object key)
        {
            /*
             * key:
             * 如果实体是单一主键,则传入的 key 与主键属性类型相同的值
             * 如果实体是多主键,则传入的 key 须是包含了与实体主键类型相同的属性的对象,如:new { Key1 = "1", Key2 = "2" }
             */

            Utils.CheckNull(key);

            Type           entityType     = typeof(TEntity);
            TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType);

            EnsureEntityHasPrimaryKey(typeDescriptor);

            KeyValuePairList <MemberInfo, object> keyValueMap = new KeyValuePairList <MemberInfo, object>();

            if (typeDescriptor.PrimaryKeys.Count == 1)
            {
                keyValueMap.Add(typeDescriptor.PrimaryKeys[0].Property, key);
            }
            else
            {
                /*
                 * key: new { Key1 = "1", Key2 = "2" }
                 */

                object multipleKeyObject     = key;
                Type   multipleKeyObjectType = multipleKeyObject.GetType();

                for (int i = 0; i < typeDescriptor.PrimaryKeys.Count; i++)
                {
                    var        keyMemberDescriptor = typeDescriptor.PrimaryKeys[i];
                    MemberInfo keyMember           = multipleKeyObjectType.GetProperty(keyMemberDescriptor.Property.Name);
                    if (keyMember == null)
                    {
                        throw new ArgumentException(string.Format("The input object does not define property for key '{0}'.", keyMemberDescriptor.Property.Name));
                    }

                    object value = keyMember.GetMemberValue(multipleKeyObject);
                    if (value == null)
                    {
                        throw new ArgumentException(string.Format("The primary key '{0}' could not be null.", keyMemberDescriptor.Property.Name));
                    }

                    keyValueMap.Add(keyMemberDescriptor.Property, value);
                }
            }

            ParameterExpression parameter  = Expression.Parameter(entityType, "a");
            Expression          lambdaBody = null;

            foreach (var keyValue in keyValueMap)
            {
                Expression propOrField  = Expression.PropertyOrField(parameter, keyValue.Key.Name);
                Expression wrappedValue = Chloe.Extensions.ExpressionExtension.MakeWrapperAccess(keyValue.Value, keyValue.Key.GetMemberType());
                Expression e            = Expression.Equal(propOrField, wrappedValue);
                lambdaBody = lambdaBody == null ? e : Expression.AndAlso(lambdaBody, e);
            }

            Expression <Func <TEntity, bool> > predicate = Expression.Lambda <Func <TEntity, bool> >(lambdaBody, parameter);

            return(predicate);
        }
コード例 #2
0
        static KeyValuePairList <JoinType, Expression> ResolveJoinInfo(LambdaExpression joinInfoExp)
        {
            /*
             * Usage:
             * var view = context.JoinQuery<User, City, Province, User, City>((user, city, province, user1, city1) => new object[]
             * {
             *     JoinType.LeftJoin, user.CityId == city.Id,
             *     JoinType.RightJoin, city.ProvinceId == province.Id,
             *     JoinType.InnerJoin,user.Id==user1.Id,
             *     JoinType.FullJoin,city.Id==city1.Id
             * }).Select((user, city, province, user1, city1) => new { User = user, City = city, Province = province, User1 = user1, City1 = city1 });
             *
             * To resolve join infomation:
             * JoinType.LeftJoin, user.CityId == city.Id               index of joinType is 0
             * JoinType.RightJoin, city.ProvinceId == province.Id      index of joinType is 2
             * JoinType.InnerJoin,user.Id==user1.Id                    index of joinType is 4
             * JoinType.FullJoin,city.Id==city1.Id                     index of joinType is 6
             */

            NewArrayExpression body = joinInfoExp.Body as NewArrayExpression;

            if (body == null)
            {
                throw new ArgumentException(string.Format("Invalid join infomation '{0}'. The correct usage is like: {1}", joinInfoExp, "context.JoinQuery<User, City>((user, city) => new object[] { JoinType.LeftJoin, user.CityId == city.Id })"));
            }

            KeyValuePairList <JoinType, Expression> ret = new KeyValuePairList <JoinType, Expression>();

            if ((joinInfoExp.Parameters.Count - 1) * 2 != body.Expressions.Count)
            {
                throw new ArgumentException(string.Format("Invalid join infomation '{0}'.", joinInfoExp));
            }

            for (int i = 0; i < joinInfoExp.Parameters.Count - 1; i++)
            {
                /*
                 * 0  0
                 * 1  2
                 * 2  4
                 * 3  6
                 * ...
                 */
                int indexOfJoinType = i * 2;

                Expression joinTypeExpression = body.Expressions[indexOfJoinType];
                object     inputJoinType      = ExpressionEvaluator.Evaluate(joinTypeExpression);
                if (inputJoinType == null || inputJoinType.GetType() != typeof(JoinType))
                {
                    throw new ArgumentException(string.Format("Not support '{0}', please pass correct type of 'Chloe.JoinType'.", joinTypeExpression));
                }

                /*
                 * The next expression of join type must be join condition.
                 */
                Expression joinCondition = body.Expressions[indexOfJoinType + 1].StripConvert();

                if (joinCondition.Type != UtilConstants.TypeOfBoolean)
                {
                    throw new ArgumentException(string.Format("Not support '{0}', please pass correct join condition.", joinCondition));
                }

                ParameterExpression[] parameters = joinInfoExp.Parameters.Take(i + 2).ToArray();

                List <Type> typeArguments = parameters.Select(a => a.Type).ToList();
                typeArguments.Add(UtilConstants.TypeOfBoolean);

                Type             delegateType          = Utils.GetFuncDelegateType(typeArguments.ToArray());
                LambdaExpression lambdaOfJoinCondition = Expression.Lambda(delegateType, joinCondition, parameters);

                ret.Add((JoinType)inputJoinType, lambdaOfJoinCondition);
            }

            return(ret);
        }
コード例 #3
0
        /// <param name="endOfTransferRecorded">True if one or more pages has been filled and the next transfer will be seen as a separate IO transfer</param>
        private void FlushRecords(List <LfsRecord> records, out bool endOfTransferRecorded)
        {
            KeyValuePairList <ulong, LfsRecordPage> pagesToWrite = new KeyValuePairList <ulong, LfsRecordPage>();
            int           bytesAvailableInPage = (int)m_restartPage.LogPageSize - (int)m_restartPage.RestartArea.LogPageDataOffset;
            LfsRecordPage currentPage          = null;
            bool          overwriteTailPage    = false;

            for (int recordIndex = 0; recordIndex < records.Count; recordIndex++)
            {
                LfsRecord record             = records[recordIndex];
                ulong     pageOffsetInFile   = LsnToPageOffsetInFile(record.ThisLsn);
                int       recordOffsetInPage = LsnToRecordOffsetInPage(record.ThisLsn);
                bool      initializeNewPage  = (recordOffsetInPage == m_restartPage.RestartArea.LogPageDataOffset);
                if (initializeNewPage) // We write the record at the beginning of a new page, we must initialize the page
                {
                    currentPage = new LfsRecordPage((int)m_restartPage.LogPageSize, m_restartPage.RestartArea.LogPageDataOffset);
                    currentPage.LastLsnOrFileOffset  = 0;
                    currentPage.LastEndLsn           = 0;
                    currentPage.NextRecordOffset     = m_restartPage.RestartArea.LogPageDataOffset;
                    currentPage.UpdateSequenceNumber = m_nextUpdateSequenceNumber; // There is no rule governing the value of the USN
                    m_nextUpdateSequenceNumber++;

                    pagesToWrite.Add(pageOffsetInFile, currentPage);
                }
                else
                {
                    if (recordIndex == 0) // currentPage == null
                    {
                        if (m_tailPage == null)
                        {
                            m_tailPage             = ReadPage(pageOffsetInFile);;
                            m_tailPageOffsetInFile = pageOffsetInFile;
                        }
                        else if (m_tailPageOffsetInFile != pageOffsetInFile)
                        {
                            throw new InvalidOperationException("LFS log records must be written sequentially");
                        }
                        currentPage       = m_tailPage;
                        overwriteTailPage = true;
                        pagesToWrite.Add(pageOffsetInFile, currentPage);
                    }
                    // currentPage cannot be null when !initializeNewPage && recordIndex > 0
                    System.Diagnostics.Debug.Assert(currentPage != null);
                }
                int bytesAvailableInFirstPage = (int)m_restartPage.LogPageSize - recordOffsetInPage;
                int bytesToWrite   = Math.Min(record.Length, bytesAvailableInFirstPage);
                int bytesRemaining = record.Length - bytesToWrite;
                record.IsMultiPageRecord = (bytesRemaining > 0);
                byte[] recordBytes = record.GetBytes();
                currentPage.WriteBytes(recordOffsetInPage, recordBytes, bytesToWrite);

                currentPage.LastLsnOrFileOffset = record.ThisLsn;
                if (!record.IsMultiPageRecord)
                {
                    currentPage.NextRecordOffset = (ushort)(recordOffsetInPage + bytesToWrite);
                    currentPage.LastEndLsn       = record.ThisLsn;
                    currentPage.HasRecordEnd     = true;
                }

                bool reusePage = !record.IsMultiPageRecord && (bytesAvailableInFirstPage >= m_restartPage.RestartArea.RecordHeaderLength);
                if (!reusePage)
                {
                    currentPage = null;
                }

                while (bytesRemaining > 0)
                {
                    pageOffsetInFile += m_restartPage.LogPageSize;
                    if (pageOffsetInFile == m_restartPage.RestartArea.FileSize)
                    {
                        pageOffsetInFile = m_restartPage.SystemPageSize * 2 + m_restartPage.LogPageSize * 2;
                    }

                    bytesToWrite = Math.Min(bytesRemaining, bytesAvailableInPage);
                    LfsRecordPage nextPage = new LfsRecordPage((int)m_restartPage.LogPageSize, m_restartPage.RestartArea.LogPageDataOffset);
                    Array.Copy(recordBytes, recordBytes.Length - bytesRemaining, nextPage.Data, 0, bytesToWrite);
                    bytesRemaining -= bytesToWrite;

                    nextPage.LastLsnOrFileOffset = record.ThisLsn;
                    if (bytesRemaining == 0)
                    {
                        nextPage.LastEndLsn       = record.ThisLsn;
                        nextPage.NextRecordOffset = (ushort)(m_restartPage.RestartArea.LogPageDataOffset + bytesToWrite);
                        nextPage.Flags           |= LfsRecordPageFlags.RecordEnd;
                        int  bytesAvailableInLastPage = (int)m_restartPage.LogPageSize - ((int)m_restartPage.RestartArea.LogPageDataOffset + bytesToWrite);
                        bool reuseLastPage            = (bytesAvailableInLastPage >= m_restartPage.RestartArea.RecordHeaderLength);
                        if (reuseLastPage)
                        {
                            currentPage = nextPage;
                        }
                    }
                    nextPage.UpdateSequenceNumber = m_nextUpdateSequenceNumber; // There is no rule governing the value of the USN
                    m_nextUpdateSequenceNumber++;
                    pagesToWrite.Add(pageOffsetInFile, nextPage);
                }
            }

            // The tail copy is used to avoid losing both the records from the previous IO transfer and the current one if the page becomes corrupted due to a power failue.
            endOfTransferRecorded = (pagesToWrite.Count > 1 || currentPage == null);
            if (!endOfTransferRecorded)
            {
                ulong pageOffsetInFile = pagesToWrite[0].Key;
                if (m_isTailCopyDirty || !overwriteTailPage)
                {
                    WritePage(pageOffsetInFile, currentPage);
                    m_isTailCopyDirty = false;
                }
                else
                {
                    WriteTailCopy(pageOffsetInFile, currentPage);;
                    m_isTailCopyDirty = true;
                }
            }
            else
            {
                for (int pageIndex = 0; pageIndex < pagesToWrite.Count; pageIndex++)
                {
                    ulong         pageOffsetInFile = pagesToWrite[pageIndex].Key;
                    LfsRecordPage page             = pagesToWrite[pageIndex].Value;
                    page.PagePosition = (ushort)(pageIndex + 1);
                    page.PageCount    = (ushort)pagesToWrite.Count;

                    if (pageIndex == 0 && !m_isTailCopyDirty && overwriteTailPage)
                    {
                        // We are about to overwrite a page from an older transfer that does not have a tail copy, create a tail copy
                        WriteTailCopy(pageOffsetInFile, page);
                    }

                    WritePage(pageOffsetInFile, page);
                }
            }

            if (currentPage == null)
            {
                m_tailPage        = null;
                m_isTailCopyDirty = false;
            }
            else
            {
                m_tailPage             = currentPage;
                m_tailPageOffsetInFile = pagesToWrite[pagesToWrite.Count - 1].Key;
            }
        }
コード例 #4
0
        public void InnerList_JustCreated_NoItemsAdded()
        {
            var list = new KeyValuePairList <string, string>();

            Assert.AreEqual(0, list.InnerList.Count);
        }
コード例 #5
0
        public static void UpdateOperationalParameters(KeyValuePairList <string, string> loginParameters, SessionParameters sessionParameters, ConnectionParameters connectionParameters)
        {
            sessionParameters.InitialR2T          = ISCSIServer.OfferedInitialR2T;
            sessionParameters.ImmediateData       = ISCSIServer.OfferedImmediateData;
            sessionParameters.MaxBurstLength      = ISCSIServer.OfferedMaxBurstLength;
            sessionParameters.FirstBurstLength    = ISCSIServer.OfferedFirstBurstLength;
            sessionParameters.MaxConnections      = ISCSIServer.OfferedMaxConnections;
            sessionParameters.DataPDUInOrder      = ISCSIServer.OfferedDataPDUInOrder;
            sessionParameters.DataSequenceInOrder = ISCSIServer.OfferedDataSequenceInOrder;
            sessionParameters.DefaultTime2Wait    = ISCSIServer.OfferedDefaultTime2Wait;
            sessionParameters.DefaultTime2Retain  = ISCSIServer.OfferedDefaultTime2Retain;
            sessionParameters.MaxOutstandingR2T   = ISCSIServer.OfferedMaxOutstandingR2T;

            string value = loginParameters.ValueOf("MaxRecvDataSegmentLength");

            if (value != null)
            {
                connectionParameters.InitiatorMaxRecvDataSegmentLength = Convert.ToInt32(value);
            }

            value = loginParameters.ValueOf("InitialR2T");
            if (value != null)
            {
                sessionParameters.InitialR2T = (value == "Yes") || ISCSIServer.OfferedInitialR2T;
            }

            value = loginParameters.ValueOf("ImmediateData");
            if (value != null)
            {
                sessionParameters.ImmediateData = (value == "Yes") && ISCSIServer.OfferedImmediateData;
            }

            value = loginParameters.ValueOf("MaxBurstLength");
            if (value != null)
            {
                sessionParameters.MaxBurstLength = Math.Min(Convert.ToInt32(value), ISCSIServer.OfferedMaxBurstLength);
            }

            value = loginParameters.ValueOf("FirstBurstLength");
            if (value != null)
            {
                sessionParameters.FirstBurstLength = Math.Min(Convert.ToInt32(value), ISCSIServer.OfferedFirstBurstLength);
            }

            value = loginParameters.ValueOf("MaxConnections");
            if (value != null)
            {
                sessionParameters.MaxConnections = Math.Min(Convert.ToInt32(value), ISCSIServer.OfferedMaxConnections);
            }

            value = loginParameters.ValueOf("DataPDUInOrder");
            if (value != null)
            {
                sessionParameters.DataPDUInOrder = (value == "Yes") || ISCSIServer.OfferedDataPDUInOrder;
            }

            value = loginParameters.ValueOf("DataSequenceInOrder");
            if (value != null)
            {
                sessionParameters.DataSequenceInOrder = (value == "Yes") || ISCSIServer.OfferedDataSequenceInOrder;
            }

            value = loginParameters.ValueOf("DefaultTime2Wait");
            if (value != null)
            {
                sessionParameters.DefaultTime2Wait = Math.Max(Convert.ToInt32(value), ISCSIServer.OfferedDefaultTime2Wait);
            }

            value = loginParameters.ValueOf("DefaultTime2Retain");
            if (value != null)
            {
                sessionParameters.DefaultTime2Retain = Math.Min(Convert.ToInt32(value), ISCSIServer.OfferedDefaultTime2Retain);
            }

            value = loginParameters.ValueOf("MaxOutstandingR2T");
            if (value != null)
            {
                sessionParameters.MaxOutstandingR2T = Math.Min(Convert.ToInt32(value), ISCSIServer.OfferedMaxOutstandingR2T);
            }
        }
コード例 #6
0
ファイル: IndexData.cs プロジェクト: zys0807/iSCSIConsole
        public void RemoveEntry(byte[] key)
        {
            if (!m_rootRecord.IsParentNode)
            {
                int index = CollationHelper.FindIndexInLeafNode(m_rootRecord.IndexEntries, key, m_rootRecord.CollationRule);
                if (index >= 0)
                {
                    m_rootRecord.IndexEntries.RemoveAt(index);
                }
                m_volume.UpdateFileRecord(m_fileRecord);
            }
            else
            {
                int indexOfEntryToRemove;
                KeyValuePairList <int, IndexRecord> path = FindRemovalPath(key, out indexOfEntryToRemove);
                if (path == null)
                {
                    return;
                }

                if ((path.Count > 0 && path[path.Count - 1].Value.IsParentNode) || path.Count == 0)
                {
                    // We find the rightmost leaf entry in the left branch and put it instead.
                    // Note: Excluding the root of the branch, the rightmost leaf entry in the branch collates last.
                    KeyValuePairList <int, IndexRecord> pathToLeaf = FindPathToRightmostLeaf(path, indexOfEntryToRemove);
                    IndexRecord leaf = pathToLeaf[pathToLeaf.Count - 1].Value;
                    IndexEntry  entryToRemoveFromLeaf = leaf.IndexEntries[leaf.IndexEntries.Count - 1];
                    leaf.IndexEntries.RemoveAt(leaf.IndexEntries.Count - 1);
                    long leafRecordIndex = ConvertToRecordIndex(leaf.RecordVBN);
                    // Note: CHKDSK does not accept an empty IndexRecord, however, we must not call RemovePointer just yet because it might affect the parent as well.
                    WriteIndexRecord(leafRecordIndex, leaf);

                    if (path.Count == 0)
                    {
                        m_rootRecord.IndexEntries[indexOfEntryToRemove].FileReference = entryToRemoveFromLeaf.FileReference;
                        m_rootRecord.IndexEntries[indexOfEntryToRemove].Key           = entryToRemoveFromLeaf.Key;
                        m_volume.UpdateFileRecord(m_fileRecord);
                    }
                    else
                    {
                        path[path.Count - 1].Value.IndexEntries[indexOfEntryToRemove].FileReference = entryToRemoveFromLeaf.FileReference;
                        path[path.Count - 1].Value.IndexEntries[indexOfEntryToRemove].Key           = entryToRemoveFromLeaf.Key;
                        long recordIndex = ConvertToRecordIndex(path[path.Count - 1].Value.RecordVBN);
                        WriteIndexRecord(recordIndex, path[path.Count - 1].Value);
                    }

                    if (leaf.IndexEntries.Count == 0)
                    {
                        int indexOfLeafPointer = pathToLeaf[pathToLeaf.Count - 1].Key;
                        RemovePointer(pathToLeaf.GetRange(0, pathToLeaf.Count - 1), indexOfLeafPointer);
                        DeallocateIndexRecord(leafRecordIndex);
                    }
                }
                else
                {
                    int         indexInParentRecord = path[path.Count - 1].Key;
                    IndexRecord leaf = path[path.Count - 1].Value;

                    leaf.IndexEntries.RemoveAt(indexOfEntryToRemove);
                    long recordIndex = ConvertToRecordIndex(leaf.RecordVBN);
                    if (leaf.IndexEntries.Count > 0)
                    {
                        WriteIndexRecord(recordIndex, leaf);
                    }
                    else
                    {
                        path.RemoveAt(path.Count - 1);
                        RemovePointer(path, indexInParentRecord);
                        DeallocateIndexRecord(recordIndex);
                    }
                }
            }
        }
コード例 #7
0
ファイル: IndexData.cs プロジェクト: zys0807/iSCSIConsole
        /// <param name="path">Key is index in parent node</param>
        private void SplitIndexRecord(KeyValuePairList <int, IndexRecord> path)
        {
            int indexInParentRecord = path[path.Count - 1].Key;
            // We will treat the record we want to split as the right node, and create a left node
            IndexRecord       rightNode        = path[path.Count - 1].Value;
            long              rightNodeVBN     = rightNode.RecordVBN;
            long              rightNodeIndex   = ConvertToRecordIndex(rightNodeVBN);
            List <IndexEntry> rightNodeEntries = rightNode.IndexEntries;
            int         splitIndex             = rightNodeEntries.Count / 2;
            IndexEntry  middleEntry            = rightNodeEntries[splitIndex];
            IndexRecord leftNode = new IndexRecord();

            leftNode.IsParentNode = rightNode.IsParentNode;
            leftNode.IndexEntries = rightNodeEntries.GetRange(0, splitIndex);
            rightNodeEntries.RemoveRange(0, splitIndex + 1);
            if (rightNode.IsParentNode)
            {
                // A parent node has n keys and points to (n + 1) subnodes,
                // When splitting it to two nodes we will take the pointer from the entry we wish to push to the parent node,
                // and use it as the last pointer in the left node.
                IndexEntry leftNodeLastEntry = new IndexEntry();
                leftNodeLastEntry.ParentNodeForm = true;
                leftNodeLastEntry.IsLastEntry    = true;
                leftNodeLastEntry.SubnodeVBN     = middleEntry.SubnodeVBN;
                leftNode.IndexEntries.Add(leftNodeLastEntry);
            }
            long leftNodeIndex = AllocateIndexRecord();

            leftNode.RecordVBN = ConvertToVirtualBlockNumber(leftNodeIndex);
            IndexEntry newParentEntry = new IndexEntry(middleEntry.FileReference, middleEntry.Key);

            newParentEntry.ParentNodeForm = true;
            newParentEntry.SubnodeVBN     = leftNode.RecordVBN;
            WriteIndexRecord(rightNodeIndex, rightNode);
            WriteIndexRecord(leftNodeIndex, leftNode);
            if (path.Count > 1)
            {
                IndexRecord       parentRecord      = path[path.Count - 2].Value;
                long              parentRecordIndex = ConvertToRecordIndex(parentRecord.RecordVBN);
                List <IndexEntry> parentEntries     = parentRecord.IndexEntries;
                parentEntries.Insert(indexInParentRecord, newParentEntry);
                if (parentRecord.DoesFit((int)m_rootRecord.BytesPerIndexRecord))
                {
                    WriteIndexRecord(parentRecordIndex, parentRecord);
                }
                else
                {
                    // Split parent index record
                    path.RemoveAt(path.Count - 1);
                    SplitIndexRecord(path);
                }
            }
            else
            {
                m_rootRecord.IndexEntries.Insert(indexInParentRecord, newParentEntry);
                if (m_rootRecord.RecordLength >= m_volume.AttributeRecordLengthToMakeNonResident)
                {
                    SplitRootIndexRecord();
                }
                else
                {
                    m_volume.UpdateFileRecord(m_fileRecord);
                }
            }
        }
コード例 #8
0
        public static void SetCommand(string[] args)
        {
            if (args.Length == 2)
            {
                KeyValuePairList <string, string> parameters = ParseParameters(args, 1);
                if (!VerifyParameters(parameters, "debug", "commandqueue", "MaxRecvDataSegmentLength".ToLower(), "MaxBurstLength".ToLower(), "FirstBurstLength".ToLower()))
                {
                    Console.WriteLine("Invalid parameter.");
                    return;
                }

                if (parameters.ContainsKey("debug"))
                {
                    m_debug = true;
                }

                if (parameters.ContainsKey("CommandQueue".ToLower()))
                {
                    int requestedCommandQueueSize = Conversion.ToInt32(parameters.ValueOf("commandqueue"), 0);
                    if (requestedCommandQueueSize < 0)
                    {
                        Console.WriteLine("Invalid queue size (must be non-negative).");
                        return;
                    }

                    SessionParameters.DefaultCommandQueueSize = (uint)requestedCommandQueueSize;
                }

                if (parameters.ContainsKey("MaxRecvDataSegmentLength".ToLower()))
                {
                    int requestedMaxRecvDataSegmentLength = Conversion.ToInt32(parameters.ValueOf("MaxRecvDataSegmentLength".ToLower()), 0);
                    if (requestedMaxRecvDataSegmentLength <= 0)
                    {
                        Console.WriteLine("Invalid length (must be positive).");
                        return;
                    }

                    ConnectionParameters.DeclaredMaxRecvDataSegmentLength = requestedMaxRecvDataSegmentLength;
                    Console.WriteLine("MaxRecvDataSegmentLength has been set to " + ISCSIServer.OfferedMaxBurstLength);
                }

                if (parameters.ContainsKey("MaxBurstLength".ToLower()))
                {
                    int requestedMaxBurstLength = Conversion.ToInt32(parameters.ValueOf("MaxBurstLength".ToLower()), 0);
                    if (requestedMaxBurstLength <= 0)
                    {
                        Console.WriteLine("Invalid length (must be positive).");
                        return;
                    }

                    ISCSIServer.OfferedMaxBurstLength = requestedMaxBurstLength;
                    Console.WriteLine("Offered MaxBurstLength has been set to " + ISCSIServer.OfferedMaxBurstLength);
                    if (ISCSIServer.OfferedMaxBurstLength < ISCSIServer.OfferedFirstBurstLength)
                    {
                        // FirstBurstLength MUST NOT exceed MaxBurstLength
                        ISCSIServer.OfferedFirstBurstLength = ISCSIServer.OfferedMaxBurstLength;
                        Console.WriteLine("Offered FirstBurstLength has been set to " + ISCSIServer.OfferedFirstBurstLength);
                    }
                }

                if (parameters.ContainsKey("FirstBurstLength".ToLower()))
                {
                    int requestedFirstBurstLength = Conversion.ToInt32(parameters.ValueOf("FirstBurstLength".ToLower()), 0);
                    if (requestedFirstBurstLength <= 0)
                    {
                        Console.WriteLine("Invalid length (must be positive).");
                        return;
                    }

                    ISCSIServer.OfferedFirstBurstLength = requestedFirstBurstLength;
                    Console.WriteLine("Offered FirstBurstLength has been set to " + ISCSIServer.OfferedFirstBurstLength);
                    if (ISCSIServer.OfferedMaxBurstLength < ISCSIServer.OfferedFirstBurstLength)
                    {
                        // FirstBurstLength MUST NOT exceed MaxBurstLength
                        ISCSIServer.OfferedMaxBurstLength = ISCSIServer.OfferedFirstBurstLength;
                        Console.WriteLine("Offered MaxBurstLength has been set to " + ISCSIServer.OfferedMaxBurstLength);
                    }
                }
            }
            else if (args.Length > 2)
            {
                Console.WriteLine("Too many arguments.");
                HelpSet();
            }
            else
            {
                HelpSet();
            }
        }
コード例 #9
0
 private static KeyValuePair <MftSegmentReference, FileNameRecord>?FindFileNameRecord(KeyValuePairList <MftSegmentReference, FileNameRecord> records, string name)
 {
     foreach (KeyValuePair <MftSegmentReference, FileNameRecord> record in records)
     {
         if (String.Equals(record.Value.FileName, name, StringComparison.InvariantCultureIgnoreCase))
         {
             return(record);
         }
     }
     return(null);
 }
コード例 #10
0
        public static void AttachCommand(string[] args)
        {
            if (m_server != null)
            {
                Console.WriteLine("Server is already running");
                return;
            }

            if (args.Length >= 2)
            {
                KeyValuePairList <string, string> parameters = ParseParameters(args, 2);
                if (!VerifyParameters(parameters, "vdisk", "disk", "volume", "readonly", "target"))
                {
                    Console.WriteLine();
                    Console.WriteLine("Invalid parameter");
                    HelpAttach();
                    return;
                }

                switch (args[1].ToLower())
                {
                case "vdisk":
                {
                    if (m_selectedDisk == null)
                    {
                        Console.WriteLine("No disk has been selected");
                        break;
                    }

                    if (!(m_selectedDisk is DiskImage))
                    {
                        Console.WriteLine("Selected disk is not a disk image");
                        break;
                    }

                    DiskImage disk = (DiskImage)m_selectedDisk;
                    string    defaultStorageTargetName = Path.GetFileNameWithoutExtension(disk.Path);
                    string    defaultTargetName        = DefaultTargetIQN + ":" + defaultStorageTargetName.Replace(" ", ""); // spaces are not allowed
                    AttachISCSIDisk(disk, defaultTargetName, parameters);
                    break;
                }

                case "disk":
                {
                    if (m_selectedDisk == null)
                    {
                        Console.WriteLine("Error: No disk has been selected.");
                        break;
                    }

                    if (!(m_selectedDisk is PhysicalDisk))
                    {
                        Console.WriteLine("Error: The selected disk is not a physical disk.");
                        break;
                    }

                    bool         isAttachmentReadOnly = parameters.ContainsKey("readonly");
                    PhysicalDisk disk = (PhysicalDisk)m_selectedDisk;
                    if (!isAttachmentReadOnly)
                    {
                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                        //if (Environment.OSVersion.Version.Major >= 6)
                        {
                            bool isDiskReadOnly;
                            bool isOnline = disk.GetOnlineStatus(out isDiskReadOnly);
                            if (isOnline)
                            {
                                Console.WriteLine();
                                Console.WriteLine("Error: The selected disk must be taken offline.");
                                break;
                            }

                            if (!isAttachmentReadOnly && isDiskReadOnly)
                            {
                                Console.WriteLine();
                                Console.WriteLine("Error: The selected disk is set to readonly!");
                                break;
                            }
                        }
                        else
                        {
                            Console.WriteLine();
                            // Locking mechanism is not implemented
                            Console.Write("Warning: if a volume on this disk is mounted locally, data corruption may occur!");
                        }
                    }
                    string defaultStorageTargetName = string.Format("disk{0}", disk.PhysicalDiskIndex);
                    string defaultTargetName        = DefaultTargetIQN + ":" + defaultStorageTargetName;
                    AttachISCSIDisk(disk, defaultTargetName, parameters);
                    break;
                }

                case "volume":
                {
                    if (m_selectedVolume == null)
                    {
                        Console.WriteLine("No volume has been selected.");
                        break;
                    }

                    VolumeDisk virtualDisk          = new VolumeDisk(m_selectedVolume);
                    string     defaultTargetName    = DefaultTargetIQN + ":Volume";
                    bool       isAttachmentReadOnly = parameters.ContainsKey("readonly");
                    if (!isAttachmentReadOnly)
                    {
                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                        //if (Environment.OSVersion.Version.Major >= 6)
                        {
                            if (m_selectedVolume is DynamicVolume)
                            {
                                foreach (DiskExtent extent in ((DynamicVolume)m_selectedVolume).Extents)
                                {
                                    if (extent.Disk is PhysicalDisk)
                                    {
                                        bool isDiskReadOnly;
                                        bool isOnline = ((PhysicalDisk)extent.Disk).GetOnlineStatus(out isDiskReadOnly);
                                        if (isOnline)
                                        {
                                            Console.WriteLine("Error: All disks containing the volume must be taken offline.");
                                            return;
                                        }

                                        if (isDiskReadOnly)
                                        {
                                            Console.WriteLine("Error: A disk containing the volume is set to readonly.");
                                            return;
                                        }
                                    }
                                }
                            }
                            else if (m_selectedVolume is Partition)
                            {
                                Disk disk = ((Partition)m_selectedVolume).Disk;
                                if (disk is PhysicalDisk)
                                {
                                    bool isDiskReadOnly;
                                    bool isOnline = ((PhysicalDisk)disk).GetOnlineStatus(out isDiskReadOnly);

                                    if (isOnline)
                                    {
                                        Console.WriteLine("Error: The disk containing the volume must be taken offline.");
                                        return;
                                    }

                                    if (isDiskReadOnly)
                                    {
                                        Console.WriteLine("Error: The disk containing the volume is set to readonly.");
                                        return;
                                    }
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine();
                            // Locking mechanism is not implemented
                            Console.WriteLine("Warning: if this volume is mounted locally, data corruption may occur!");
                        }
                    }
                    AttachISCSIDisk(virtualDisk, defaultTargetName, parameters);
                    break;
                }

                default:
                {
                    Console.WriteLine();
                    Console.WriteLine("Invalid argument.");
                    HelpAttach();
                    break;
                }
                }
            }
            else
            {
                HelpAttach();
            }
        }