def precheck(self): # Check if parameters are valid # bridge exists? if self.__network_mode == "bridge": if self.__bridge_name is None: if "br0" not in helper.get_all_interfaces(): raise ArgsNotCorrect( "[CNetwork] ERROR: network_name(br0) does not exist") else: if self.__bridge_name not in helper.get_all_interfaces(): raise ArgsNotCorrect( "[CNetwork] ERROR: network_name({}) does not exist". format(self.__bridge_name)) if "mac" not in self.__network: raise ArgsNotCorrect( "[CNetwork] ERROR: mac address is not specified for " "target network:\n{}".format( json.dumps(self.__network, indent=4))) else: list_addr = self.__mac_address.split(":") if len(list_addr) != 6: raise ArgsNotCorrect( "[CNetwork] ERROR: mac address invalid: {}".format( self.__mac_address)) for each_addr in list_addr: try: int(each_addr, 16) except Exception: raise ArgsNotCorrect( "[CNetwork] ERROR: mac address invalid: {}".format( self.__mac_address))
def init(self): self.__host_bdf = self.__pci_dev_info.get("host") self.__bus = self.__pci_dev_info.get("bus") self.__addr = self.__pci_dev_info.get("addr") self.__multifunction = self.__pci_dev_info.get("multifunction") if self.__host_bdf is None: raise ArgsNotCorrect("host should be set.") self.__target_driver = self.__pci_dev_info.get("driver", "vfio-pci") if self.__target_driver not in ["vfio-pci", "pci-stub"]: raise ArgsNotCorrect("{} not supported".format( self.__target_driver)) if self.__target_driver == "vfio-pci": os.system("modprobe vfio-pci") else: os.system("modprobe pci-stub") if not re.search(r'\d{4}:[0-9a-fA-F]{2}:\d{2}\.\d+$', self.__host_bdf): raise ArgsNotCorrect("BDF should be Domain:Bus:Device.Function") target_dev_sysfs_path = "/sys/bus/pci/devices/{}".format( self.__host_bdf) if not os.path.exists(target_dev_sysfs_path): raise InfraSimError("No such device {}".format(self.__host_bdf)) if not os.path.exists(os.path.join(target_dev_sysfs_path, "iommu")): raise InfraSimError( "No IOMMU found. Check your hardware and/or linux parameters, use intel_iommu=on" ) self.__get_dev_sysfs_path_in_iommu_group(self.__host_bdf) self.bind()
def precheck(self): if not self.__backend_type: raise ArgsNotCorrect("[Chardev] Backend of chardev should be set.") if self.__host and not helper.is_valid_ip(self.__host): raise ArgsNotCorrect("[CharDev] Invalid chardev host: {}".format( self.__host)) if self.__port: try: int(self.__port) except ValueError: raise ArgsNotCorrect( "[Chardev] Port is not a valid integer: {}".format( self.__port)) if helper.check_if_port_in_use("0.0.0.0", self.__port): raise ArgsNotCorrect( "[Chardev] Port {} is already in use".format(self.__port)) if self.__path: dir_path = os.path.dirname(self.__path) if not os.path.isdir(dir_path): raise ArgsNotCorrect( "[Chardev] Path folder doesn't exist: {}".format(dir_path))
def precheck(self): if self.__page_file and not os.path.exists(self.__page_file): raise ArgsNotCorrect( "[CBaseDrive] page file {0} doesnot exist".format( self.__page_file)) if self.__share_rw != "true" and self.__share_rw != "false": raise ArgsNotCorrect( "[CBaseDrive] share-rw: {} is not a valid option [true/false]". format(self.__share_rw)) if self.__sector_size not in [None, 512, 520, 4160]: raise ArgsNotCorrect( "[CBaseDrive] sector_size only support 512, 520, 4160") if self.__sector_size in [520, 4160] and self.__format != "raw": raise ArgsNotCorrect( "[CBaseDrive] sector_size {} is only supported 'raw' format". format(self.__sector_size)) if os.path.exists(self._drive_info.get( "file", "")) and self._drive_info.get("size"): cmd = "qemu-img info {} --output json".format( self._drive_info.get("file")) img_size = json.loads(run_command(cmd)[1])["virtual-size"] if img_size != math.ceil( self._drive_info.get("size") * 1024 * 1024 * 1024 / 512) * 512: print "\033[93mWarning: Existing drive image size {}GB is " \ "different from the size {}GB defined in yaml.\033[0m" \ .format((img_size >> 30), self._drive_info.get("size")) self.logger.warning( "Existing drive image size %dGB is different from the size %dGB defined in yaml.", (img_size >> 30), math.ceil(self._drive_info.get("size")))
def __process_ntb_device(self): # get pair of node name and ntb info. ntb_maps = [] for node in self.__chassis.get("nodes", []): n = node["compute"].get("ntb") if n: ntb_maps.append({"name": node["name"], "ntb": n}) # update node name of peer ntb. for item in ntb_maps: peer_idx = item["ntb"].get("peer_id") if peer_idx is None: raise ArgsNotCorrect( "Peer id of ntb ({}) can't be None".format( item["ntb"]["id"])) peer_name = filter(lambda x: x["ntb"]["id"] == peer_idx, ntb_maps) if len(peer_name) != 1: raise ArgsNotCorrect( "Peer id of ntb ({}) is not valid".format(peer_idx)) item["peer_node"] = peer_name[0] # build cross link of ntb devices. for item in ntb_maps: ntb_info = item["ntb"] # set local unix socket name for rx: infrasim_home/<name>/<ntb_id> ntb_info["local"] = ntb_info.get( "local", os.path.join(config.infrasim_home, item["name"], ntb_info.get("id"))) # combine the peer unix socket name for tx: infrasim_home/<peer_name>/<peer_ntb_id> ntb_info["peer_rx"] = ntb_info.get( "peer_rx", os.path.join(config.infrasim_home, item["peer_node"]["name"], item["peer_node"]["ntb"]["id"]))
def add_connector(port): # get the full name of expander full_name = "" if port.get("atta_enclosure"): full_name = "{}_".format(port["atta_enclosure"]) full_name = "{}{}".format(full_name, port["atta_exp"]) # find the expander exp = find(lambda exp: exp["name"] == full_name, self._expanders) if exp is None: raise ArgsNotCorrect("No expander named {}".format(full_name)) # find the specified port exp_port = find(lambda p: p["id"] == port["atta_port"], exp["ports"]) if exp_port is None: raise ArgsNotCorrect("No expander port {1} in {0} ".format( full_name, port["atta_port"])) # get the phy id of found port local_phy = exp_port["phy"] self.__append_link( exp, local_phy, self.__get_link(local_phy, exp_port["number"], port["wwn"], port["phy"], _Const.HBA_DEVICE)) port["atta_wwn"] = exp["wwn"] port["atta_phy"] = local_phy port["phy_number"] = exp_port["number"]
def __check_peer_bmc_info(self): if self.__peer_bmc_info_list: for pbi in self.__peer_bmc_info_list: addr = pbi.get("addr") if addr is None or (addr & 0x1) or addr >= 0xff: raise ArgsNotCorrect( "[BMC] {} is not a valid I2C address.".format(addr)) interface = pbi.get("interface") if interface is None or (interface != "lan" and interface != "lanplus"): raise ArgsNotCorrect( "[BMC] {} should be 'lan' or 'lanplus'.".format( interface)) if pbi.get("user") is None: raise ArgsNotCorrect("[BMC] user name is required.") if pbi.get("password") is None: raise ArgsNotCorrect("[BMC] password is required.") host_ip = pbi.get("host") try: socket.inet_aton(host_ip) except socket.error as e: raise ArgsNotCorrect("[BMC] {} is not valid.({})".format( host_ip, e))
def __create_controller(self, controller_info): controller_obj = None model = controller_info.get("type", "ahci") if model.startswith("megasas"): controller_obj = MegaSASController(controller_info) elif model.startswith("lsi"): controller_obj = LSISASController(controller_info) elif model.startswith("pmc"): controller_obj = PMCSASController(controller_info) elif "nvme" in model: controller_obj = NVMeController(controller_info) elif "ahci" in model: controller_obj = AHCIController(controller_info, self.__is_cdrom_connected) elif "disk_array" in model: if self.__diskarray: raise ArgsNotCorrect( "[BackendStorage] Only 1 disk array object allowed") controller_obj = DiskArrayController(controller_info) self.__diskarray = controller_obj else: raise ArgsNotCorrect( "[BackendStorage] Unsupported controller type: {}".format( model)) controller_obj.logger = self.logger # set owner controller_obj.owner = self return controller_obj
def add_connector(port): # get the full name of expander # check empty port. if port.get("connected") is False: port["atta_wwn"] = 0 port["atta_phy"] = 0 port["phy_number"] = port.get("phy_number", 4) return full_name = "" if port.get("atta_enclosure"): full_name = "{}_".format(port["atta_enclosure"]) full_name = "{}{}".format(full_name, port["atta_exp"]) # find the expander exp = find(lambda exp: exp["name"] == full_name, self._expanders) if exp is None: raise ArgsNotCorrect("No expander named {}".format(full_name)) # find the specified port exp_port = find(lambda p: p["id"] == port["atta_port"], exp["ports"]) if exp_port is None: raise ArgsNotCorrect("No expander port {1} in {0} ".format( full_name, port["atta_port"])) # get the phy id of found port local_phy = exp_port["phy"] self.__update_link(exp, local_phy, exp_port["number"], atta_type=_Const.HBA_DEVICE, atta_phy=port["phy"], atta_wwn=port["wwn"]) port["atta_wwn"] = exp["wwn"] port["atta_phy"] = local_phy port["phy_number"] = exp_port["number"]
def precheck(self): if self.__page_file and not os.path.exists(self.__page_file): raise ArgsNotCorrect( "[CBaseDrive] page file {0} doesnot exist".format( self.__page_file)) if not isinstance(self.__share_rw, bool): raise ArgsNotCorrect( "[CBaseDrive] share-rw is not boolean: {}".format( self.__share_rw))
def precheck(self): if self.__imc_info.get("bus") is None: raise ArgsNotCorrect("imc bus is mandatory!") if self.__imc_info.get("id",) is None: raise ArgsNotCorrect("imc id is mandatory!") addr = self.__imc_info.get("addr",) if ((addr) != "08.0") and ((addr) != "09.0"): raise ArgsNotCorrect("imc address must be 08.0 or 09.0")
def precheck(self): if not self.__ip: raise ArgsNotCorrect( "[Racadm] Specified racadm interface {} doesn\'t exist".format( self.__interface)) if helper.check_if_port_in_use(self.__ip, self.__port_idrac): raise ArgsNotCorrect( "[Racadm] Racadm port {}:{} is already in use.".format( self.__ip, self.__port_idrac))
def precheck(self): if self.__page_file and not os.path.exists(self.__page_file): raise ArgsNotCorrect( "[CBaseDrive] page file {0} doesnot exist".format( self.__page_file)) if self.__share_rw != "true" and self.__share_rw != "false": raise ArgsNotCorrect( "[CBaseDrive] share-rw: {} is not a valid option [true/false]". format(self.__share_rw))
def precheck(self): if not helper.is_valid_ip(self.__ip): self.logger.exception("[Monitor] Invalid IP: {} of interface: {}". format(self.__ip, self.__interface)) raise ArgsNotCorrect("Invalid IP: {} of interface: {}".format( self.__ip, self.__interface)) if helper.check_if_port_in_use(self.__ip, self.__port): self.logger.exception("[Monitor] Monitor port {}:{} is already in use.". format(self.__ip, self.__port)) raise ArgsNotCorrect("Monitor port {}:{} is already in use.". format(self.__ip, self.__port))
def precheck(self): if self.__pcu_info.get("bus") is None: raise ArgsNotCorrect("pcu's bus is mandatory!") if self.__pcu_info.get("spd_data_file") is None: raise ArgsNotCorrect("pcu's spd_data_file is mandatory!") if self.__pcu_info.get("dimm_slot_topo") is None: raise ArgsNotCorrect("pcu's dimm_slot_topo is mandatory!") if self.__pcu_info.get("attach_cpu_index") is None: raise ArgsNotCorrect("pcu's attach_cpu_index is mandatory!")
def precheck(self): # Since QEMU support CMB size in MB, we recognize 1k, 4k # CMB size as invalid here. if self._cmb_size_mb not in [1, 16, 256, 4096, 65536]: raise ArgsNotCorrect("[NVMe{}] CMB size {} is invalid".format( self.__controller_index, self._cmb_size_mb)) if self.chassis_slot: if self.chassis_slot not in range(0, 25): raise ArgsNotCorrect( "[NVMe{}] chassis_slot {} is invalid".format( self.__controller_index, self.chassis_slot))
def precheck(self): """ Check if the CPU quantities exceeds the real physical CPU cores """ if self.__quantities <= 0: raise ArgsNotCorrect( '[CPU] quantities invalid: {}, should be positive'.format( self.__quantities)) if self.__quantities % self.__socket != 0: raise ArgsNotCorrect( '[CPU] quantities: {} is not divided by socket: {}'.format( self.__quantities, self.__socket))
def precheck(self): if self.__vmd_info.get("id") is None: raise ArgsNotCorrect("VMD's id is mandatory!") if self.__vmd_info.get("bus") is None: raise ArgsNotCorrect("VMD's bus is mandatory!") size = self.__vmd_info.get("bar1_size", 1024) if (size & (size - 1)) != 0: raise ArgsNotCorrect("bar1_size must be pow 2") size = self.__vmd_info.get("bar2_size", 1024) if (size & (size - 1)) != 0: raise ArgsNotCorrect("bar2_size must be pow 2")
def handle_parms(self): if self.__network_mode == "bridge": if self.__bridge_name is None: self.__bridge_name = "br0" qemu_sys_prefix = os.path.dirname( run_command("which qemu-system-x86_64")[1]).replace("bin", "") bridge_helper = os.path.join(qemu_sys_prefix, "libexec", "qemu-bridge-helper") netdev_option = ",".join([ 'bridge', 'id=netdev{}'.format(self.__index), 'br={}'.format(self.__bridge_name), 'helper={}'.format(bridge_helper) ]) elif self.__network_mode == "nat": netdev_option = ",".join( ["user", "id=netdev{}".format(self.__index)]) else: raise ArgsNotCorrect( "[CNetwork] ERROR: Network mode '{}'' is not supported now.". format(self.__network_mode)) for item in self.__port_forwards: netdev_option = ",".join([ "{}".format(netdev_option), "hostfwd={}::{}-:{}".format(item["protocal"], item["outside"], item["inside"]) ]) nic_option = ",".join([ "{}".format(self.__nic_name), "netdev=netdev{}".format(self.__index), "mac={}".format(self.__mac_address) ]) if self.__bus: nic_option = ",".join( ["{}".format(nic_option), "bus={}".format(self.__bus)]) if self.__addr: nic_option = ",".join( ["{}".format(nic_option), "addr={}".format(self.__addr)]) if self.__multifunction: nic_option = ",".join([ "{}".format(nic_option), "multifunction={}".format(self.__multifunction) ]) if self.__model: nic_option = ",".join( ["{}".format(nic_option), "model={}".format(self.__model)]) if self.__id: nic_option = ",".join( ["{}".format(nic_option), "id={}".format(self.__id)]) if self.__extra_options: nic_option = ",".join( ["{}".format(nic_option), self.__extra_options]) network_option = " ".join([ "-netdev {}".format(netdev_option), "-device {}".format(nic_option) ]) self.add_option(network_option)
def check_id(self): id_list = [] for component in self.__component_list: id_list.append(component['id']) if len(id_list) != len(set(id_list)): raise ArgsNotCorrect("PCIE device id duplicated")
def add_storage_backend(self, backend_info): # called in node.init diskarrays = filter(lambda x: x["type"] == "disk_array", backend_info) if len(diskarrays) == 0: return None if len(diskarrays) > 1: raise ArgsNotCorrect( "[Disk Array] Only 1 Disk Array object Allowed") diskarray_controller = diskarrays[0] if diskarray_controller.get("sas_drives", None): # if it is handled by chassis already, clear and quit. self._expanders = [] return if self.__check_duplicated_diskarray(diskarray_controller) is False: diskarray_controller["sas_drives"] = self._sas_all_drv self.__add_diskarray(diskarray_controller) controllers = filter( lambda x: x.get("connectors") or x.get("external_connectors"), backend_info) self._controllers.extend(controllers) for controller in controllers: self.__add_local_resource(controller) return diskarray_controller
def precheck(self): if not self.__port_info: raise ArgsNotCorrect("port device is required.") if not set(['id', 'bus', 'chassis', 'slot']).issubset( self.__port_info): raise ArgsNotCorrect("port \ <id>/<bus>/<chassis>/<slot> are all required.") if 'addr' in self.__port_info: if ('sec_bus' in self.__port_info) ^ ('pri_bus' in self.__port_info): raise ArgsNotCorrect( "<sec_bus> and <pri_bus> should appear together") else: if 'sec_bus' in self.__port_info or 'pri_bus' in self.__port_info: raise ArgsNotCorrect( "<sec_bus> and <pri_bus> should appear with <addr>")
def handle_parms(self): if self.__network_mode == "bridge": if self.__bridge_name is None: self.__bridge_name = "br0" qemu_sys_prefix = os.path.dirname( run_command("which qemu-system-x86_64")[1]).replace("bin", "") bridge_helper = os.path.join(qemu_sys_prefix, "libexec", "qemu-bridge-helper") netdev_option = ",".join([ 'bridge', 'id=netdev{}'.format(self.__index), 'br={}'.format(self.__bridge_name), 'helper={}'.format(bridge_helper) ]) elif self.__network_mode == "nat": netdev_option = ",".join( ["user", "id=netdev{}".format(self.__index)]) else: raise ArgsNotCorrect( "[CNetwork] ERROR: Network mode '{}'' is not supported now.". format(self.__network_mode)) nic_option = ",".join([ "{}".format(self.__nic_name), "netdev=netdev{}".format(self.__index), "mac={}".format(self.__mac_address) ]) network_option = " ".join([ "-netdev {}".format(netdev_option), "-device {}".format(nic_option) ]) self.add_option(network_option)
def __update_link(self, exp, phy, num, atta_phy, atta_type, atta_wwn, atta_name=0, atta_slot_id=0): if atta_name == 0: atta_name = atta_wwn for temp in range(0, num): local_phy = phy + temp if exp["links"][local_phy] is not None: raise ArgsNotCorrect("Exp {} phy {} is not empty. {}".format( exp["name"], local_phy, exp["links"][local_phy])) exp["links"][local_phy] = { "phy": local_phy, "num": num - temp, "atta_wwn": atta_wwn, "atta_type": atta_type, "atta_dev_name": atta_name, "atta_phy": atta_phy + temp, "atta_scsi_id": 0, "atta_slot_id": atta_slot_id }
def precheck(self): # check if socat exists try: code, socat_cmd = run_command("which socat") self.__bin = socat_cmd.strip(os.linesep) except CommandRunFailed: self.logger.exception("[Socat] Can't find file socat") raise CommandNotFound("socat") if not self.__sol_device: raise ArgsNotCorrect("[Socat] No SOL device is defined") if not self.__socket_serial: raise ArgsNotCorrect( "[Socat] No socket file for serial is defined")
def __update_scsi_id(self, controller): """ allocate scsi_id for all devices under this controller """ hba_phys = set(range(controller.get("phy_count", 8))) # update scsi_id of non-direct drv start_scsi_id = 0 # controller.get("phy_count", 8) for port in controller.get("hba_ports", []): phys = set(range(port["phy"], port["phy"] + port["phy_number"])) if not phys <= hba_phys: raise ArgsNotCorrect("HBA {} phy {} conflict".format( port["wwn"], phys)) hba_phys -= phys for exp in port["expanders"]: exp["start_scsi_id"] = start_scsi_id for link in exp["links"]: link["atta_scsi_id"] = start_scsi_id + link["phy"] if link["atta_type"] == _Const.END_DEVICE: drv = find(lambda d: d["port_wwn"] == link["atta_wwn"], exp["drives"]) drv["scsi-id"] = link["atta_scsi_id"] if link["atta_type"] == _Const.SES_DEVICE: ses = exp["ses"] ses["scsi-id"] = link["atta_scsi_id"] start_scsi_id = start_scsi_id + exp["phy_count"] # update scsi_id of direct attached drv direct_drvs = controller.get("drives", []) for drv in direct_drvs: if drv.get("atta_phy"): phy = drv["atta_phy"] if phy not in hba_phys: raise ArgsNotCorrect("wrong atta_phy:{} of drv {}".format( phy, hex(drv["wwn"]))) hba_phys.remove(phy) else: if len(hba_phys) == 0: raise ArgsNotCorrect( "no more free phy of hba for drv {}".format( hex(drv["wwn"]))) phy = hba_phys.pop() drv["atta_phy"] = phy drv["scsi-id"] = phy drv["port_wwn"] = drv["wwn"] + 1 drv["target_wwn"] = drv["wwn"] + 2
def add_slot_map(self, chassis_slot, dev_attrs): if not isinstance(chassis_slot, int) or chassis_slot < 0: return if chassis_slot not in range(0, 25): raise ArgsNotCorrect("[BackendStorage] Unsupported chassis slot: {}". format(chassis_slot)) key = "slot_{}".format(chassis_slot) if key in self.__nvme_map_dict: raise ArgsNotCorrect("[BackendStorage] Chassis slot: {} has been used". format(chassis_slot)) nvme_map_dict = dev_attrs nvme_map_dict["model_number"] = dev_attrs.get("model_number", "").replace("\"", "") nvme_map_dict["drive"] = dev_attrs.get("id", "").replace("dev-", "") nvme_map_dict["power_status"] = "on" self.__nvme_map_dict[key] = nvme_map_dict self.logger.info("Add slot: {} nvme_map_dict: {}". format(chassis_slot, nvme_map_dict))
def precheck(self): if self.__imc_info.get("bus") is None: raise ArgsNotCorrect("imc bus is mandatory!") if self.__imc_info.get("id", ) is None: raise ArgsNotCorrect("imc id is mandatory!") if self.__imc_info.get("imc_slot_topo", ) is None: raise ArgsNotCorrect( "imc_slot_topo is mandatory, bit0-23 means logic dimm slot 0-23" ) if self.__imc_info.get("imc_cpu_index", ) is None: raise ArgsNotCorrect("imc_cpu_index is mandatory!") addr = self.__imc_info.get("addr", ) if ((addr) != "08.0") and ((addr) != "09.0"): raise ArgsNotCorrect("imc address must be 08.0 or 09.0")
def __check_peer_bmc_info(self): if self.__peer_bmc_info_list: for pbi in self.__peer_bmc_info_list: addr = pbi.get("addr") if addr is None or (addr & 0x1) or addr >= 0xff: raise ArgsNotCorrect( "[BMC] {} is not a valid I2C address.".format(addr)) peer_port = pbi.get("port_ipmb") if peer_port is None: raise ArgsNotCorrect("[BMC] peer ipmb port is not given.") host_ip = pbi.get("host") try: socket.inet_aton(host_ip) except socket.error as e: raise ArgsNotCorrect("[BMC] {} is not valid.({})".format( host_ip, e))
def precheck(self): if not self.__backend_type: raise ArgsNotCorrect("[Chardev] Backend of chardev should be set.") if self.__host and not helper.is_valid_ip(self.__host): raise ArgsNotCorrect("[CharDev] Invalid chardev host: {}".format( self.__host)) if self.__port: try: int(self.__port) except ValueError, e: raise ArgsNotCorrect( "[Chardev] Port is not a valid integer: {}".format( self.__port)) if helper.check_if_port_in_use("0.0.0.0", self.__port): raise ArgsNotCorrect( "[Chardev] Port {} is already in use".format(self.__port))