diff --git a/servicereportpkg/repair/plugins/spyre_repair.py b/servicereportpkg/repair/plugins/spyre_repair.py index cbc4746..03360db 100644 --- a/servicereportpkg/repair/plugins/spyre_repair.py +++ b/servicereportpkg/repair/plugins/spyre_repair.py @@ -46,10 +46,26 @@ def fix_vfio_drive_config(self, plugin_obj, vfio_drive_config_check): def fix_user_mem_conf(self, plugin_obj, user_mem_conf_check): """Fix memory configuration usergroup""" + updated_lines = [] for config, val in user_mem_conf_check.get_config_attributes().items(): if not val["status"]: - append_to_file(user_mem_conf_check.get_file_path(), - "\n"+config) + config_match = re.sub(r'\s(\d+|unlimited)$', '', config) + try: + with open(user_mem_conf_check.get_file_path(), "r", encoding="utf-8") as file: + lines = file.readlines() + for line in lines: + # if a user mem config rule is redundant incorrect or old rule will be + # removed + if line.strip() and config_match not in line: + updated_lines.append(line) + + except FileNotFoundError: + self.log.error("File not found : %s", user_mem_conf_check.get_file_path()) + + updated_lines.append("\n"+config) + updated_string = "".join(updated_lines) + add_to_file(user_mem_conf_check.get_file_path(), + updated_string) re_check = plugin_obj.check_memlock_conf() if re_check.get_status(): diff --git a/servicereportpkg/validate/plugins/spyre.py b/servicereportpkg/validate/plugins/spyre.py index b4bc16c..a658350 100644 --- a/servicereportpkg/validate/plugins/spyre.py +++ b/servicereportpkg/validate/plugins/spyre.py @@ -59,6 +59,30 @@ def is_applicable(cls): return Spyre.is_spyre_card_exists() + @classmethod + def get_number_of_spyre_cards(cls): + """Returns number of spyre cards in the device""" + + number_of_cards = 0 + context = pyudev.Context() + # IBM vendor ID + spyre_vendor_ids = ["0x1014"] + # Spyre device IDs + spyre_device_ids = ["0x06a7", "0x06a8"] + + for device in context.list_devices(subsystem='pci'): + vendor_id = device.attributes.get("vendor").decode("utf-8").strip() + if vendor_id not in spyre_vendor_ids: + continue + + device_id = device.attributes.get("device").decode("utf-8").strip() + if device_id not in spyre_device_ids: + continue + + number_of_cards+=1 + + return number_of_cards + def check_driver_config(self): """VFIO Driver configuration""" @@ -136,10 +160,37 @@ def check_udev_rule(self): conf_check.set_status(status) return conf_check + def verify_if_memlimit_config_is_valid(self, conf_check, + line, vfio_mem_conf): + """Verify if memlimit config rule valid""" + + # Patterns to parse sentient 1234, memlock ulimited, + # memlock 7890, sentient memlock unlimited + pattern = r'^(.+?)\s+(unlimited|\d+)$' + for conf in vfio_mem_conf[:]: + if line == conf: + conf_check.add_attribute(line, True, None, None) + vfio_mem_conf.remove(conf) + continue + line_match = re.match(pattern, line) + conf_match = re.match(pattern, conf) + if line_match and conf_match: + line_str = line_match.group(1) + line_value = line_match.group(2) + conf_str = conf_match.group(1) + conf_value = conf_match.group(2) + if line_str == conf_str: + if (line_value == "unlimited" + or (int(line_value) >= int(conf_value))): + conf_check.add_attribute(line, True, None, None) + vfio_mem_conf.remove(conf) + def check_memlock_conf(self): """User memlock configuration""" - vfio_mem_conf = ["@sentient - memlock 134217728"] + num_cards = Spyre.get_number_of_spyre_cards() + memlimit = num_cards * 134234112 + vfio_mem_conf = [f"@sentient - memlock {memlimit}"] config_file = "/etc/security/limits.d/memlock.conf" conf_check = ConfigurationFileCheck(self.check_memlock_conf.__doc__, @@ -150,9 +201,13 @@ def check_memlock_conf(self): with open(config_file, "r", encoding="utf-8") as file: for line in file: line = line.strip() - if line in vfio_mem_conf: - conf_check.add_attribute(line, True, None, None) - vfio_mem_conf.remove(line) + if not line: + continue + # parses the vfio mem config and exiting config and + # validates the vfio mem config and the memlimit value + # against existing config. + self.verify_if_memlimit_config_is_valid(conf_check, + line, vfio_mem_conf) except FileNotFoundError: self.log.error("File not found : %s", config_file)