/// <summary> /// Thread functions to run the set commands /// </summary> private static void RunSetDeviceCommands() { while (true) { try { if (ChassisState.ShutDown) { return; } if (ConfigLoaded.EnableFan) { // Step 1. Set All Fan Speeds if EnableFan is set. SetAllFanSpeeds(); } // Step 2. Check Serial Console Inactivity. CheckBladeConsoleInactivity(); // Step 3. Reset Watch Dog Timer ResetWatchDog(); // Step 4. Set Attention Leds SetAttentionLeds(); } catch (Exception ex) { Tracer.WriteWarning("Chassis Manager RunSetDeviceCommands thread encountered an exception " + ex); } } }
/// <summary> /// Write to Chassis Fru - (Important) note that this function enables write to any offset /// Offset checks ensures that we are within permissible limits, but cannot enforce semantics within those limits /// Length checks validity of packet, however empty fields in packet are responsibility of writing function /// User level priority since this is not an internal call /// </summary> /// <param name="offset"></param> /// <param name="length"></param> /// <param name="packet"></param> /// <returns></returns> public byte writeChassisFru(ushort offset, ushort length, byte[] packet) { byte deviceId = 1; ChassisFruWriteResponse response = new ChassisFruWriteResponse(); try { response = (ChassisFruWriteResponse)this.SendReceive(DeviceType.ChassisFruEeprom, deviceId, new ChassisFruWriteRequest(offset, length, packet), typeof(ChassisFruWriteResponse), (byte)PriorityLevel.User); } catch (Exception ex) { Tracer.WriteWarning("ChassisFru write had an exception", ex); } if (response.CompletionCode != (byte)CompletionCode.Success) { Tracer.WriteError("Fru Write failed with completion code {0:X}", response.CompletionCode); } else { Tracer.WriteInfo("Fru Write succeeded"); } return((byte)response.CompletionCode); }
/// <summary> /// Checks the validity of the current blade id passed /// </summary> /// <param name="bladeId"></param> /// <returns></returns> public static bool checkBladeTypeValidity(byte bladeId) { try { // Open the request message using an xml reader XmlReader xr = OperationContext.Current.IncomingMessageHeaders.GetReaderAtHeader(0); // Split the URL at the API name--Parameters junction indicated by the '?' character - taking the first string will ignore all parameters string[] urlSplit = xr.ReadElementContentAsString().Split('/'); // Extract just the API name and rest of the URL, which will be the last item in the split using '/' string[] apiSplit = urlSplit[3].Split('?'); BladeType val = BladeType.Unknown; invalidBladeFunction.TryGetValue(apiSplit[0], out val); // If the blade type does not support this function, return false, so we can send back useful info to user if ((byte)val == ChassisState.GetBladeType(bladeId)) { Tracer.WriteWarning("Command {0} not valid for Blade id {1}, Blade Type {2}", apiSplit[0], bladeId, ChassisState.GetBladeTypeName((byte)val)); return(false); } } catch (Exception ex) { Tracer.WriteError("Checking Blade Type validity encountered an exception" + ex); // We decide to go ahead and issue the command to the blade if the blade type check fails with exception, // This is done in order to not penalize a user command based on some failure in checking // The command might fail eventually, but with an unhelpful error message } return(true); }
/// <summary> /// Reads raw CM information - can be called individually if needed /// User level priority since this is not an internal call /// </summary> public ChassisFruReadResponse readRawChassisFru(ushort offset, ushort length) { byte deviceId = 1; ChassisFruReadResponse response = new ChassisFruReadResponse(); try { response = (ChassisFruReadResponse)this.SendReceive(DeviceType.ChassisFruEeprom, deviceId, new ChassisFruReadRequest(offset, length), typeof(ChassisFruReadResponse), (byte)PriorityLevel.User); } catch (Exception ex) { Tracer.WriteWarning("Chassis Fru read had an exception", ex); } if (response.CompletionCode != (byte)CompletionCode.Success) { Tracer.WriteError("Fru read failed with completion code {0:X}", response.CompletionCode); } else { Tracer.WriteInfo("Chassis Fru info read: {0:X}", response.DataReturned.ToString()); } return(response); }
// Returns the most privileged role this user belongs to static internal authorizationRole GetCurrentUserMostPrivilegedRole() { try { ServiceSecurityContext context = OperationContext.Current.ServiceSecurityContext; WindowsIdentity windowsIdentity = context.WindowsIdentity; var principal = new WindowsPrincipal(windowsIdentity); // Extract domain + role names to check for access privilege // The first item before '\' is the domain name - extract it string[] usernameSplit = windowsIdentity.Name.Split('\\'); // Apend role names after the domain name string wcscmadminRole = usernameSplit[0] + "\\" + "WcsCmAdmin"; string wcscmoperatorRole = usernameSplit[0] + "\\" + "WcsCmOperator"; string wcscmuserRole = usernameSplit[0] + "\\" + "WcsCmUser"; if (principal.IsInRole("Administrators")) { Tracer.WriteUserLog("User({0}) belongs to Administrators group and hence belongs to WcsCmAdmin privilege role", windowsIdentity.Name); return(authorizationRole.WcsCmAdmin); } // Is user in local WcsCmAdmin group or domain's WcsCmAdmin group? if (principal.IsInRole("WcsCmAdmin") || principal.IsInRole(wcscmadminRole)) { Tracer.WriteUserLog("User({0}) belongs to WcsCmAdmin privilege role", windowsIdentity.Name); return(authorizationRole.WcsCmAdmin); } // Is user in local WcsCmOperator group or domain's WcsCmOperator group? if (principal.IsInRole("WcsCmOperator") || principal.IsInRole(wcscmoperatorRole)) { Tracer.WriteUserLog("User({0}) belongs to WcsCmOperator privilege role", windowsIdentity.Name); return(authorizationRole.WcsCmOperator); } // Is user in local WcsCmUser group or domain's WcsCmUser group? if (principal.IsInRole("WcsCmUser") || principal.IsInRole(wcscmuserRole)) { Tracer.WriteUserLog("User({0}) belongs to WcsCmUser privilege role", windowsIdentity.Name); return(authorizationRole.WcsCmUser); } // User not mapped to any standard roles Tracer.WriteWarning("GetCurrentUserMostPrivilegedRole: Current user({0}) not mapped to the standard WCS roles", windowsIdentity.Name); Tracer.WriteUserLog("GetCurrentUserMostPrivilegedRole: Current user({0}) not mapped to the standard WCS roles", windowsIdentity.Name); } catch (Exception ex) { Tracer.WriteError("User Authorization check exception was thrown: " + ex); } // Return as unauthorized if the user do not belong to any of the category or if there is an exception return(authorizationRole.WcsCmUnAuthorized); }
/// <summary> /// Identifies the PSU vendor at each psu slot using the modelnumber API of the PsuBase class /// (Assumes all PSU vendors implement the MFR_MODEL Pmbus command) /// Based on the model number, we bind the Psu class object to the corresponding child (vendor) class object /// </summary> private static void PsuInitialize() { for (uint psuIndex = 0; psuIndex < ConfigLoaded.NumPsus; psuIndex++) { // Initially create instance of the base class // Later.. based on the psu model number, we create the appropriate psu class object Psu[psuIndex] = new PsuBase((byte)(psuIndex + 1)); PsuModelNumberPacket modelNumberPacket = new PsuModelNumberPacket(); modelNumberPacket = Psu[psuIndex].GetPsuModel(); string psuModelNumber = modelNumberPacket.ModelNumber; PsuModel model = ConvertPsuModelNumberToPsuModel(psuModelNumber); switch (model) { case PsuModel.Delta: Psu[psuIndex] = new DeltaPsu((byte)(psuIndex + 1)); Tracer.WriteInfo("Delta PSU identified at slot-{0}, Model Number: {1}", psuIndex + 1, psuModelNumber); break; case PsuModel.EmersonWithLes: Psu[psuIndex] = new EmersonPsu((byte)(psuIndex + 1), true); Tracer.WriteInfo("Emerson with LES PSU identified at slot-{0}, Model Number: {1}", psuIndex + 1, psuModelNumber); break; case PsuModel.EmersonNonLes: Psu[psuIndex] = new EmersonPsu((byte)(psuIndex + 1), false); Tracer.WriteInfo("Emerson non-LES PSU identified at slot-{0}, Model Number: {1}", psuIndex + 1, psuModelNumber); break; default: // Unknown PSUs if (ConfigLoaded.ForceEmersonPsu) { // Force to Emerson PSU without LES to enable FW update methods in the EmersonPsu class to be called. // This is useful when a previous FW update did not complete successfully. // The PSU stays in bootloader mode and does not recognize the // MFR_MODEL command and will return all 0xFFs for this command. Psu[psuIndex] = new EmersonPsu((byte)(psuIndex + 1), false); Tracer.WriteWarning("Forcing PSU instantiation to Emerson non-LES PSU at slot-{0}, Model Number: {1}", psuIndex + 1, psuModelNumber); } else { Psu[psuIndex] = new PsuBase((byte)(psuIndex + 1)); Tracer.WriteInfo("Unidentified PSU at slot-{0}, Model Number: {1}. Default to base PSU class.", psuIndex + 1, psuModelNumber); } break; } // Enable/disable Battery Extended Operation Mode Psu[psuIndex].SetBatteryExtendedOperationMode(ConfigLoaded.DatasafeOperationsEnabled ? true: false); } }
/// <summary> /// Gets the PSU status for all PSUs /// </summary> private void GetAllPsuStatus() { int countStatus = 0; for (int numPsus = 0; numPsus < MaxPsuCount; numPsus++) { try { PsuStatusPacket psuStatusPacket = new PsuStatusPacket(); psuStatusPacket = ChassisState.Psu[numPsus].GetPsuStatus(); if (psuStatusPacket.CompletionCode != CompletionCode.Success) { Tracer.WriteWarning("PSU ({0}) get status request failed with return code {1}", numPsus + 1, psuStatusPacket.CompletionCode); } else { if (psuStatusPacket.PsuStatus == (byte)Contracts.PowerState.ON) { countStatus++; } else { Tracer.WriteWarning("PSU ({0}) PowerGood signal is negated - check trace log for fault information", numPsus + 1); CompletionCode clearFaultCompletionCode = ChassisState.Psu[numPsus].SetPsuClearFaults(); if (clearFaultCompletionCode != CompletionCode.Success) { Tracer.WriteError("PsuStatus clear fault (invoked upon negated power good signal) command failed. Completion code({0})", clearFaultCompletionCode); } else { Tracer.WriteWarning("PsuStatus clear fault (invoked upon negated power good signal) command succeeded."); } } } } catch (Exception e) { Tracer.WriteError("PSU {0} status check failed with Exception: {1}", numPsus + 1, e); } } // Identify whether there is a PSU failure or not if (countStatus != MaxPsuCount) { ChassisState.PsuFailure = true; } else { ChassisState.PsuFailure = false; } }
/// <summary> /// Attempts to retrieve the Psu Status. This method /// calls down to the Chassis Manager with SendReceive /// </summary> private PsuStatusPacket GetPsuStatus(byte psuId) { // Initialize return packet PsuStatusPacket returnPacket = new PsuStatusPacket(); returnPacket.CompletionCode = CompletionCode.UnspecifiedError; returnPacket.PsuStatus = 0; returnPacket.FaultPresent = false; try { PsuStatusResponse myResponse = new PsuStatusResponse(); myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_WORD, (byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse)); if (myResponse.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode; Tracer.WriteWarning("GetPsuStatus Failure for PSU {0}: Completion Code: {1}", psuId, myResponse.CompletionCode); } else { returnPacket.CompletionCode = CompletionCode.Success; byte varStatus; byte[] psuStatus = myResponse.PsuStatus; // If there are any other faults, indicate fault is present and log the full status word if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus)) { Tracer.WriteWarning("GetPsuStatus: Psu ({0}) STATUS_WORD is non-zero: " + "(High Byte: {1} Low Byte: {2}) (See STATUS_WORD register in PmBusII Manual)", this.PsuId, System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0'), System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0')); returnPacket.FaultPresent = true; } returnPacket.PsuStatus = varStatus; } } catch (System.Exception ex) { returnPacket.CompletionCode = CompletionCode.UnspecifiedError; returnPacket.PsuStatus = 0; Tracer.WriteError("GetPsuStatus Exception: " + ex); } return(returnPacket); }
/// <summary> /// Gets the current status of rear attention LED for the chassis /// </summary> /// <returns></returns> private static byte GetRearAttentionLedStatus() { // Gets the LED status response Contracts.LedStatusResponse ledStatus = new Contracts.LedStatusResponse(); ledStatus = ChassisState.AttentionLed.GetLedStatus(); if (ledStatus.completionCode != Contracts.CompletionCode.Success) { Tracer.WriteWarning("Internal getRearAttentionLedStatus - getting status failed with Completion Code {0:X}", ledStatus.completionCode); return((byte)LedStatus.NA); } else { return((byte)ledStatus.ledState); } }
// This function should be called before executing any service APIs // TODO: Add other checks that needs to be done before executing APIs - like check for chassis terminating etc internal static CompletionCode ApiGreenSignalling() { CompletionCode response = new CompletionCode(); response = CompletionCode.UnspecifiedError; int currBladeId = bladeId; // Return Success if there is no active serial console session in progress if (!BladeSerialSessionMetadata.IsSerialConsoleSessionActive()) { response = CompletionCode.Success; return(response); } // If App.config parameter, KillSerialConsoleSession, is enabled, // terminate existing serial console session and proceed executing incoming commmands. if (ConfigLoaded.KillSerialConsoleSession) { response = CompletionCode.UnspecifiedError; Tracer.WriteInfo("Kill serial console session is enabled to allow incoming commands to succeed."); Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse(); sessionResponse = StopBladeSerialSession(ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken, true); if (sessionResponse.completionCode != Contracts.CompletionCode.Success) { Tracer.WriteError("BladeSerialSessionMetadata.ApiGreenSignalling:Error stopserialsession failed"); return(response); } response = CompletionCode.Success; return(response); } // If App.config parameter, KillSerialConsoleSession, is not enabled, maintain existing serial console session, // and ignore incoming commands, with explicit failure message output as warning in trace, since it will not // affect service correctness. else { response = CompletionCode.SerialPortOtherErrors; Tracer.WriteWarning("Serial console session in progress. Ignore incoming command with message:{0}", response); // We are returning non-Success completion code (represented as SerialPortOtherErrors) // to indicate/trigger the failure of this incoming command. return(response); } }
/// <summary> /// Internal operation to call both hard power on (soft power on is not exposed to the user) /// </summary> /// <param name="bladeId">Blade ID</param> /// <returns>True/false for success/failure</returns> internal static bool PowerOn(int bladeId) { Tracer.WriteInfo("Received poweron({0})", bladeId); bool powerOnStatus = false; BladePowerStatePacket bladePowerSwitchStatePacket = new BladePowerStatePacket(); CompletionCode status; // Hard Power enable // Serialize setting of state and actual code logic lock (ChassisState.locker[bladeId - 1]) { BladePowerStatePacket currState = ChassisState.BladePower[bladeId - 1].GetBladePowerState(); if (currState.CompletionCode != CompletionCode.Success || (currState.BladePowerState == (byte)Contracts.PowerState.OFF)) { // No return here, because we still want to return a BMC state on the fall through, // if Blade enable read fails for whatever reason Tracer.WriteWarning("PowerOn: Blade {0} Power Enable state read failed (Completion Code: {1:X})", bladeId, currState.CompletionCode); bladePowerSwitchStatePacket = ChassisState.BladePower[bladeId - 1].SetBladePowerState((byte)PowerState.ON); status = bladePowerSwitchStatePacket.CompletionCode; Tracer.WriteInfo("Hard poweron status " + status); if (status == CompletionCode.Success) { // Hard power on status is true, so Blade should be set to Initialization state on success Tracer.WriteInfo("PowerOn: State Transition for blade {0}: {1} -> Initialization", bladeId, ChassisState.GetStateName((byte)bladeId)); ChassisState.SetBladeState((byte)bladeId, (byte)BladeState.Initialization); powerOnStatus = true; } else { Tracer.WriteWarning("PowerOn: Hard Power On failed for BladeId {0} with code {1:X}", bladeId, status); } } else { powerOnStatus = true; // the blade was already powered on, so we dont power it on again } } return(powerOnStatus); }
/// <summary> /// The code that is executed by the worker thread /// 1. Wait for a new work item /// 2. Generate a data packet using the request information /// 3. Send the generated packet over the port /// 4. Receive the response from the target hardware device /// 5. Generate/copy a response packet /// 6. Signal the waiting user-level thread /// 7. Repeat above /// Note: For serviceability purpose, continue to execute /// the main loop even with an unhandled exception /// </summary> private void WorkerThreadFunction() { while (true) { try { while (true) { WorkItem workItem; // Get a new work item workItem = GetWorkItem(); if (workItem != null) { Tracer.WriteInfo("[Worker] logicalPortId: {0}, Signaled", logicalPortId); if (shouldTerminateWorkerThread == true) { Tracer.WriteWarning("[Worker] Draining the remaining work item before terminating CM"); } SendReceive(ref workItem); } else { // If CM is about to gracefully terminate and there is no more work item in the // queues (i.e., all the queues have been drained), stop this worker thread // by exiting from the main loop if (shouldTerminateWorkerThread == true) { Tracer.WriteInfo("[Worker] Stopping worker threads", logicalPortId); return; } WaitForWorkItem(); } } } catch (Exception e) { Tracer.WriteError("Unhandled Exception in PortManager worker thread main loop"); Tracer.WriteError(e); } } }
/// <summary> /// BladeOff commands switches off blade through IPMI (soft blade off) /// </summary> /// <param name="bladeId"></param> /// <returns></returns> internal static bool BladeOff(int bladeId) { bool powerOffStatus = false; // Soft power enable byte softStatus = WcsBladeFacade.SetPowerState((byte)bladeId, Ipmi.IpmiPowerState.Off); Tracer.WriteInfo("Soft poweroff status " + softStatus); if (softStatus != (byte)CompletionCode.Success) { Tracer.WriteWarning("Blade Soft Power Off Failed with Completion Code {0:X}", softStatus); } else { powerOffStatus = true; } return(powerOffStatus); }
/// <summary> /// Converts inlet temperature to PWM value /// </summary> /// <param name="temperature"></param> /// <returns></returns> private static byte GetPwmFromTemperature(double temperature, double lowThreshold, double highThreshold) { byte PWM = (byte)ConfigLoaded.MinPWM; // set to min as default if (lowThreshold >= highThreshold) { Tracer.WriteWarning("Low Threshold Temperature is greater or equal compared to high threshold"); return(PWM); } // PWM should never be higher or lower than the threshold. if (temperature < lowThreshold || temperature > highThreshold) { Tracer.WriteWarning("Temperature value {0} is out of range (lowThreshold {1} - highThreshold {2})", temperature, lowThreshold, highThreshold); return(PWM); } // Find PWM corresponding to temperature value from low threshold and range value // Linear extrapolation requires current value, range for consideration and the low-threshold so that // we can compute the PWM (as a value between 20-100) if (temperature <= highThreshold) { // These thresholds are read from threshold values in SDR record double range = highThreshold - lowThreshold; double value = ConfigLoaded.MinPWM + ((temperature - lowThreshold) / range) * (MaxPWM - ConfigLoaded.MinPWM); PWM = (byte)value; // Reset to MinPWM if calculated PWM is lower than MinPWM if (PWM < ConfigLoaded.MinPWM) { PWM = (byte)ConfigLoaded.MinPWM; } // Set PWM to MaxPWM if calculated PWM is more than MaxPWM if (PWM > MaxPWM) { PWM = MaxPWM; } } return(PWM); }
/// <summary> /// Sets the rear attention LED to on or off based on ledState param (0 - off, 1 - on) /// </summary> /// <param name="ledState"></param> private static byte SetRearAttentionLedStatus(byte ledState) { byte completionCode = (byte)CompletionCode.UnspecifiedError; if (ledState == (byte)LedStatus.On) { completionCode = ChassisState.AttentionLed.TurnLedOn(); Tracer.WriteInfo("Internal setRearAttentionLEDStatus - LEDOn Return: {0:X}", completionCode); } if (ledState == (byte)LedStatus.Off) { completionCode = ChassisState.AttentionLed.TurnLedOff(); Tracer.WriteInfo("Internal setRearAttentionLEDStatus - LEDOff Return: {0:X}", completionCode); } if (completionCode != (byte)CompletionCode.Success) { Tracer.WriteWarning("Internal setRearAttentionLEDStatus error - completion code: {0:X}", completionCode); } return(completionCode); }
/// <summary> /// Attempts to retrieve the Psu Status. This method /// calls down to the Chassis Manager with SendReceive /// </summary> private PsuStatusPacket GetPsuStatus(byte psuId) { // Initialize return packet PsuStatusPacket returnPacket = new PsuStatusPacket(); returnPacket.CompletionCode = CompletionCode.UnspecifiedError; returnPacket.PsuStatus = 0; try { PsuStatusResponse myResponse = new PsuStatusResponse(); myResponse = (PsuStatusResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_WORD, (byte)PmBusResponseLength.STATUS_WORD), typeof(PsuStatusResponse)); if (myResponse.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)myResponse.CompletionCode; Tracer.WriteWarning("GetPsuStatus Failure: status({0})", returnPacket.PsuStatus); } else { returnPacket.CompletionCode = CompletionCode.Success; byte varStatus; byte[] psuStatus = myResponse.PsuStatus; // If there are any other faults, print the full status word if (!PmBus.ExtractPowerGoodFromPsuStatus(psuStatus, out varStatus)) { Tracer.WriteWarning("Psu({0}) PowerGood Negated ({1} {2}) in/out curr/volt faults (See StatusWord in PmBusII Manual)", this.PsuId, System.Convert.ToString(psuStatus[0], 2).PadLeft(8, '0'), System.Convert.ToString(psuStatus[1], 2).PadLeft(8, '0')); } returnPacket.PsuStatus = varStatus; } } catch (System.Exception ex) { returnPacket.CompletionCode = CompletionCode.UnspecifiedError; returnPacket.PsuStatus = 0; Tracer.WriteError("GetPsuStatus Exception: " + ex); } return(returnPacket); }
/// <summary> /// Initialize Communication Device /// </summary> /// <returns>status byte which indicates whether initialization was successful or not</returns> private static byte CommunicationDeviceInitialize() { byte status = (byte)CompletionCode.UnspecifiedError; Tracer.WriteInfo("Initializing Communication Device"); CompletionCode completionCode = CommunicationDevice.Init(); #region Comm. Device Initialization Retry if (CompletionCodeChecker.Failed(completionCode)) { Tracer.WriteWarning("Initialization failed: {0}", completionCode); int loop = 0; // Retry 3 times before failing completely for (loop = 0; loop < ConfigLoaded.MaxRetries; loop++) { Tracer.WriteInfo("Initialization Retry: {0}", loop); completionCode = CommunicationDevice.Init(); if (CompletionCodeChecker.Succeeded(completionCode)) { break; } } if (loop == ConfigLoaded.MaxRetries) { Tracer.WriteError("Re-attempt at Communication Device Initialization failed with code: {0}", completionCode); return(status); } } #endregion if (CompletionCodeChecker.Succeeded(completionCode)) { Tracer.WriteInfo("Communication Device Initialization successful.."); } return((byte)CompletionCode.Success); }
// Returns the least privileged role with access to this API static internal authorizationRole GetCurrentApiLeastPrivilegedRole(string apiName) { try { authorizationRole val = authorizationRole.WcsCmUnAuthorized; // If api name do not map to any of the mapped roles, then by default make it accessible only by WcsCmAdmin role if (!apiNameLeastPrivilegeRoleMap.TryGetValue(apiName, out val)) { Tracer.WriteWarning("GetCurrentApiLeastPrivilegedRole: There is no role mapping for the api " + apiName); return(authorizationRole.WcsCmAdmin); } Tracer.WriteInfo("Requested API's minimum privilege requirement: " + val); return(val); } catch (Exception ex) { Tracer.WriteError("Api-to-Role Mapping Exception was thrown: " + ex); // Return as UnAuthorized if there is an exception, then by default make this API accessible only by WcsCmAdmin role Tracer.WriteInfo("Requested API's minimum privilege requirement (after exception): " + authorizationRole.WcsCmAdmin); return(authorizationRole.WcsCmAdmin); } }
private SerialDataPacket receiveSerialData(byte id) { // Initialize return packet SerialDataPacket returnPacket = new SerialDataPacket(); returnPacket.completionCode = CompletionCode.UnspecifiedError; returnPacket.data = null; try { // Call device layer below SerialConsolePortReceiveResponse serialResponse = (SerialConsolePortReceiveResponse)this.SendReceive(this.SerialPortConsoleDeviceType, translateSerialPortId(this.PortId), new SerialConsolePortReceiveRequest(), typeof(SerialConsolePortReceiveResponse), (byte)PriorityLevel.User); // check for completion code if (serialResponse.CompletionCode != 0) { returnPacket.completionCode = (CompletionCode)serialResponse.CompletionCode; } else { returnPacket.completionCode = CompletionCode.Success; if (serialResponse.ReceiveData == null) { Tracer.WriteWarning("Data is empty in SerialPortConsole.receiveSerialData"); } returnPacket.data = serialResponse.ReceiveData; } } catch (System.Exception ex) { returnPacket.completionCode = CompletionCode.UnspecifiedError; returnPacket.data = null; Tracer.WriteError(this.PortId, DeviceType.SerialPortConsole, ex); } return(returnPacket); }
/// <summary> /// Add a work item into a work queue. /// Return fail if the parameter is not valid and/or /// the target queue is currently full /// The caller must check the return value /// </summary> /// <param name="priorityLevel"></param> /// <param name="workItem"></param> /// <returns></returns> internal bool SendReceive(PriorityLevel priorityLevel, WorkItem workItem) { Queue workQueue = GetWorkQueue(priorityLevel); // Invalid priority level if (workQueue == null) { return(false); } // Must be thread-safe as other user-level thread or the device-level thread // can concurrently access the queue lock (workQueue.SyncRoot) { if (workQueue.Count > maxQueueLength) { // Invalid execution path: should not reach here Tracer.WriteError("[Error, PortManager: {0}, priorityLevel: {1}] Queue (size: {2}) overflowed", logicalPortId, priorityLevel, workQueue.Count); return(false); } else if (workQueue.Count == maxQueueLength) { // The work queue is current full and cannot serve the request Tracer.WriteWarning("[PortManager: {0}, priorityLevel: {1}] Full", logicalPortId, priorityLevel); return(false); } // Insert the work item workQueue.Enqueue(workItem); } // Signal the worker thread to process the work item that has been just inserted autoEvent.Set(); // The work item has been successfully inserted return(true); }
/// <summary> /// Thread function for running get blade requirement continuously /// </summary> private static void RunGetAllBladeRequirements() { while (true) { try { while (true) { if (ChassisState.ShutDown) { return; } // Get Blade Pwm requirements. GetAllBladePwmRequirements(); } } catch (Exception ex) { Tracer.WriteWarning("Chassis Manager RunGetAllBladeRequirements thread encountered an exception " + ex); } } }
/// <summary> /// Monitors PSU and takes remedial actions. Called by PSU_ALERT thread. /// </summary> internal static void MonitorPsuAlert() { if (ConfigLoaded.NumPsus > 0) { try { while (true) { if (ChassisState.ShutDown) { Tracer.WriteWarning("Psu Monitoring Thread Exiting"); return; } // Monitor PSU MonitorPsuAlertHelper(); } } catch (Exception ex) { Tracer.WriteWarning("Chassis Manager MonitorPsuAlert thread encountered an exception " + ex); } } }
/// <summary> /// Attempts to retrieve the Psu fault status registers. This method /// calls down to the Chassis Manager with SendReceive /// </summary> private PsuResponseBasePacket LogPsuFaultStatus(byte psuId) { // Initialize return packet PsuResponseBasePacket returnPacket = new PsuResponseBasePacket(); returnPacket.CompletionCode = CompletionCode.Success; try { PsuCommandByteResponse response = new PsuCommandByteResponse(); // STATUS_VOUT response = (PsuCommandByteResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_VOUT, (byte)PmBusResponseLength.STATUS_VOUT), typeof(PsuCommandByteResponse)); if (response.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)response.CompletionCode; Tracer.WriteWarning("LogPsuFaultStatus: Failed to read STATUS_VOUT on PSU {0}: Completion Code: {1}", psuId, response.CompletionCode); } else { Tracer.WriteWarning("LogPsuFaultStatus: PSU {0} STATUS_VOUT: {1}", psuId, System.Convert.ToString(response.PsuByteResponse, 2).PadLeft(8, '0')); } // STATUS_IOUT response = (PsuCommandByteResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_IOUT, (byte)PmBusResponseLength.STATUS_IOUT), typeof(PsuCommandByteResponse)); if (response.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)response.CompletionCode; Tracer.WriteWarning("LogPsuFaultStatus: Failed to read STATUS_IOUT on PSU {0}: Completion Code: {1}", psuId, response.CompletionCode); } else { Tracer.WriteWarning("LogPsuFaultStatus: PSU {0} STATUS_IOUT: {1}", psuId, System.Convert.ToString(response.PsuByteResponse, 2).PadLeft(8, '0')); } // STATUS_INPUT response = (PsuCommandByteResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_INPUT, (byte)PmBusResponseLength.STATUS_INPUT), typeof(PsuCommandByteResponse)); if (response.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)response.CompletionCode; Tracer.WriteWarning("LogPsuFaultStatus: Failed to read STATUS_INPUT on PSU {0}: Completion Code: {1}", psuId, response.CompletionCode); } else { Tracer.WriteWarning("LogPsuFaultStatus: PSU {0} STATUS_INPUT: {1}", psuId, System.Convert.ToString(response.PsuByteResponse, 2).PadLeft(8, '0')); } // STATUS_TEMPERATURE response = (PsuCommandByteResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_TEMPERATURE, (byte)PmBusResponseLength.STATUS_TEMPERATURE), typeof(PsuCommandByteResponse)); if (response.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)response.CompletionCode; Tracer.WriteWarning("LogPsuFaultStatus: Failed to read STATUS_TEMPERATURE on PSU {0}: Completion Code: {1}", psuId, response.CompletionCode); } else { Tracer.WriteWarning("LogPsuFaultStatus: PSU {0} STATUS_TEMPERATURE: {1}", psuId, System.Convert.ToString(response.PsuByteResponse, 2).PadLeft(8, '0')); } // STATUS_CML response = (PsuCommandByteResponse)this.SendReceive(this.PsuDeviceType, this.PsuId, new PsuRequest((byte)PmBusCommand.STATUS_CML, (byte)PmBusResponseLength.STATUS_CML), typeof(PsuCommandByteResponse)); if (response.CompletionCode != 0) { returnPacket.CompletionCode = (CompletionCode)response.CompletionCode; Tracer.WriteWarning("LogPsuFaultStatus: Failed to read STATUS_CML on PSU {0}: Completion Code: {1}", psuId, response.CompletionCode); } else { Tracer.WriteWarning("LogPsuFaultStatus: PSU {0} STATUS_CML: {1}", psuId, System.Convert.ToString(response.PsuByteResponse, 2).PadLeft(8, '0')); } } catch (System.Exception ex) { returnPacket.CompletionCode = CompletionCode.UnspecifiedError; Tracer.WriteError("LogPsuFaultStatus Exception: " + ex); } return(returnPacket); }
/// <summary> /// Class Constructor. /// </summary> static ConfigLoaded() { // check app.config for Population, if population is not found // in the app.config default the value to 24. int.TryParse(Config.AppSettings["Population"], out Population); Population = Population == 0 ? 24 : Population; // check app.config for MaxSerialConsolePorts, if MaxSerialConsolePorts is not found // in the app.config default the value to 1. int.TryParse(Config.AppSettings["MaxSerialConsolePorts"], out MaxSerialConsolePorts); MaxSerialConsolePorts = MaxSerialConsolePorts == 0 ? 1 : MaxSerialConsolePorts; int.TryParse(Config.AppSettings["InactiveSerialPortId"], out InactiveSerialPortId); InactiveSerialPortId = InactiveSerialPortId == 0 ? -1 : InactiveSerialPortId; InactiveSerialPortSessionToken = Config.AppSettings["InactiveSerialPortSessionToken"].ToString(); InactiveSerialPortSessionToken = InactiveSerialPortSessionToken == string.Empty ? "-1" : InactiveSerialPortSessionToken; SecretSerialPortSessionToken = Config.AppSettings["SecretSerialPortSessionToken"].ToString(); SecretSerialPortSessionToken = SecretSerialPortSessionToken == string.Empty ? "-99" : SecretSerialPortSessionToken; int.TryParse(Config.AppSettings["SerialPortConsoleClientSessionInactivityTimeoutInSecs"], out SerialPortConsoleClientSessionInactivityTimeoutInSecs); SerialPortConsoleClientSessionInactivityTimeoutInSecs = SerialPortConsoleClientSessionInactivityTimeoutInSecs == 0 ? 120 : SerialPortConsoleClientSessionInactivityTimeoutInSecs; int.TryParse(Config.AppSettings["SerialPortConsoleDeviceCommunicationTimeoutInMsecs"], out SerialPortConsoleDeviceCommunicationTimeoutInMsecs); SerialPortConsoleDeviceCommunicationTimeoutInMsecs = SerialPortConsoleDeviceCommunicationTimeoutInMsecs == 0 ? 100 : SerialPortConsoleDeviceCommunicationTimeoutInMsecs; int.TryParse(Config.AppSettings["InactiveBladePortId"], out InactiveBladePortId); InactiveBladePortId = InactiveBladePortId == 0 ? -1 : InactiveBladePortId; InactiveBladeSerialSessionToken = Config.AppSettings["InactiveBladeSerialSessionToken"].ToString(); InactiveBladeSerialSessionToken = InactiveBladeSerialSessionToken == string.Empty ? "-1" : InactiveBladeSerialSessionToken; int.TryParse(Config.AppSettings["SecretBladePortId"], out SecretBladePortId); SecretBladePortId = SecretBladePortId == 0 ? -99 : SecretBladePortId; SecretBladeSerialSessionToken = Config.AppSettings["SecretBladeSerialSessionToken"].ToString(); SecretBladeSerialSessionToken = SecretBladeSerialSessionToken == string.Empty ? "-99" : SecretBladeSerialSessionToken; int.TryParse(Config.AppSettings["bladeSerialTimeout"], out bladeSerialTimeout); bladeSerialTimeout = bladeSerialTimeout == 0 ? 2 : bladeSerialTimeout; int.TryParse(Config.AppSettings["SerialTimeout"], out SerialTimeout); SerialTimeout = SerialTimeout == 0 ? 100 : SerialTimeout; int.TryParse(Config.AppSettings["GpioErrorLimit"], out GpioErrorLimit); GpioErrorLimit = GpioErrorLimit == 0 ? 3 : GpioErrorLimit; // check app.config for BmcSessionTime. if not found, the default value // is 6. int.TryParse(Config.AppSettings["BmcSessionTime"], out BmcSessionTime); BmcSessionTime = BmcSessionTime == 0 ? 6 : BmcSessionTime; // check app.config for BmcUserName, if BmcUserName is not found // in the app.config default the value to root. BmcUserName = Config.AppSettings["BmcUserName"].ToString(); BmcUserName = BmcUserName == string.Empty ? "root" : BmcUserName; // check app.config for BmcUserKey, if BmcUserName is not found // in the app.config default the value to root. BmcUserKey = Config.AppSettings["BmcUserKey"].ToString(); BmcUserKey = BmcUserKey == string.Empty ? "root" : BmcUserKey; // check app.config for NumFans, if NumFans is not found // in the app.config default the value to 6. int.TryParse(Config.AppSettings["NumFans"], out NumFans); NumFans = NumFans == 0 ? 6 : NumFans; // check app.config for NumPsus, if NumPsus is not found // in the app.config default the value to 6. int.TryParse(Config.AppSettings["NumPsus"], out NumPsus); NumPsus = NumPsus == 0 ? 6 : NumPsus; // check app.config for NumNicsPerBlade, if not found // in the app.config default the value to 2. int.TryParse(Config.AppSettings["NumNicsPerBlade"], out NumNicsPerBlade); NumNicsPerBlade = NumNicsPerBlade == 0 ? 2 : NumNicsPerBlade; // check app.config for NumPowerSwitches, if NumPowerSwitches is not found // in the app.config default the value to 2. int.TryParse(Config.AppSettings["NumPowerSwitches"], out NumPowerSwitches); NumPowerSwitches = NumPowerSwitches == 0 ? 2 : NumPowerSwitches; // check app.config for WaitTimeAfterACSocketPowerOffInMsecs, if not found // in the app.config default the value to 1000 ms. int.TryParse(Config.AppSettings["WaitTimeAfterACSocketPowerOffInMsecs"], out WaitTimeAfterACSocketPowerOffInMsecs); WaitTimeAfterACSocketPowerOffInMsecs = WaitTimeAfterACSocketPowerOffInMsecs == 0 ? 1000 : WaitTimeAfterACSocketPowerOffInMsecs; // check app.config for WaitTimeAfterBladeHardPowerOffInMsecs, if not found // in the app.config default the value to 100 ms. int.TryParse(Config.AppSettings["WaitTimeAfterBladeHardPowerOffInMsecs"], out WaitTimeAfterBladeHardPowerOffInMsecs); WaitTimeAfterBladeHardPowerOffInMsecs = WaitTimeAfterBladeHardPowerOffInMsecs == 0 ? 100 : WaitTimeAfterBladeHardPowerOffInMsecs; // check app.config for ChassisManagerTraceFilePath, if not found // in the app.config default the value to C:\ChassisManagerTrace.txt. TraceLogFilePath = Config.AppSettings["TraceLogFilePath"].ToString(); TraceLogFilePath = TraceLogFilePath == string.Empty ? @"C:\ChassisManagerTrace.txt" : TraceLogFilePath; // check app.config for ChassisManagerTraceFileSize, if not found // in the app.config default the value to 100 KB. int.TryParse(Config.AppSettings["TraceLogFileSize"], out TraceLogFileSize); TraceLogFileSize = TraceLogFileSize == 0 ? 100 : TraceLogFileSize; // check app.config for ChassisManagerTraceFilePath, if not found // in the app.config default the value to C:\ChassisManagerTrace.txt. UserLogFilePath = Config.AppSettings["UserLogFilePath"].ToString(); UserLogFilePath = UserLogFilePath == string.Empty ? @"C:\ChassisManagerUserLog.txt" : UserLogFilePath; // check app.config for ChassisManagerUserFileSize, if not found // in the app.config default the value to 100 KB. int.TryParse(Config.AppSettings["UserLogFileSize"], out UserLogFileSize); UserLogFileSize = UserLogFileSize == 0 ? 100 : UserLogFileSize; // check app.config for GetTimePeriod, if it is not found // in the app.config default the value to 30000. int.TryParse(Config.AppSettings["GetTimePeriod"], out GetTimePeriod); GetTimePeriod = GetTimePeriod == 0 ? 30000 : GetTimePeriod; // check app.config for SetTimePeriod, if it is not found // in the app.config default the value to 30000. int.TryParse(Config.AppSettings["SetTimePeriod"], out SetTimePeriod); SetTimePeriod = SetTimePeriod == 0 ? 30000 : SetTimePeriod; // check app.config for MaxPWM, if it is not found // in the app.config default the value to 100. int.TryParse(Config.AppSettings["MaxPWM"], out MaxPWM); MaxPWM = MaxPWM == 0 ? 100 : MaxPWM; // check app.config for MinPWM, if it is not found // in the app.config default the value to 20. int.TryParse(Config.AppSettings["MinPWM"], out MinPWM); MinPWM = MinPWM == 0 ? 20 : MinPWM; // check app.config for StepPWM, if it is not found // in the app.config default the value to 10. int.TryParse(Config.AppSettings["StepPWM"], out StepPWM); StepPWM = StepPWM == 0 ? 10 : StepPWM; // check app.config for InputSensor, if it is not found // in the app.config default the value to 1. int.TryParse(Config.AppSettings["InputSensor"], out InputSensor); InputSensor = InputSensor == 0 ? 1 : InputSensor; // check app.config for SensorLowThreshold, if it is not found // in the app.config default the value to 0. int.TryParse(Config.AppSettings["SensorLowThreshold"], out SensorLowThreshold); SensorLowThreshold = SensorLowThreshold == 0 ? 0 : SensorLowThreshold; // check app.config for SensorHighThreshold, if it is not found // in the app.config default the value to 100. int.TryParse(Config.AppSettings["SensorHighThreshold"], out SensorHighThreshold); SensorHighThreshold = SensorHighThreshold == 0 ? 100 : SensorHighThreshold; // check app.config for AltitudeCorrectionFactor, if it is not found // in the app.config default the value to 0.032 (3.2%). float.TryParse(Config.AppSettings["AltitudeCorrectionFactor"], out AltitudeCorrectionFactor); AltitudeCorrectionFactor = AltitudeCorrectionFactor == 0 ? (float)0.032 : AltitudeCorrectionFactor; // check app.config for Altitude, if it is not found // in the app.config default the value to 0 (0 feet above sea level). int.TryParse(Config.AppSettings["Altitude"], out Altitude); Altitude = Altitude == 0 ? 0 : Altitude; // check app.config for MaxRetries, if it is not found // in the app.config default the value to 3. int.TryParse(Config.AppSettings["MaxRetries"], out MaxRetries); MaxRetries = MaxRetries == 0 ? 3 : MaxRetries; // check app.config for LEDHigh, if it is not found // in the app.config default the value to 255. int.TryParse(Config.AppSettings["LEDHigh"], out LEDHigh); LEDHigh = LEDHigh == 0 ? 255 : LEDHigh; // check app.config for LEDLow, if it is not found // in the app.config default the value to 0. int.TryParse(Config.AppSettings["LEDLow"], out LEDLow); LEDLow = LEDLow == 0 ? 0 : LEDLow; // check app.config for MinPowerLimit, if it is not found // in the app.config default the value to 120W. int.TryParse(Config.AppSettings["MinPowerLimit"], out MinPowerLimit); MinPowerLimit = MinPowerLimit == 0 ? 120 : MinPowerLimit; // check app.config for MaxPowerLimit, if it is not found // in the app.config default the value to 1000W. int.TryParse(Config.AppSettings["MaxPowerLimit"], out MaxPowerLimit); MaxPowerLimit = MaxPowerLimit == 0 ? 1000 : MaxPowerLimit; // check app.config for MaxFailCount, if it is not found // in the app.config default the value to 0. int.TryParse(Config.AppSettings["MaxFailCount"], out MaxFailCount); MaxFailCount = MaxFailCount == 0 ? 0 : MaxFailCount; // check app.config for CM Fru variables, if it is not found // in the app.config default the value FRU values found in Spec V1.0. int.TryParse(Config.AppSettings["CMStartingOffset"], out ChassisStartingOffset); ChassisStartingOffset = ChassisStartingOffset == 0 ? 0 : ChassisStartingOffset; int.TryParse(Config.AppSettings["CMFruLength"], out ChassisFruLength); ChassisFruLength = ChassisFruLength == 0 ? 256 : ChassisFruLength; int.TryParse(Config.AppSettings["InternalUseSize"], out InternalUseSize); InternalUseSize = InternalUseSize == 0 ? 72 : InternalUseSize; int.TryParse(Config.AppSettings["ChassisInfoSize"], out ChassisInfoSize); ChassisInfoSize = ChassisInfoSize == 0 ? 32 : ChassisInfoSize; int.TryParse(Config.AppSettings["BoardInfoSize"], out BoardInfoSize); BoardInfoSize = BoardInfoSize == 0 ? 64 : BoardInfoSize; int.TryParse(Config.AppSettings["ProductInfoSize"], out ProductInfoSize); ProductInfoSize = ProductInfoSize == 0 ? 80 : ProductInfoSize; // check app.config for Hard Disk Drive Sensor ids int.TryParse(Config.AppSettings["BladeDisk0"], out BladeDisk0); BladeDisk0 = BladeDisk0 == 0 ? 243 : BladeDisk0; int.TryParse(Config.AppSettings["BladeDisk1"], out BladeDisk1); BladeDisk1 = BladeDisk1 == 0 ? 244 : BladeDisk1; int.TryParse(Config.AppSettings["BladeDisk2"], out BladeDisk2); BladeDisk2 = BladeDisk2 == 0 ? 245 : BladeDisk2; int.TryParse(Config.AppSettings["BladeDisk3"], out BladeDisk3); BladeDisk3 = BladeDisk3 == 0 ? 246 : BladeDisk3; // check app.config for Health Diagnostics Sensor ids int.TryParse(Config.AppSettings["CPU0ProcHotSensor"], out CPU0ProcHotSensor); CPU0ProcHotSensor = CPU0ProcHotSensor == 0 ? 187 : CPU0ProcHotSensor; int.TryParse(Config.AppSettings["CPU1ProcHotSensor"], out CPU1ProcHotSensor); CPU1ProcHotSensor = CPU1ProcHotSensor == 0 ? 188 : CPU1ProcHotSensor; int.TryParse(Config.AppSettings["PCIeBusSensor"], out PCIeBusSensor); PCIeBusSensor = PCIeBusSensor == 0 ? 161 : PCIeBusSensor; int.TryParse(Config.AppSettings["SPSFWSensor"], out SPSFWSensor); SPSFWSensor = SPSFWSensor == 0 ? 23 : SPSFWSensor; // check app.config for MaxPortManagerWorkQueueLength, if it is not found // in the app.config default the value to 10. int.TryParse(Config.AppSettings["MaxPortManagerWorkQueueLength"], out MaxPortManagerWorkQueueLength); MaxPortManagerWorkQueueLength = MaxPortManagerWorkQueueLength == 0 ? 20 : MaxPortManagerWorkQueueLength; // check app.config for ServiceTimeoutInMinutes, if it is not found // in the app.config default the value to 2 minutes. double.TryParse(Config.AppSettings["ServiceTimeoutInMinutes"], out ServiceTimeoutInMinutes); ServiceTimeoutInMinutes = ServiceTimeoutInMinutes == 0 ? 2 : ServiceTimeoutInMinutes; // check app.config for CMServicePortNumber, if it is not found // in the app.config default the value to 8000. int.TryParse(Config.AppSettings["CmServicePortNumber"], out CmServicePortNumber); CmServicePortNumber = CmServicePortNumber < 1 ? 8000 : CmServicePortNumber; // check app.config for SslCertificateName, if not found // in the app.config default the value to "CMServiceServer". SslCertificateName = Config.AppSettings["SslCertificateName"].ToString(); SslCertificateName = SslCertificateName == string.Empty ? @"CMServiceServer" : SslCertificateName; // check app.config for EnableSslEncryption, if not found // in the app.config default the value to true/enable. int tempSslEncrypt = 1; int.TryParse(Config.AppSettings["EnableSslEncryption"], out tempSslEncrypt); EnableSslEncryption = tempSslEncrypt == 0 ? false : true; // Check App.config for KillSerialConsoleSession, if not found, default to true/enable. int tempKillSerialConsoleSession = 1; int.TryParse(Config.AppSettings["KillSerialConsoleSession"], out tempKillSerialConsoleSession); KillSerialConsoleSession = tempKillSerialConsoleSession == 0 ? false : true; // Check App.config for EnableFan, if not found, default to true/enable. int tempEnableFan = 1; int.TryParse(Config.AppSettings["EnableFan"], out tempEnableFan); EnableFan = tempEnableFan == 0 ? false : true; // check app.config for EventLogXml, if not found // in the app.config default the value to EventDataStrings.xml string evtLogFile = string.Empty; evtLogFile = Config.AppSettings["EventLogXml"].ToString(); evtLogFile = evtLogFile == string.Empty ? @"EventDataStrings.xml" : evtLogFile; // format event log strings dictionary Dictionary <string, string> formatStrings = new Dictionary <string, string>(); try { FileStream fs = new FileStream(evtLogFile, FileMode.Open, FileAccess.Read); XmlDocument XmlEventLogDoc = new XmlDocument(); // load xml document XmlEventLogDoc.Load(fs); // convert xml document into class objects EventStrings = XmlToObject("EventLogTypeCode", XmlEventLogDoc); // populate format event log strings dictionary XmlFormatStrings("EventLogStrings", formatStrings, XmlEventLogDoc); } catch (System.Exception ex) { Tracer.WriteWarning(string.Format("ERROR: Could not load Event Log Strings from {0}", evtLogFile)); Tracer.WriteError(ex); // set event strings to default empty list. EventStrings = new List <EventLogData>(); } if (formatStrings.ContainsKey("ErrorCode")) { EventLogStrError = formatStrings["ErrorCode"].ToString(); } else { EventLogStrError = string.Empty; } if (formatStrings.ContainsKey("Separator")) { EventLogStrSeparator = formatStrings["Separator"].ToString(); } else { EventLogStrSeparator = string.Empty; } if (formatStrings.ContainsKey("Space")) { EventLogStrSpacer = formatStrings["Space"].ToString(); } else { EventLogStrSpacer = string.Empty; } if (formatStrings.ContainsKey("SensorType")) { EventLogStrSensor = formatStrings["SensorType"].ToString(); } else { EventLogStrSensor = string.Empty; } if (formatStrings.ContainsKey("Unknown")) { Unknown = formatStrings["Unknown"].ToString(); } else { Unknown = string.Empty; } }
/// <summary> /// Unified API for querying user chassis audit logs - both timestamp and maxEntries used as input /// </summary> /// <param name="filterStartTime"></param> /// <param name="filterEndTime"></param> /// <param name="maxEntries"></param> /// <returns>Returns list of user log when success else returns null.</returns> public static List <LogEntry> GetFilteredLogEntries(DateTime filterStartTime, DateTime filterEndTime, int maxEntries) { if (Tracer.GetCurrentUserLogFilePath() == null) { return(null); } try { List <LogEntry> timestampFilteredEntries = new List <LogEntry>(); // Parse the log entries from each user log file // Note that these files could simultaneously be modified (switch primary, delete content etc) foreach (string filepath in Tracer.GetAllUserLogFilePaths()) { if (!File.Exists(filepath)) { Tracer.WriteInfo("UserLogXmllinqHelper.GetFilteredLogEntries(): Skipping file ({0}) since it does not exist."); continue; } using (FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (BufferedStream bstream = new BufferedStream(fileStream)) using (StreamReader reader = new StreamReader(bstream)) { int index = 0; const int count = 2048; // Reading 2K characters at a time to alleviate memory pressure // Splitting file with arbitrary chunks size may result in chopped 'partial' XML data which is saved in this variable // This data will be merged with the subsequent (consecutive) XML data string prevEntry = null; while (!reader.EndOfStream) { char[] localbuffer = new char[count]; reader.Read(localbuffer, index, count); string myData = new string(localbuffer); myData = prevEntry + myData; string[] subStrings = System.Text.RegularExpressions.Regex.Split(myData, @"ApplicationData>"); if (subStrings.Length < 1) { break; } prevEntry = subStrings[subStrings.Length - 1]; for (int i = 0; i < subStrings.Length - 1; i++) { string str = subStrings[i]; if (str.Length > 2 && str.Trim().EndsWith("</")) { string currentEntry = (str.Remove(str.Length - 2)); string[] tokens = currentEntry.Trim().Split(new char[] { ',' }); LogEntry timestampFilteredEntry = new LogEntry(); if (DateTime.TryParse(tokens[0], out timestampFilteredEntry.eventTime)) { timestampFilteredEntry.eventTime = DateTime.ParseExact(tokens[0], "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); timestampFilteredEntry.eventDescription = currentEntry.Replace(tokens[0] + ",", ""); // Add this entry to the list only when the timestamp falls withing the parameter input range if (timestampFilteredEntry.eventTime >= filterStartTime && timestampFilteredEntry.eventTime <= filterEndTime) { timestampFilteredEntries.Add(timestampFilteredEntry); } } else { Tracer.WriteWarning("GetFilteredLogEntries(): Reading Chassis user log - ignoring entry '({0})' due to unparse-able date ", tokens[0]); // Skipping the entry since date is not parse-able } } } prevEntry = subStrings[subStrings.Length - 1]; } } } timestampFilteredEntries.Reverse(); return(timestampFilteredEntries.Take(maxEntries).ToList()); } catch (Exception e) { Tracer.WriteError("GetFilteredLogEntries(): Reading Chassis user log exception " + e.Message); return(null); } }
private static List <EventLogData> XmlToObject(string xmlTag, XmlDocument xmlEventLogDoc) { List <EventLogData> response = new List <EventLogData>(); try { XmlNodeList rootNodeList = xmlEventLogDoc.GetElementsByTagName(xmlTag); if (rootNodeList.Count > 0) { // root level node: EventLogTypeCode foreach (XmlNode root in rootNodeList) { // GenericEvent/SensorSpecificEvent foreach (XmlNode node in root.ChildNodes) { EventLogMsgType clasification = GetEventLogClass(node.Name.ToString()); XmlNodeList firstTierNodes = node.ChildNodes; // enumerate first level child nodes foreach (XmlNode firstNode in firstTierNodes) { int number = Convert.ToInt32(firstNode.Attributes["Number"].Value.ToString()); string description = firstNode.Attributes["ReadingClass"].Value.ToString(); XmlNodeList secondTierNodes = firstNode.ChildNodes; // enumerate second level xml nodes foreach (XmlNode secondNode in secondTierNodes) { int offset = Convert.ToInt32(secondNode.Attributes["Number"].Value.ToString()); string message = secondNode.Attributes["Description"].Value.ToString(); EventLogData respObj = new EventLogData(number, offset, clasification, message, description); XmlNodeList thirdTierNodes = secondNode.ChildNodes; if (thirdTierNodes.Count > 0) { // enumerate third level xml nodes foreach (XmlNode extension in thirdTierNodes) { int id = Convert.ToInt32(extension.Attributes["Number"].Value.ToString()); string detail = extension.Attributes["Description"].Value.ToString(); respObj.AddExtension(id, detail); } // enumerate third level xml nodes } response.Add(respObj); } // enumerate second level xml nodes } // enumerate first level child nodes } // GenericEvent/SensorSpecificEvent } } else { Tracer.WriteWarning("ERROR: Could not load Event Log Strings, could not find xml root node in file"); } } catch (Exception ex) { Tracer.WriteError(string.Format("ERROR: Could not load Event Log Strings. Error: {0}", ex.ToString())); } return(response); }
/// <summary> /// Class Constructor. /// </summary> static ConfigLoaded() { // check app.config for Join Timeout in seconds int joinTimeout; int.TryParse(Config.AppSettings["JoinTimeout"], out joinTimeout); ThreadJoinTimeout = joinTimeout == 0 ? TimeSpan.FromSeconds(10) : TimeSpan.FromSeconds(joinTimeout); // check app.config for Population, if population is not found // in the app.config default the value to 24. int.TryParse(Config.AppSettings["Population"], out Population); Population = Population == 0 ? 24 : Population; // check app.config for MaxSerialConsoleSessions, if MaxSerialConsoleSessions is not found // in the app.config default the value to 12. uint.TryParse(Config.AppSettings["MaxSerialConsoleSessions"], out MaxSerialConsoleSessions); MaxSerialConsoleSessions = MaxSerialConsoleSessions == 0 ? 12 : MaxSerialConsoleSessions; // check app.config for MaxSerialConsolePorts, if MaxSerialConsolePorts is not found // in the app.config default the value to 1. int.TryParse(Config.AppSettings["MaxSerialConsolePorts"], out MaxSerialConsolePorts); MaxSerialConsolePorts = MaxSerialConsolePorts == 0 ? 1 : MaxSerialConsolePorts; // Time for BMC to decompress firmware and start responding after power on. // This is the firmware decompression time. int.TryParse(Config.AppSettings["FirmwareDecompressionTime"], out FirmwareDecompressionTime); FirmwareDecompressionTime = FirmwareDecompressionTime == 0 ? 28 : FirmwareDecompressionTime; int manufacturerId; int.TryParse(Config.AppSettings["MultiRecordFruManufacturerId"], out manufacturerId); manufacturerId = manufacturerId == 0 ? 311 : manufacturerId; ConvertIanaManufactureId(manufacturerId); int fruWritesRemaining = 0; int.TryParse(Config.AppSettings["ResetMultiRecordFruWritesRemaining"], out fruWritesRemaining); ResetMultiRecordFruWritesRemaining = fruWritesRemaining == 0 ? false : true; int.TryParse(Config.AppSettings["SerialPortConsoleClientSessionInactivityTimeoutInSecs"], out SerialPortConsoleClientSessionInactivityTimeoutInSecs); SerialPortConsoleClientSessionInactivityTimeoutInSecs = SerialPortConsoleClientSessionInactivityTimeoutInSecs == 0 ? 120 : SerialPortConsoleClientSessionInactivityTimeoutInSecs; int.TryParse(Config.AppSettings["SerialPortConsoleDeviceCommunicationTimeoutInMsecs"], out SerialPortConsoleDeviceCommunicationTimeoutInMsecs); SerialPortConsoleDeviceCommunicationTimeoutInMsecs = SerialPortConsoleDeviceCommunicationTimeoutInMsecs == 0 ? 100 : SerialPortConsoleDeviceCommunicationTimeoutInMsecs; // Default to 300 seconds if app.config setting is 0, negative or an invalid string uint.TryParse(Config.AppSettings["BladeSerialTimeout"], out BladeSerialTimeout); BladeSerialTimeout = BladeSerialTimeout == 0 ? 300 : BladeSerialTimeout; int.TryParse(Config.AppSettings["SerialTimeout"], out SerialTimeout); SerialTimeout = SerialTimeout == 0 ? 100 : SerialTimeout; int.TryParse(Config.AppSettings["GpioErrorLimit"], out GpioErrorLimit); GpioErrorLimit = GpioErrorLimit == 0 ? 3 : GpioErrorLimit; // check app.config for BmcSessionTime. if not found, the default value // is 6. int.TryParse(Config.AppSettings["BmcSessionTime"], out BmcSessionTime); BmcSessionTime = BmcSessionTime == 0 ? 6 : BmcSessionTime; // check app.config for BmcUserName, if BmcUserName is not found // in the app.config default the value to root. BmcUserName = Config.AppSettings["BmcUserName"]; BmcUserName = string.IsNullOrEmpty(BmcUserName) ? "root" : BmcUserName; // check app.config for BmcUserKey, if BmcUserName is not found // in the app.config default the value to root. BmcUserKey = Config.AppSettings["BmcUserKey"]; BmcUserKey = string.IsNullOrEmpty(BmcUserKey) ? "root" : BmcUserKey; // check app.config for NumFans, if NumFans is not found // in the app.config default the value to 6. int.TryParse(Config.AppSettings["NumFans"], out NumFans); NumFans = NumFans < 0 ? 6 : NumFans; // check app.config for NumPsus, if NumPsus is not found // in the app.config default the value to 6. int.TryParse(Config.AppSettings["NumPsus"], out NumPsus); NumPsus = NumPsus < 0 ? 6 : NumPsus; // check app.config for NumBatteries, if NumBatteries is not found // in the app.config default the value to 6. int.TryParse(Config.AppSettings["NumBatteries"], out NumBatteries); NumBatteries = NumBatteries < 0 ? 6 : NumBatteries; // check app.config for NumNicsPerBlade, if not found // in the app.config default the value to 2. int.TryParse(Config.AppSettings["NumNicsPerBlade"], out NumNicsPerBlade); NumNicsPerBlade = NumNicsPerBlade == 0 ? 2 : NumNicsPerBlade; // check app.config for NumPowerSwitches, if NumPowerSwitches is not found // in the app.config default the value to 2. int.TryParse(Config.AppSettings["NumPowerSwitches"], out NumPowerSwitches); NumPowerSwitches = NumPowerSwitches < 0 ? 0 : NumPowerSwitches; // check app.config for WaitTimeAfterACSocketPowerOffInMsecs, if not found // in the app.config default the value to 1000 ms. int.TryParse(Config.AppSettings["WaitTimeAfterACSocketPowerOffInMsecs"], out WaitTimeAfterACSocketPowerOffInMsecs); WaitTimeAfterACSocketPowerOffInMsecs = WaitTimeAfterACSocketPowerOffInMsecs == 0 ? 1000 : WaitTimeAfterACSocketPowerOffInMsecs; // check app.config for WaitTimeAfterBladeHardPowerOffInMsecs, if not found // in the app.config default the value to 100 ms. int.TryParse(Config.AppSettings["WaitTimeAfterBladeHardPowerOffInMsecs"], out WaitTimeAfterBladeHardPowerOffInMsecs); WaitTimeAfterBladeHardPowerOffInMsecs = WaitTimeAfterBladeHardPowerOffInMsecs == 0 ? 100 : WaitTimeAfterBladeHardPowerOffInMsecs; // check app.config for ChassisManagerTraceFilePath, if not found // in the app.config default the value to C:\ChassisManagerTrace.txt. TraceLogFilePath = Config.AppSettings["TraceLogFilePath"]; TraceLogFilePath = string.IsNullOrEmpty(TraceLogFilePath) ? @"C:\ChassisManagerTrace.txt" : TraceLogFilePath; // check app.config for ChassisManagerTraceFileSize, if not found // in the app.config default the value to 100 KB. int.TryParse(Config.AppSettings["TraceLogFileSize"], out TraceLogFileSize); TraceLogFileSize = TraceLogFileSize == 0 ? 100 : TraceLogFileSize; // check app.config for ChassisManagerTraceFilePath, if not found // in the app.config default the value to C:\ChassisManagerTrace.txt. UserLogFilePath = Config.AppSettings["UserLogFilePath"]; UserLogFilePath = string.IsNullOrEmpty(UserLogFilePath) ? @"C:\ChassisManagerUserLog.txt" : UserLogFilePath; // check app.config for ChassisManagerUserFileSize, if not found // in the app.config default the value to 100 KB. int.TryParse(Config.AppSettings["UserLogFileSize"], out UserLogFileSize); UserLogFileSize = UserLogFileSize == 0 ? 100 : UserLogFileSize; // check app.config for UserLogMaxEntries, if not found // in the app.config default the value to 50 entries. int.TryParse(Config.AppSettings["UserLogMaxEntries"], out UserLogMaxEntries); UserLogMaxEntries = UserLogMaxEntries == 0 ? 50 : UserLogMaxEntries; // check app.config for MaxPWM, if it is not found // in the app.config default the value to 100. int.TryParse(Config.AppSettings["MaxPWM"], out MaxPWM); MaxPWM = MaxPWM == 0 ? 100 : MaxPWM; // check app.config for MinPWM, if it is not found // in the app.config default the value to 20. int.TryParse(Config.AppSettings["MinPWM"], out MinPWM); MinPWM = MinPWM == 0 ? 20 : MinPWM; // check app.config for StepPWM, if it is not found // in the app.config default the value to 10. int.TryParse(Config.AppSettings["StepPWM"], out StepPWM); StepPWM = StepPWM == 0 ? 10 : StepPWM; // check app.config for InputSensor, if it is not found // in the app.config default the value to 1. int.TryParse(Config.AppSettings["InputSensor"], out InputSensor); InputSensor = InputSensor == 0 ? 1 : InputSensor; // check app.config for Inlet, if it is not found // in the app.config default the value to 176. int.TryParse(Config.AppSettings["InletSensor"], out InletSensor); InletSensor = InletSensor == 0 ? 176 : InletSensor; // check app.config for Inlet Offset, if it is not found // in the app.config default the value to false. int InletOffSet = 0; int.TryParse(Config.AppSettings["EnableInletOffSet"], out InletOffSet); EnableInletOffSet = InletOffSet == 0 ? false : true; // check app.config for SensorLowThreshold, if it is not found // in the app.config default the value to 0. int.TryParse(Config.AppSettings["SensorLowThreshold"], out SensorLowThreshold); SensorLowThreshold = SensorLowThreshold == 0 ? 0 : SensorLowThreshold; // check app.config for SensorHighThreshold, if it is not found // in the app.config default the value to 100. int.TryParse(Config.AppSettings["SensorHighThreshold"], out SensorHighThreshold); SensorHighThreshold = SensorHighThreshold == 0 ? 100 : SensorHighThreshold; // check app.config for AltitudeCorrectionFactor, if it is not found // in the app.config default the value to 0.032 (3.2%). float.TryParse(Config.AppSettings["AltitudeCorrectionFactor"], out AltitudeCorrectionFactor); AltitudeCorrectionFactor = AltitudeCorrectionFactor == 0 ? (float)0.032 : AltitudeCorrectionFactor; // check app.config for Altitude, if it is not found // in the app.config default the value to 0 (0 feet above sea level). int.TryParse(Config.AppSettings["Altitude"], out Altitude); Altitude = Altitude == 0 ? 0 : Altitude; // check app.config for MaxRetries, if it is not found // in the app.config default the value to 3. int.TryParse(Config.AppSettings["MaxRetries"], out MaxRetries); MaxRetries = MaxRetries == 0 ? 3 : MaxRetries; // check app.config for LEDHigh, if it is not found // in the app.config default the value to 255. int.TryParse(Config.AppSettings["LEDHigh"], out LEDHigh); LEDHigh = LEDHigh == 0 ? 255 : LEDHigh; // check app.config for MinPowerLimit, if it is not found // in the app.config default the value to 120W. int.TryParse(Config.AppSettings["MinPowerLimit"], out MinPowerLimit); MinPowerLimit = MinPowerLimit == 0 ? 120 : MinPowerLimit; // check app.config for MaxPowerLimit, if it is not found // in the app.config default the value to 1000W. int.TryParse(Config.AppSettings["MaxPowerLimit"], out MaxPowerLimit); MaxPowerLimit = MaxPowerLimit == 0 ? 1000 : MaxPowerLimit; // check app.config for SetPowerLimitCorrectionTimeInMilliseconds, if it is not found // in the app.config default the value to 6000ms. int.TryParse(Config.AppSettings["SetPowerLimitCorrectionTimeInMilliseconds"], out SetPowerLimitCorrectionTimeInMilliseconds); SetPowerLimitCorrectionTimeInMilliseconds = SetPowerLimitCorrectionTimeInMilliseconds == 0 ? 6000 : SetPowerLimitCorrectionTimeInMilliseconds; // check app.config for MaxFailCount, if it is not found // in the app.config default the value to 0. int.TryParse(Config.AppSettings["MaxFailCount"], out MaxFailCount); MaxFailCount = MaxFailCount == 0 ? 0 : MaxFailCount; // check app.config for MaxPortManagerWorkQueueLength, if it is not found // in the app.config default the value to 10. int.TryParse(Config.AppSettings["MaxPortManagerWorkQueueLength"], out MaxPortManagerWorkQueueLength); MaxPortManagerWorkQueueLength = MaxPortManagerWorkQueueLength == 0 ? 20 : MaxPortManagerWorkQueueLength; // check app.config for ServiceTimeoutInMinutes, if it is not found // in the app.config default the value to 2 minutes. double.TryParse(Config.AppSettings["ServiceTimeoutInMinutes"], out ServiceTimeoutInMinutes); ServiceTimeoutInMinutes = ServiceTimeoutInMinutes == 0 ? 2 : ServiceTimeoutInMinutes; // check app.config for CMServicePortNumber, if it is not found // in the app.config default the value to 8000. int.TryParse(Config.AppSettings["CmServicePortNumber"], out CmServicePortNumber); CmServicePortNumber = CmServicePortNumber < 1 ? 8000 : CmServicePortNumber; // check app.config for SslCertificateName, if not found // in the app.config default the value to "CMServiceServer". SslCertificateName = Config.AppSettings["SslCertificateName"]; SslCertificateName = string.IsNullOrEmpty(SslCertificateName) ? @"CMServiceServer" : SslCertificateName; // check app.config for EnableSslEncryption, if not found // in the app.config default the value to true/enable. int tempSslEncrypt = 1; int.TryParse(Config.AppSettings["EnableSslEncryption"], out tempSslEncrypt); EnableSslEncryption = tempSslEncrypt == 0 ? false : true; // Check App.config for EnableFan, if not found, default to true/enable. int tempEnableFan = 1; int.TryParse(Config.AppSettings["EnableFan"], out tempEnableFan); EnableFan = tempEnableFan == 0 ? false : true; // Check App.config for EnableBatteryMonitoring int batteryMonitoring; int.TryParse(Config.AppSettings["EnableBatteryMonitoring"], out batteryMonitoring); BatteryMonitoringEnabled = (batteryMonitoring == 0 ? false : true); // Check App.config for EnablePsuAlert int psuAlert; int.TryParse(Config.AppSettings["EnablePsuAlertMonitoring"], out psuAlert); PsuAlertMonitorEnabled = (psuAlert == 0 ? false : true); // Check App.config for EnableDatasafeAPIs int datasafeOperations; int.TryParse(Config.AppSettings["EnableDatasafeAPIs"], out datasafeOperations); DatasafeOperationsEnabled = (datasafeOperations == 0 ? false : true); // Check App.config for EnablePowerAlertDrivenPowerCapAPIs int powerAlertAPIs; int.TryParse(Config.AppSettings["EnablePowerAlertDrivenPowerCapAPIs"], out powerAlertAPIs); PowerAlertDrivenPowerCapAPIsEnabled = (powerAlertAPIs == 0 ? false : true); // Check App.config for DpcAutoDeassert int dpcAuto; int.TryParse(Config.AppSettings["DpcAutoDeassert"], out dpcAuto); DpcAutoDeassert = (dpcAuto == 0 ? false : true); int.TryParse(Config.AppSettings["PsuAlertPollInterval"], out PsuAlertPollInterval); PsuAlertPollInterval = PsuAlertPollInterval < 3 ? 3 : PsuAlertPollInterval; int.TryParse(Config.AppSettings["PsuPollInterval"], out PsuPollInterval); PsuPollInterval = PsuPollInterval < 10 ? 10 : PsuPollInterval; // Flag for forcing instantiation of unknown PSUs to Emerson PSUs. int forceEmersonPsuFlag = 0; int.TryParse(Config.AppSettings["ForceEmersonPsu"], out forceEmersonPsuFlag); ForceEmersonPsu = forceEmersonPsuFlag == 0 ? false : true; int.TryParse(Config.AppSettings["NvDimmPerBlade"], out NvDimmPerBlade); NvDimmPerBlade = NvDimmPerBlade == 0 ? 2 : NvDimmPerBlade; int.TryParse(Config.AppSettings["NvDimmTriggerFailureCount"], out NvDimmTriggerFailureCount); NvDimmTriggerFailureCount = NvDimmTriggerFailureCount < 1 ? 1 : NvDimmTriggerFailureCount; int.TryParse(Config.AppSettings["NvDimmTriggerFailureAction"], out NvDimmTriggerFailureAction); NvDimmTriggerFailureAction = NvDimmTriggerFailureAction < 0 ? 0 : NvDimmTriggerFailureAction; int.TryParse(Config.AppSettings["AdrCompleteDelay"], out AdrCompleteDelay); AdrCompleteDelay = AdrCompleteDelay == 0 ? 5 : AdrCompleteDelay; int.TryParse(Config.AppSettings["NvDDimmPresentPowerOffDelay"], out NvDimmPresentPowerOffDelay); NvDimmPresentPowerOffDelay = NvDimmPresentPowerOffDelay == 0 ? 160 : NvDimmPresentPowerOffDelay; // check app.config for ProcessBatteryStatus // if not found in the app.config default the value to false. int tempProcessBatteryStatus = 0; int.TryParse(Config.AppSettings["ProcessBatteryStatus"], out tempProcessBatteryStatus); ProcessBatteryStatus = tempProcessBatteryStatus == 0 ? false : true; // check app.config for BatteryChargeLevelThreshold // if not found in the app.config default the value to 50 percent. double.TryParse(Config.AppSettings["BatteryChargeLevelThreshold"], out BatteryChargeLevelThreshold); BatteryChargeLevelThreshold = BatteryChargeLevelThreshold == 0 ? 50 : BatteryChargeLevelThreshold; // check app.config for BatteryDischargeTimeInSecs // if not found in the app.config default the value to 35 seconds. int.TryParse(Config.AppSettings["BatteryDischargeTimeInSecs"], out BatteryDischargeTimeInSecs); BatteryDischargeTimeInSecs = BatteryDischargeTimeInSecs == 0 ? 35 : BatteryDischargeTimeInSecs; // check app.config for SerialSessionPowerOnWait // if not found in the app.config default the value to 5000 ms. int.TryParse(Config.AppSettings["SerialSessionPowerOnWait"], out SerialSessionPowerOnWait); SerialSessionPowerOnWait = SerialSessionPowerOnWait == 0 ? 5000 : SerialSessionPowerOnWait; // check app.config for SerialSessionPowerOnRetry // if not found in the app.config default the value to 10. int.TryParse(Config.AppSettings["SerialSessionPowerOnRetry"], out SerialSessionPowerOnRetry); SerialSessionPowerOnRetry = SerialSessionPowerOnRetry == 0 ? 10 : SerialSessionPowerOnRetry; // check app.config for EventLogXml, if not found // in the app.config default the value to EventDataStrings.xml string evtLogFile = string.Empty; evtLogFile = Config.AppSettings["EventLogXml"]; evtLogFile = string.IsNullOrEmpty(evtLogFile) ? @"EventDataStrings.xml" : evtLogFile; // format event log strings dictionary Dictionary <string, string> formatStrings = new Dictionary <string, string>(); try { FileStream fs = new FileStream(evtLogFile, FileMode.Open, FileAccess.Read); XmlDocument XmlEventLogDoc = new XmlDocument(); // load xml document XmlEventLogDoc.Load(fs); // convert xml document into class objects EventStrings = XmlToObject("EventLogTypeCode", XmlEventLogDoc); // populate format event log strings dictionary XmlFormatStrings("EventLogStrings", formatStrings, XmlEventLogDoc); } catch (System.Exception ex) { Tracer.WriteWarning(string.Format("ERROR: Could not load Event Log Strings from {0}", evtLogFile)); Tracer.WriteError(0, "ConfigLoaded.Configloaded", ex); // set event strings to default empty list. EventStrings = new List <EventLogData>(); } if (formatStrings.ContainsKey("EventData")) { EventData = formatStrings["EventData"]; } else { EventData = string.Empty; } if (formatStrings.ContainsKey("Separator")) { EventLogStrSeparator = formatStrings["Separator"]; } else { EventLogStrSeparator = string.Empty; } if (formatStrings.ContainsKey("Space")) { EventLogStrSpacer = formatStrings["Space"]; } else { EventLogStrSpacer = string.Empty; } if (formatStrings.ContainsKey("SensorType")) { EventLogStrSensor = formatStrings["SensorType"]; } else { EventLogStrSensor = string.Empty; } if (formatStrings.ContainsKey("Unknown")) { Unknown = formatStrings["Unknown"]; } else { Unknown = string.Empty; } }
/// <summary> /// Every component in the higher level of the stack should call this method /// to send/receive data to/from actual hardware devices /// </summary> /// <param name="priorityLevel"></param> /// <param name="deviceType"></param> /// <param name="deviceId"></param> /// <param name="request"> /// Input /// [0]: function code /// [1:2]: byte count (N) /// [3:N+2]: payload /// </param> /// <param name="response"> /// Output /// [0]: completion code /// [1:2]: byte count (N) /// [3:N+2]: payload /// Note: response can be null /// </param> static internal void SendReceive(PriorityLevel priorityLevel, byte deviceType, byte deviceId, byte[] request, out byte[] response) { Tracer.WriteInfo("CommunicationDevice.SendReceive({0})", deviceType); ushort sessionId = IncrementTimeStampAndGetSessionId(); byte physicalId; // If CM is terminating, do not accept any more new requests if (isTerminating == true) { ResponsePacketUtil.GenerateResponsePacket(CompletionCode.ServiceTerminating, out response); return; } if (IsValidRequest(deviceType, deviceId, ref request) == false) { ResponsePacketUtil.GenerateResponsePacket(CompletionCode.InvalidCommand, out response); return; } physicalId = GetPhysicalIdFromLogicalId(deviceType, deviceId); Tracer.WriteInfo("CommunicationDevice.SendReceive PhysicalID ({0})", physicalId); using (WorkItem workItem = new WorkItem(deviceType, physicalId, request, sessionId)) { byte logicalPortId = (byte)LogicalPortId.InvalidLogicalPortId; byte functionCode = RequestPacketUtil.GetFunctionCode(ref request); switch (deviceType) { case (byte)DeviceType.Server: // Fall through case (byte)DeviceType.BladeConsole: logicalPortId = (byte)LogicalPortId.SerialPortServers; break; case (byte)DeviceType.SerialPortConsole: // TODO: Extend the code for more serial consoles if (deviceId == 1) { logicalPortId = (byte)LogicalPortId.SerialPortConsole1; } else if (deviceId == 2) { logicalPortId = (byte)LogicalPortId.SerialPortConsole2; } else if (deviceId == 3) { logicalPortId = (byte)LogicalPortId.SerialPortConsole3; } else if (deviceId == 4) { logicalPortId = (byte)LogicalPortId.SerialPortConsole4; } break; default: logicalPortId = (byte)LogicalPortId.SerialPortOtherDevices; break; } if (logicalPortId == (byte)LogicalPortId.InvalidLogicalPortId) { ResponsePacketUtil.GenerateResponsePacket(CompletionCode.InvalidCommand, out response); return; } // If currently in safe mode, reject all the requests routed to COM4 except for BladeConsole commands if ((isSafeModeEnabled == true) && (logicalPortId == (byte)LogicalPortId.SerialPortServers) && (deviceType != (byte)DeviceType.BladeConsole)) { ResponsePacketUtil.GenerateResponsePacket(CompletionCode.CannotExecuteRequestInSafeMode, out response); return; } if (portManagers[logicalPortId].SendReceive(priorityLevel, workItem) == true) { // Successfully added the request in the work queue Tracer.WriteInfo("[logicalPortId: {0}, priorityLevel: {1}] SendReceive succeeded and wait", logicalPortId, priorityLevel); // Sleep until signaled by the device worker thread // Wait time: wait time in the queue + worker thread processing time workItem.Wait(); // Copy the response to the output buffer workItem.GetResponse(out response); } else { // Could not add the reuqest in the work queue Tracer.WriteWarning("[logicalPortId: {0}, priorityLevel: {1}] SendReceive failed", logicalPortId, priorityLevel); ResponsePacketUtil.GenerateResponsePacket(CompletionCode.OutOfSpace, out response); } } }
/// <summary> /// Function that gets fan speed requirements /// from all blades. It also updates the blade states. /// </summary> private static void GetAllBladePwmRequirements() { // Rate is required to timestep over each individual Blade call double rate = (double)getBladePwmReqtTimePeriodInMilliseconds / (double)MaxSledCount; double timeDiff = 0; for (byte blade = 1; blade <= MaxSledCount; blade++) { // Handle shutdown state if (ChassisState.ShutDown) { return; } // default PWM setting byte PWM = (byte)ConfigLoaded.MinPWM; // Query blade type from IPMI layer ChassisState.BladeTypeCache[blade - 1] = (byte)WcsBladeFacade.clients[blade].BladeClassification; // wait for rate limiter which includes the previous time difference for sensor get, and then issue get fan requirement double sleepTime = rate - timeDiff; if (sleepTime > rate) { sleepTime = rate; } if (sleepTime > 0) { Thread.Sleep(TimeSpan.FromMilliseconds(sleepTime)); } Tracer.WriteInfo("GetBladeRequirement called at {0} for BladeId {1} (state: {2})", DateTime.Now, blade, ChassisState.GetStateName(blade)); // Check for the condition where known state is hardpoweroff, but someone plugged a new blade in if (ChassisState.GetBladeState(blade) == (byte)BladeState.HardPowerOff) { CheckPowerEnableState(blade); } // Log Start time DateTime startTime = DateTime.Now; #region Check fail State -> Initialize // If blade was in Fail state if (ChassisState.GetBladeState(blade) == (byte)BladeState.Fail) { // If failed count is greater than a maximum value, we move it to Initialization state if (ChassisState.FailCount[blade - 1] > ConfigLoaded.MaxFailCount) { // Move to Initialization state so that this blade could be reinitialized Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for blade {0}: {1} -> Initialization", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Initialization); } else { // Moving out of Fail state - First we use a light-weight get GUID to check whether the blade is there. // do not allow retries on Get System Guid DeviceGuid guid = WcsBladeFacade.GetSystemGuid(blade, false); if (guid.CompletionCode == (byte)CompletionCode.Success) { Tracer.WriteInfo("GetAllBladePwmRequirements: GUID present for blade {0}, GUID: {1}", blade, guid.Guid.ToString()); DeviceGuid cachedGuid = WcsBladeFacade.GetCachedGuid(blade); if (guid.Guid == cachedGuid.Guid) { // Change state to Probation and assume the system was in fail due to timeout. Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for blade {0}: {1} -> Probation", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Probation); } else { // Change state to Initialization as the device has changed. Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for blade {0}: {1} -> Probation", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Initialization); } } else { Tracer.WriteInfo("GetAllBladePwmRequirements: Get System GUID returns a bad completion status: {0}", guid.CompletionCode); } } // Increase time spent in Fail state everytime we are in this state ChassisState.FailCount[blade - 1]++; } #endregion #region Move Initialize -> Probation // Handles Initialization if (ChassisState.GetBladeState(blade) == (byte)BladeState.Initialization) { BladePowerStatePacket powerstate = ChassisState.BladePower[blade - 1].GetCachedBladePowerState(); if (powerstate.CompletionCode == 0) { if (powerstate.DecompressionTime == 0) { // Will result in Hard Power off or Probation ReInitialize(blade); } } } #endregion // Normal operation - possible states are probation or healthy if (ChassisState.GetBladeState(blade) == (byte)BladeState.Probation || ChassisState.GetBladeState(blade) == (byte)BladeState.Healthy) { #region Jbod (no sensor reading) if (ChassisState.GetBladeType(blade) == (byte)BladeType.Jbod) { // Do not allow retries on system guid. DeviceGuid guid = WcsBladeFacade.GetSystemGuid(blade, false); if (guid.CompletionCode == (byte)CompletionCode.Success) { Tracer.WriteInfo("GetAllBladePwmRequirements: GUID present for JBOD {0}, GUID: {1}", blade, guid.Guid.ToString()); // Change state to Healthy if (ChassisState.GetBladeState(blade) == (byte)BladeState.Probation) { Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for JBOD {0}: {1} -> Healthy", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Healthy); } } else { Tracer.WriteInfo("GetAllBladePwmRequirements: Get System GUID for JBOD {0} failed with status {1}", blade, guid.CompletionCode); // Set it to failed state, where we will retry guids and reinitialize if needed Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for JBOD {0}: {1} -> Fail", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Fail); } // No need to check for sensor reading, just continue continue; } #endregion #region Server -> Get PWM move to Healthy or move to Fail // Call temperature reading list command SensorReading Temps = WcsBladeFacade.GetSensorReading((byte)blade, (byte)ConfigLoaded.InputSensor, PriorityLevel.System); if (Temps.CompletionCode != (byte)CompletionCode.Success) { Tracer.WriteWarning("GetAllBladePwmRequirements: BladeId: {0} - GetSensorReading for temperature failed with code {1:X}", blade, Temps.CompletionCode); // Move to Fail state if no readings were obtained Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for blade {0}: {1} -> Fail", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Fail); } else { Tracer.WriteInfo("GetAllBladePwmRequirements: #### BladeId = " + blade + " Sensor id= " + ConfigLoaded.InputSensor + " Sensor reading = " + Temps.Reading + " Raw = " + Temps.RawReading + ", LowerNonCritical= " + ConfigLoaded.SensorLowThreshold + ", UpperNonCritical= " + ConfigLoaded.SensorHighThreshold); // Handle state logic if needed // Probation state should be shifted to Healthy since there was no timeout, & sensorread succeeded if (ChassisState.GetBladeState(blade) == (byte)BladeState.Probation) { // Change state to healthy Tracer.WriteInfo("GetAllBladePwmRequirements: State Transition for blade {0}: {1} -> Healthy", blade, ChassisState.GetStateName(blade)); ChassisState.SetBladeState(blade, (byte)BladeState.Healthy); ChassisState.FailCount[blade - 1] = 0; // reset the fail count // When a blade transitions to 'Healthy' state, enable/disable default blade operations EnableDisableDefaultBladeOperations(blade); } if (ConfigLoaded.InputSensor != 1) // Non-PWM sensor. { PWM = GetPwmFromTemperature(Temps.Reading, ConfigLoaded.SensorLowThreshold, ConfigLoaded.SensorHighThreshold); } else { // PWM should never be higher or lower than the threshold. if (Temps.Reading < ConfigLoaded.MinPWM || Temps.Reading > ConfigLoaded.MaxPWM) { Tracer.WriteWarning("PWM value " + Temps.Reading + " on blade " + blade + " is out of range (lowThreshold: " + ConfigLoaded.MinPWM + " - highThreshold: " + ConfigLoaded.MaxPWM); PWM = (byte)ConfigLoaded.MinPWM; } else { PWM = (byte)Temps.Reading; } } Tracer.WriteInfo("PWM value on blade {0} for Sensor {1} = {2}", blade, InputSensor, PWM); } #endregion } // write value into requirements table BladeRequirementTable[blade - 1] = PWM; // Log end time and capture time of execution for sensor get command DateTime endTime = DateTime.Now; timeDiff = endTime.Subtract(startTime).TotalMilliseconds; // convert time difference into milliseconds } }
/// <summary> /// Sets the chassis fan speed /// </summary> private static void SetAllFanSpeeds() { // rate limiter for setting thread Thread.Sleep(TimeSpan.FromMilliseconds(setTimePeriodInMilliseconds)); // Get max requirement from the bladerequirement table byte maxFanRequest = GetMaxRequirement(); Tracer.WriteInfo("Max value got from Blade table = {0} (at {1})", maxFanRequest, DateTime.Now); // Check Fan Status and get number of working fans int numFansWorking = GetAllFanStatus(); // Handle one fan failure if (numFansWorking == MaxFanCount - 1) { // Alert that one fan has failed! Tracer.WriteError("Fan failure. Scaling fan speed up proportionally to handle one fan failure."); // Denote fan failure in chassis ChassisState.FanFailure = true; double conversion = (double)MaxFanCount / (double)(MaxFanCount - 1); maxFanRequest = (byte)(conversion * maxFanRequest); } else if (numFansWorking < MaxFanCount - 1) { // Set fan speed to max for fan failures more than N-1 maxFanRequest = MaxPWM; // this is to set at max speed Tracer.WriteError("More than 1 Fans failed"); // Denote that this is a fan failure in chassis ChassisState.FanFailure = true; } else { // All fans are working fine - check rear attention LED and if on, turn it off (by setting fanFailure to false) ChassisState.FanFailure = false; } // Do altitude correction maxFanRequest = (byte)((1 + ConfigLoaded.AltitudeCorrectionFactor * (int)(ConfigLoaded.Altitude / 1000)) * maxFanRequest); // Bound fan request to the maximum possible if (maxFanRequest > MaxPWM) { maxFanRequest = MaxPWM; } // Enable Ramp Down in smaller steps if (PrevFanPWM >= maxFanRequest + 2 * ConfigLoaded.StepPWM) { maxFanRequest = (byte)(PrevFanPWM - ConfigLoaded.StepPWM); } // Set fan speed for all fans - setting one fan device is enough, since setfanspeed is for all fan devices byte status = ChassisState.Fans[0].SetFanSpeed(maxFanRequest); // Trace the speed of fan Tracer.WriteInfo("Fan speed = " + ChassisState.Fans[0].GetFanSpeed()); if (status != (byte)CompletionCode.Success) { Tracer.WriteWarning("SetFanSpeed failed with Completion Code: {0:X}", status); } else { Tracer.WriteInfo("Fan Speed set to {0}", maxFanRequest); } // Store current fan PWM in PrevFanPWM for next iteration PrevFanPWM = maxFanRequest; }