def sensor_valid_check(board, sname, check_name, attribute): try: if attribute['type'] == "power_status": with open("/sys/class/gpio/gpio"+fru_map[board]['ready']+"/value", "r") as f: bic_ready = f.read(1) if bic_ready[0] == "1": return 0 cmd = "/usr/local/bin/power-util %s status" % board data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() result=data.split(": ") if match(r'ON', result[1]) != None: if match(r'soc_dimm', sname) != None: # check DIMM present with open("/mnt/data/kv_store/sys_config/"+fru_map[board]['name']+loc_map[sname[8:10]], "rb") as f: dimm_sts = f.read(1) if dimm_sts[0] == 0x3f: return 0 return 1 else: return 0 else: Logger.debug("Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return -1
def sensor_valid_check(board, sname, check_name, attribute): status = c_uint8(0) try: if attribute["type"] == "power_status": lpal_hndl.pal_get_server_power(int(fru_map[board]["slot_num"]), byref(status)) if (status.value == 1): if match(r"soc_cpu", sname) is not None: return 1 elif match(r"soc_therm", sname) is not None: return 1 elif match(r"soc_dimm", sname) is not None: # check DIMM present file = "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + part_name_map[sname[8]] with open(file, "r") as f: dimm_sts = f.readline() if re.search(r"([a-zA-Z0-9])", dimm_sts): return 1 else: return 0 else: return 0 return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return 0
def sensor_valid_check(board, sname, check_name, attribute): try: if attribute["type"] == "power_status": with open( "/sys/class/gpio/gpio" + fru_map[board]["gpio"] + "/value", "r") as f: pwr_sts = f.read(1) if pwr_sts[0] == "1": if match(r"soc_dimm", sname) != None: # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + loc_map[sname[8:10]], "rb", ) as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 return 1 else: return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return -1
def write(self, value): """ Writes to write_source using echo to sysfs location echo #value > sysfs_path Arguments: value: value to be set to the sensor Return: N/A """ if self.write_source is None: return cmd = ("echo " + str(value * self.max_duty_register / 100) + " > " + self.write_source) Logger.debug("Setting value using cmd=%s" % cmd) response = "" try: response = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() except SystemExit: Logger.debug("SystemExit from sensor write") raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, response))
def read(self, **kwargs): ''' Reads all sensors values from sysfs source and return data read. There are two kinds of sensors temperature and fans. Arguments: kwargs: set of aruments needed to read from sysfs Return: blob of data read from sysfs ''' cmd = 'cat ' + self.read_source Logger.debug("Reading data with cmd=%s" % cmd) data = '' try: proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) data = proc.stdout.read() err = proc.stderr.read() if err: self.read_source_fail_counter += 1 else: self.read_source_fail_counter = 0 except SystemExit: Logger.debug("SystemExit from sensor read") self.read_source_fail_counter += 1 raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, data)) self.read_source_fail_counter += 1 return data
def sensor_valid_check(board, sname, check_name, attribute): cmd = "" data = "" try: if attribute["type"] == "power_status": return bmc_read_power() elif attribute["type"] == "gpio": cmd = ["gpiocli", "get-value", "--shadow", attribute["shadow"]] data = check_output(cmd).decode().split("=") if int(data[1]) == 0: return 1 else: return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception as err: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s, err=%s" % (board, sname, cmd, data, err)) return 0
def write(self, value): ''' Writes to write_source using util. Arguments: value: value to be set to the sensor Return: N/A ''' if self.write_source is None: return cmd = self.write_source % (int(value)) Logger.debug("Setting value using cmd=%s" % cmd) response = '' try: response = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if response.find("Error") != -1: raise Exception("Write failed with response=%s" % response) except SystemExit: Logger.debug("SystemExit from sensor write") raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, response))
def read(self, **kwargs): ''' Reads all sensors values from the util and return data read. There are two kinds of sensors temperature and fans. Following are the util usages: sensor util: 'util <fru name>' Reads all sensors from a specific fru 'util <fru name> <sensor number>' Reads sensor from a specific fru number fan util: 'util' Reads all fan speeds Arguments: kwargs: set of aruments needed to read from any of the util Return: blob of data read from util ''' cmd = self.read_source if 'fru' in kwargs: if 'num' in kwargs and len(kwargs['num']): cmd = '' for num in kwargs['num']: cmd += self.read_source + " " + kwargs[ 'fru'] + " " + num + ";" else: cmd = cmd + " " + kwargs['fru'] Logger.debug("Reading data with cmd=%s" % cmd) data = '' try: data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, data)) return data
def sensor_valid_check(board, sname, check_name, attribute): cmd = '' data = '' try: if attribute['type'] == "power_BIC_status": cmd = "/usr/local/bin/power-util %s status" % attribute['fru'] data = '' data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() result = data.split(": ") if match(r'ON', result[1]) != None: cmd = "cat /sys/class/gpio/gpio%s/value" % attribute['number'] data = '' data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if int(data) == 0: return 1 else: return 0 else: return 0 elif attribute['type'] == "gpio_power_nvme": cmd = "cat /sys/class/gpio/gpio%s/value" % attribute['number'] data = '' data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if int(data) == 0: cmd = "/usr/local/bin/power-util %s status" % attribute['fru'] data = '' data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() result = data.split(": ") if match(r'ON', result[1]) != None: cmd = "/tmp/cache_store/M2_%s_NVMe" % attribute['nvme'] data = '' if os.path.isfile(cmd) == True: data = open(cmd, "r") if data.read() == "1": return 1 else: return 0 else: return 0 else: return 0 else: return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s" % (board, sname, cmd, data)) return 0
def sensor_valid_check(board, sname, check_name, attribute): status = c_uint8(0) is_valid_check = False try: if attribute["type"] == "power_status": lpal_hndl.pal_get_server_power(int(fru_map[board]["slot_num"]), byref(status)) if (status.value == 1): # power on if match(r"soc_cpu|soc_therm", sname) is not None: is_valid_check = True elif match(r"spe_ssd", sname) is not None: # get SSD present status cmd = '/usr/bin/bic-util slot1 0xe0 0x2 0x9c 0x9c 0x0 0x15 0xe0 0x34 0x9c 0x9c 0x0 0x0 0x3' response = Popen(cmd, shell=True, stdout=PIPE).stdout.read() response = response.decode() # check the completion code if response.split(' ')[6] != '00': return 0 prsnt_bits = response.split(' ')[-3] int_val = int('0x' + prsnt_bits, 16) ssd_id = int(sname[7]) if int_val & (1 << ssd_id): return 1 else: return 0 else: suffix = "" if match(r"1ou_m2", sname) is not None: # 1ou_m2_a_temp. key is at 7 suffix = m2_1ou_name_map[sname[7]] elif match(r"soc_dimm", sname) is not None: # soc_dimma_temp. key is at 8 suffix = dimm_location_name_map[sname[8]] file = "/mnt/data/kv_store/sys_config/" + fru_map[board][ "name"] + suffix if is_dev_prsnt(file) == True: is_valid_check = True if is_valid_check == True: # Check power status again file = "/tmp/cache_store/" + host_ready_map[board] if not os.path.exists(file): return 0 with open(file, "r") as f: flag_status = f.read() if (flag_status == "1"): return 1 return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return 0
def sensor_valid_check(board, sname, check_name, attribute): cmd = "" data = "" try: if attribute["type"] == "power_BIC_status": cmd = "/usr/local/bin/power-util %s status" % attribute["fru"] data = "" data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() result = data.split(": ") if match(r"ON", result[1]) is not None: cmd = "cat /sys/class/gpio/gpio%s/value" % attribute["number"] data = "" data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if int(data) == 0: return 1 else: return 0 else: return 0 elif attribute["type"] == "gpio_power_nvme": cmd = "cat /sys/class/gpio/gpio%s/value" % attribute["number"] data = "" data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if int(data) == 0: cmd = "/usr/local/bin/power-util %s status" % attribute["fru"] data = "" data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() result = data.split(": ") if match(r"ON", result[1]) is not None: key = "M2_%s_NVMe" % attribute["nvme"] try: return int(kv_get(key)) except Exception: return 0 else: return 0 else: return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s" % (board, sname, cmd, data)) return 0
def set_pwm(self, fan, pct): """ Method to set fan pwm Arguments: fan: fan sensor object pct: new pct to set to the specific fan Returns: N/A """ Logger.debug("Set pwm %d to %d" % (int(fan.source.name), pct)) fan.source.write(pct)
def set_all_pwm(self, fans, pct): """ Method to set all fans pwm Arguments: fans: fan sensor objects pct: new pct to set to the specific fan Returns: N/A """ Logger.debug("Set all pwm to %d" % (pct)) for key, _value in list(fans.items()): self.set_pwm(fans[key], pct)
def run(self, value, ctx): value = float(value) self.last_out = ctx["last_pwm"] out = ((self.last_out) + (self.kp * (value - self.valp1)) + (self.ki * (value - self.setpoint)) + (self.kd * (value - 2 * self.valp1 + self.valp2))) self.valp2 = self.valp1 self.valp1 = value Logger.debug( " PID pwm(new:%.2f old:%.2f) pid(%.2f,%.2f,%.2f) setpoint(%.2f) temp(%.2f) " % (out, self.last_out, self.kp, self.ki, self.kd, self.setpoint, value)) self.last_out = out return self.last_out
def read(self, **kwargs): """ Reads all sensors values from the util and return data read. There are two kinds of sensors temperature and fans. Following are the util usages: sensor util: 'util <fru name>' Reads all sensors from a specific fru 'util <fru name> <sensor number>' Reads sensor from a specific fru number fan util: 'util' Reads all fan speeds Arguments: kwargs: set of aruments needed to read from any of the util Return: blob of data read from util """ cmd = self.read_source if "fru" in kwargs: if "inf" in kwargs and kwargs["inf"] is not None: cmd += " " + kwargs["fru"] + " --filter" inf = kwargs["inf"] for name in inf["ext_vars"]: sdata = name.split(":") board = sdata[0] if board != kwargs["fru"]: continue #sname = sdata[1] cmd += " " + sdata[1] elif "num" in kwargs and len(kwargs["num"]): cmd = "" for num in kwargs["num"]: cmd += self.read_source + " " + kwargs[ "fru"] + " " + num + ";" else: cmd = cmd + " " + kwargs["fru"] Logger.debug("Reading data with cmd=%s" % cmd) data = "" try: data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, data)) return data
def sensor_valid_check(board, sname, check_name, attribute): cmd = "" data = "" try: if attribute["type"] == "power_status": # check power status first pwr_sts = bmc_read_power() if pwr_sts != 1: return 0 fru_name = c_char_p(board.encode("utf-8")) snr_name = c_char_p(sname.encode("utf-8")) is_snr_valid = lpal_hndl.pal_sensor_is_valid(fru_name, snr_name) return int(is_snr_valid) elif attribute["type"] == "gpio": cmd = ["gpiocli", "get-value", "--shadow", attribute["shadow"]] data = check_output(cmd).decode().split("=") if int(data[1]) == 0: return 1 else: return 0 elif attribute["type"] == "prsnt": fru_name = c_char_p(board.encode("utf-8")) snr_name = c_char_p(sname.encode("utf-8")) is_snr_valid = lpal_hndl.pal_sensor_is_valid(fru_name, snr_name) return int(is_snr_valid) else: Logger.debug( "Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception as err: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s, err=%s" % (board, sname, cmd, data, err)) return 0
def read_fans(self, fans): """ Method to read all fans speeds Arguments: fans: Set of all sensor fan souces from fsc config Returns: Fan speeds set """ Logger.debug("Read all fan speeds") result = {} for key, value in list(fans.items()): if isinstance(value.source, FscSensorSourceUtil): result[fans[key]] = parse_fan_util(fans[key].source.read()) elif isinstance(fans[key].source, FscSensorSourceSysfs): result[fans[key]] = parse_fan_sysfs(fans[key].source.read()) else: Logger.crit("Unknown source type") return result
def sensor_valid_check(board, sname, check_name, attribute): try: if attribute['type'] == "power_status": with open( "/sys/class/gpio/gpio" + fru_map[board]['pwr_gpio'] + "/value", "r") as f: pwr_sts = f.read(1) if pwr_sts[0] == "1": slot_id = fru_map[board]['slot_num'] is_slot_server = lpal_hndl.pal_is_slot_server(slot_id) if int(is_slot_server) == 1: with open( "/sys/class/gpio/gpio" + fru_map[board]['bic_ready_gpio'] + "/value", "r") as f: bic_sts = f.read(1) if bic_sts[0] == "0": if match(r'soc_dimm', sname) != None: # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]['name'] + loc_map[sname[8:10]], "rb") as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 return 1 else: return 1 return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return 0
def sensor_valid_check(board, sname, check_name, attribute): cmd = "" data = "" if str(board) == "all": sdata = sname.split("_") board = sdata[0] sname = sname.replace(board + "_", "") Logger.debug("board=%s sname=%s" % (board, sname)) try: if attribute["type"] == "power_status": # check power status first pwr_sts = bmc_read_power() if pwr_sts == 1: return 1 return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception as err: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s, err=%s" % (board, sname, cmd, data, err)) return 0
def read_sensors(self, sensor_sources, inf): """ Method to read all sensors Arguments: sensor_sources: Set of all sensor souces from fsc config Returns: SensorValue tuples """ sensors = {} for fru in self.frus: sensors[fru] = get_sensor_tuples(fru, self.nums[fru], sensor_sources, inf) Logger.debug("Last fan speed : %d" % self.last_fan_speed) Logger.debug("Sensor reading") # Offset the sensor Temp value for key, data in list(sensor_sources.items()): sensorname = key.lower() for fru in self.frus: if sensorname in sensors[fru]: senvalue = sensors[fru][sensorname] Logger.debug(" {} = {}".format(sensorname, senvalue.value)) offset = 0 if data.offset != None: offset = data.offset elif data.offset_table != None: # Offset sensor Temp, relate with current fan speed for (fan_speed, offset_temp) in sorted(data.offset_table): if self.last_fan_speed > fan_speed: offset = offset_temp else: break if offset != 0: for fru in self.frus: if sensorname in sensors[fru]: senvalue = sensors[fru][sensorname] value = senvalue.value + offset sensors[fru][sensorname] = senvalue._replace( value=value) value = senvalue.value + offset Logger.debug(" %s = %.2f (after offset %.2f)" % (sensorname, value, offset)) return sensors
def write(self, value): ''' Writes to write_source using echo to sysfs location echo #value > sysfs_path Arguments: value: value to be set to the sensor Return: N/A ''' if self.write_source is None: return cmd = 'echo ' + str(value) + ' > ' + self.write_source Logger.debug("Setting value using cmd=%s" % cmd) response = '' try: response = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() except SystemExit: Logger.debug("SystemExit from sensor write") raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, response))
def sensor_valid_check(board, sname, check_name, attribute): cmd = '' data = '' try: if attribute['type'] == "power_status": #check power status first pwr_sts = bmc_read_power() if pwr_sts != 1: return 0 fru_name = c_char_p(board.encode('utf-8')) snr_name = c_char_p(sname.encode('utf-8')) is_snr_valid = lpal_hndl.pal_sensor_is_valid(fru_name, snr_name) return int(is_snr_valid) elif attribute['type'] == "gpio": cmd = "cat /sys/class/gpio/gpio%s/value" % attribute['number'] data = '' data = Popen(cmd, shell=True, stdout=PIPE).stdout.read().decode() if int(data) == 0: return 1 else: return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return -1 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception as err: Logger.crit( "Exception with board=%s, sensor_name=%s, cmd=%s, response=%s, err=%s" % (board, sname, cmd, data, err)) return 0
def read(self, **kwargs): ''' Reads all sensors values from sysfs source and return data read. There are two kinds of sensors temperature and fans. Arguments: kwargs: set of aruments needed to read from sysfs Return: blob of data read from sysfs ''' # IF read_source has hwmon* then determine what is the hwmon device # and use that for reading readsysfs = self.read_source if "hwmon*" in self.read_source: readsysfs = self.get_hwmon_source() cmd = 'cat ' + readsysfs Logger.debug("Reading data with cmd=%s" % cmd) data = '' try: proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE) data = proc.stdout.read().decode() err = proc.stderr.read().decode() if err: self.read_source_fail_counter += 1 else: self.read_source_fail_counter = 0 except SystemExit: Logger.debug("SystemExit from sensor read") self.read_source_fail_counter += 1 raise except Exception: Logger.crit("Exception with cmd=%s response=%s" % (cmd, data)) self.read_source_fail_counter += 1 return data
def sensor_valid_check(board, sname, check_name, attribute): global fscd_counter global board_for_counter global sname_for_counter if not board_for_counter: board_for_counter = board sname_for_counter = sname if str(board) == str(board_for_counter): if str(sname) == str(sname_for_counter): fscd_counter = lpal_hndl.pal_get_fscd_counter() fscd_counter = fscd_counter+1 lpal_hndl.pal_set_fscd_counter(fscd_counter) if match(r'soc_temp_diode', sname) != None: return rc_stby_sensor_check(board) try: if attribute['type'] == "power_status": with open("/sys/class/gpio/gpio"+fru_map[board]['pwr_gpio']+"/value", "r") as f: pwr_sts = f.read(1) if pwr_sts[0] == "1": slot_id = fru_map[board]['slot_num'] is_slot_server = lpal_hndl.pal_is_slot_support_update(slot_id) if int(is_slot_server) == 1: with open("/sys/class/gpio/gpio"+fru_map[board]['bic_ready_gpio']+"/value", "r") as f: bic_sts = f.read(1) if bic_sts[0] == "0": if match(r'soc_dimm', sname) != None: server_type = lpal_hndl.pal_get_server_type(slot_id) if int(server_type) == 1: #RC Server # check DIMM present with open("/mnt/data/kv_store/sys_config/"+fru_map[board]['name']+loc_map_rc[sname[9:10]], "rb") as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 elif int(server_type) == 2: #EP Server # check DIMM present with open("/mnt/data/kv_store/sys_config/"+fru_map[board]['name']+loc_map_ep[sname[8:9]], "rb") as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 else: #TL Server # check DIMM present with open("/mnt/data/kv_store/sys_config/"+fru_map[board]['name']+loc_map[sname[8:10]], "rb") as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 else: fru_name = c_char_p(board.encode('utf-8')) snr_name = c_char_p(sname.encode('utf-8')) is_m2_prsnt = lpal_hndl.pal_is_m2_prsnt(fru_name, snr_name) return int(is_m2_prsnt) else: if match(r'dc_nvme', sname) != None: #GPv1 fru_name = c_char_p(board.encode('utf-8')) snr_name = c_char_p(sname.encode('utf-8')) is_m2_prsnt = lpal_hndl.pal_is_m2_prsnt(fru_name, snr_name) return int(is_m2_prsnt) return 1 return 0 else: Logger.debug("Sensor corresponding valid check funciton not found!") return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return 0
def run(self, value, ctx): mini = 0 dead_fans = len(ctx["dead_fans"]) if self.table == None: self.table = self.table_normal_up if self.compare_fsc_value == None: self.compare_fsc_value = value self.accelerate = 1 elif value > self.compare_fsc_value: self.accelerate = 1 elif value < self.compare_fsc_value: self.accelerate = 0 if self.accelerate == 1 and dead_fans == 0: self.table = self.table_normal_up elif self.accelerate == 0 and dead_fans == 0: self.table = self.table_normal_down elif self.accelerate == 1 and dead_fans == 1: self.table = self.table_onefail_up elif self.accelerate == 0 and dead_fans == 1: self.table = self.table_onefail_down if self.accelerate: Logger.debug(" accelerate(up) table {0}".format(self.table)) else: Logger.debug(" accelerate(down) table {0}".format(self.table)) if self.last_out is None: self.last_out = sorted(self.table)[0][1] for (in_thr, out) in self.table: mini = out if value >= in_thr: self.compare_fsc_value = value if self.accelerate: # ascending Logger.debug(" LINEAR pwmout max([%.0f,%.0f]) temp(%.2f)" % (out, self.last_out, value)) self.last_out = max([out, self.last_out]) else: # descending Logger.debug(" LINEAR pwmout min[(%.0f,%.0f]) temp(%.2f)" % (out, self.last_out, value)) self.last_out = min([out, self.last_out]) return self.last_out self.compare_fsc_value = value if self.accelerate: # ascending Logger.debug(" LINEAR pwmout max([%.0f,%.0f]) temp(%.2f)" % (mini, self.last_out, value)) self.last_out = max([mini, self.last_out]) else: # descending Logger.debug(" LINEAR pwmout min([%.0f,%.0f]) temp(%.2f)" % (mini, self.last_out, value)) self.last_out = min([mini, self.last_out]) return self.last_out
def update_zones(self, dead_fans, time_difference): """ TODO: Need to change logic here. # Platforms with chassis_intrusion mode enabled if chassis_intrusion: set the chassis_intrusion_boost_flag to 0 and then do necessary checks to set flag to 1 if chassis_intrusion_boost_flag: run boost mode else: run normal mode else # Platforms WITHOUT chassis_intrusion mode run normal mode # Platforms with enable_fsc_sensor_check mode enabled if enable_fsc_sensor_check: set the sensor_violated_flag to 0 and then do necessary checks to set flag to 1 if sensor_violated_flag: run boost mode else: run normal mode else # Platforms WITHOUT enable_fsc_sensor_check mode run normal mode """ ctx = {} if not self.sensor_filter_all: sensors_tuples = self.machine.read_sensors(self.sensors, None) self.fsc_safe_guards(sensors_tuples) for zone in self.zones: if self.sensor_filter_all: sensors_tuples = self.machine.read_sensors( self.sensors, zone.expr_meta) self.fsc_safe_guards(sensors_tuples) Logger.info("PWM: %s" % (json.dumps(zone.pwm_output))) mode = 0 chassis_intrusion_boost_flag = 0 sensor_violated_flag = 0 if self.chassis_intrusion: self_tray_pull_out = board_callout(callout="chassis_intrusion") if self_tray_pull_out == 1: chassis_intrusion_boost_flag = 1 if self.enable_fsc_sensor_check: Logger.info("enable_fsc_sensor_check") if self.fsc_sensor_check(sensors_tuples) != 0: sensor_violated_flag = 1 Logger.debug(" dead_fans(%d) " % len(dead_fans)) Logger.debug("Calculate") if chassis_intrusion_boost_flag == 0 and sensor_violated_flag == 0: ctx["dt"] = time_difference ctx["dead_fans"] = dead_fans ctx["last_pwm"] = zone.last_pwm ignore_fan_mode = False if self.non_fanfail_limited_boost and dead_fans: ignore_fan_mode = True pwmval = zone.run(sensors=sensors_tuples, ctx=ctx, ignore_mode=ignore_fan_mode) mode = zone.get_set_fan_mode(mode, action="read") # if we set pwm_sensor_boost_value option, assign it to pwmval if self.pwm_sensor_boost_value != None and \ int(mode) == fan_mode["boost_mode"]: if pwmval == self.boost: pwmval = self.pwm_sensor_boost_value else: pwmval = self.boost mode = fan_mode["boost_mode"] if self.fan_fail: boost_record_path = RECORD_DIR + "fan_fail_boost" if self.boost_type == "progressive" and self.fan_dead_boost: # Cases where we want to progressively bump PWMs dead = len(dead_fans) if dead > 0: Logger.info( "Progressive mode: Failed fans: %s" % (", ".join([str(i.label) for i in dead_fans]))) for fan_count, rate in self.fan_dead_boost["data"]: if dead <= fan_count: pwmval = clamp(pwmval + (dead * rate), 0, 100) mode = fan_mode["normal_mode"] if os.path.isfile(boost_record_path): os.remove(boost_record_path) break else: pwmval = self.boost mode = fan_mode["boost_mode"] if not os.path.isfile(boost_record_path): fan_fail_boost_record = open( boost_record_path, "w") fan_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) else: if dead_fans: # If not progressive ,when there is 1 fan failed, boost all fans Logger.info( "Failed fans: %s" % (", ".join([str(i.label) for i in dead_fans]))) # choose the higher PWM if self.output_max_boost_pwm: pwmval = self.boost if pwmval < self.boost else pwmval else: pwmval = self.boost mode = fan_mode["boost_mode"] if not os.path.isfile(boost_record_path): fan_fail_boost_record = open( boost_record_path, "w") fan_fail_boost_record.close() else: if os.path.isfile(boost_record_path): os.remove(boost_record_path) if self.fan_dead_boost: # If all the fans failed take action after a few cycles if len(dead_fans) == len(self.fans): self.all_fan_fail_counter = self.all_fan_fail_counter + 1 Logger.warn( "Currently all fans failed for {} cycles". format(self.all_fan_fail_counter)) if (self.fan_dead_boost["threshold"] and self.fan_dead_boost["action"]): if (self.all_fan_fail_counter >= self.fan_dead_boost["threshold"]): self.fsc_host_action( action=self.fan_dead_boost["action"], cause="All fans are bad for more than " + str(self.fan_dead_boost["threshold"]) + " cycles", ) else: # If atleast 1 fan is working reset the counter self.all_fan_fail_counter = 0 if self.fan_limit_upper_pwm: if pwmval > self.fan_limit_upper_pwm: pwmval = self.fan_limit_upper_pwm if self.fan_limit_lower_pwm: if pwmval < self.fan_limit_lower_pwm: pwmval = self.fan_limit_lower_pwm # if no fan fail, the max of pwm is non_fanfail_limited_boost pwm: if self.non_fanfail_limited_boost and not dead_fans: pwmval = clamp(pwmval, 0, self.non_fanfail_limited_boost) if abs(zone.last_pwm - pwmval) > self.ramp_rate: if pwmval < zone.last_pwm: pwmval = zone.last_pwm - self.ramp_rate else: pwmval = zone.last_pwm + self.ramp_rate zone.last_pwm = pwmval if hasattr(zone.pwm_output, "__iter__"): for output in zone.pwm_output: self.machine.set_pwm(self.fans.get(str(output)), pwmval) else: self.machine.set_pwm(self.fans[zone.pwm_output], pwmval) zone.get_set_fan_mode(mode, action="write")
def sensor_valid_check(board, sname, check_name, attribute): global fscd_counter global board_for_counter global sname_for_counter if not board_for_counter: board_for_counter = board sname_for_counter = sname if str(board) == str(board_for_counter): if str(sname) == str(sname_for_counter): fscd_counter = lpal_hndl.pal_get_fscd_counter() fscd_counter = fscd_counter + 1 lpal_hndl.pal_set_fscd_counter(fscd_counter) if str(board) == "all": sdata = sname.split("_") board = sdata[0] sname = sname.replace(board + "_", "") Logger.debug("board=%s sname=%s" % (board, sname)) if match(r"soc_temp_diode", sname) is not None: return rc_stby_sensor_check(board) try: if attribute["type"] == "power_status": with open(gpio_path + fru_map[board]["pwr_gpio"] + "/value", "r") as f: pwr_sts = f.read(1) if pwr_sts[0] == "1": slot_id = fru_map[board]["slot_num"] is_slot_server = lpal_hndl.pal_is_slot_support_update(slot_id) if int(is_slot_server) == 1: with open( gpio_path + fru_map[board]["bic_ready_gpio"] + "/value", "r", ) as f: bic_sts = f.read(1) if bic_sts[0] == "0": if match(r"soc_dimm", sname) is not None: server_type = lpal_hndl.pal_get_server_type( slot_id) if int(server_type) == 1: # RC Server # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + loc_map_rc[sname[9:10]], "rb", ) as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 elif int(server_type) == 2: # EP Server # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + loc_map_ep[sname[8:9]], "rb", ) as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 elif int(server_type) == 4: # ND Server # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + loc_map_nd[sname[8:9]], "rb", ) as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 else: # TL Server # check DIMM present with open( "/mnt/data/kv_store/sys_config/" + fru_map[board]["name"] + loc_map[sname[8:10]], "rb", ) as f: dimm_sts = f.read(1) if dimm_sts[0] != 1: return 0 else: return 1 else: fru_name = c_char_p(board.encode("utf-8")) snr_name = c_char_p(sname.encode("utf-8")) is_m2_prsnt = lpal_hndl.pal_is_m2_prsnt( fru_name, snr_name) return int(is_m2_prsnt) else: if match(r"dc_nvme", sname) is not None: # GPv1 fru_name = c_char_p(board.encode("utf-8")) snr_name = c_char_p(sname.encode("utf-8")) is_m2_prsnt = lpal_hndl.pal_is_m2_prsnt( fru_name, snr_name) return int(is_m2_prsnt) return 1 return 0 else: Logger.debug( "Sensor corresponding valid check funciton not found!") return 0 except SystemExit: Logger.debug("SystemExit from sensor read") raise except Exception: Logger.warn("Exception with board=%s, sensor_name=%s" % (board, sname)) return 0
def run(self, sensors, dt): ctx = {'dt': dt} outmin = 0 fail_ssd_count = 0 missing = set() for v in self.expr_meta['ext_vars']: board, sname = v.split(":") if sname in sensors[board]: sensor = sensors[board][sname] ctx[v] = sensor.value if sensor.status in ['ucr']: Logger.warn('Sensor %s reporting status %s' % (sensor.name, sensor.status)) outmin = self.transitional if self.fail_sensor_type != None: if 'standby_sensor_fail' in self.fail_sensor_type.keys(): if self.fail_sensor_type[ 'standby_sensor_fail'] == True: if sensor.status in ['na']: if re.match(r'SOC', sensor.name) != None: if 'server_sensor_fail' in self.fail_sensor_type.keys( ): if self.fail_sensor_type[ 'server_sensor_fail'] == True: ret = fsc_board.get_power_status( board) if ret: Logger.debug( "Server Sensor Fail") outmin = self.boost break elif re.match(r'SSD', sensor.name) != None: if 'SSD_sensor_fail' in self.fail_sensor_type.keys( ): if self.fail_sensor_type[ 'SSD_sensor_fail'] == True: fail_ssd_count = fail_ssd_count + 1 else: Logger.debug("Standby Sensor Fail") outmin = self.boost break else: missing.add(v) # evaluation tries to ignore the effects of None values # (e.g. acts as 0 in max/+) ctx[v] = None if missing: Logger.warn('Missing sensors: %s' % (', '.join(missing), )) if verbose: (exprout, dxstr) = self.expr.dbgeval(ctx) Logger.info(dxstr + " = " + str(exprout)) else: exprout = self.expr.eval(ctx) Logger.info(self.expr_str + " = " + str(exprout)) # If *all* sensors in the top level max() report None, the # expression will report None if not exprout: if not self.transitional_assert_flag: Logger.crit('ASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) exprout = self.transitional self.transitional_assert_flag = True else: if self.transitional_assert_flag: Logger.crit('DEASSERT: Zone%d No sane fan speed could be \ calculated! Using transitional speed.' % (self.counter)) self.transitional_assert_flag = False if self.fail_sensor_type != None: if 'SSD_sensor_fail' in self.fail_sensor_type.keys(): if self.fail_sensor_type['SSD_sensor_fail'] == True: if fail_ssd_count != 0: if self.ssd_progressive_algorithm != None: if 'offset_algorithm' in self.ssd_progressive_algorithm.keys( ): list_index = 0 for i in self.ssd_progressive_algorithm[ 'offset_algorithm']: list_index = list_index + 1 if fail_ssd_count <= i[0]: exprout = exprout + i[1] break else: if list_index == len( self.ssd_progressive_algorithm[ 'offset_algorithm']): outmin = self.boost if exprout < outmin: exprout = outmin exprout = clamp(exprout, 0, 100) return exprout