def do_run (self): self.run_dpdk_lspci () if map_driver.dump_interfaces is None or (map_driver.dump_interfaces == [] and map_driver.parent_cfg): self.load_config_file() if_list=self.m_cfg_dict[0]['interfaces'] else: if_list = map_driver.dump_interfaces if not if_list: for dev in self.m_devices.values(): if dev.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: if_list.append(dev['Slot']) if_list = list(map(self.pci_name_to_full_name, if_list)) for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Driver_str' in self.m_devices[key]: if self.m_devices[key]['Driver_str'] not in dpdk_nic_bind.dpdk_drivers : self.do_bind_one (key) else: self.do_bind_one (key) if if_list and map_driver.args.parent and dpdk_nic_bind.get_igb_uio_usage(): pid = dpdk_nic_bind.get_pid_using_pci(if_list) cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('Some or all of given interfaces are in use by following process:\npid: %s, cmd: %s' % (pid, cmdline)) if not dpdk_nic_bind.confirm('Ignore and proceed (y/N):'): sys.exit(1)
def do_return_to_linux(self): if not self.m_devices: self.run_dpdk_lspci() dpdk_interfaces = [] for device in self.m_devices.values(): if device.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: dpdk_interfaces.append(device['Slot']) if not dpdk_interfaces: print('No DPDK bound interfaces.') return if dpdk_nic_bind.get_igb_uio_usage(): pid = dpdk_nic_bind.get_pid_using_pci(dpdk_interfaces) if pid: cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('DPDK interfaces are in use. Unbinding them might cause following process to hang:\npid: %s, cmd: %s' % (pid, cmdline)) if not dpdk_nic_bind.confirm('Confirm (y/N):'): return drivers_table = { 'rte_ixgbe_pmd': 'ixgbe', 'rte_igb_pmd': 'igb', 'rte_i40e_pmd': 'i40e', 'rte_em_pmd': 'e1000', 'rte_vmxnet3_pmd': 'vmxnet3', 'rte_virtio_pmd': 'virtio-pci', 'rte_enic_pmd': 'enic', } for pci, info in dpdk_nic_bind.get_info_from_trex(dpdk_interfaces).items(): if pci not in self.m_devices: raise DpdkSetup('Internal error: PCI %s is not found among devices' % pci) dev = self.m_devices[pci] if info['TRex_Driver'] not in drivers_table: print('Got unknown driver %s, description: %s' % (info['TRex_Driver'], dev['Device_str'])) else: print('Returning to Linux %s' % pci) dpdk_nic_bind.bind_one(pci, drivers_table[info['TRex_Driver']], False)
def do_return_to_linux(self): if not self.m_devices: self.run_dpdk_lspci() dpdk_interfaces = [] for device in self.m_devices.values(): if device.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: dpdk_interfaces.append(device['Slot']) if not dpdk_interfaces: print('No DPDK bound interfaces.') return if dpdk_nic_bind.get_igb_uio_usage(): pid = dpdk_nic_bind.get_pid_using_pci(dpdk_interfaces) if pid: cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('DPDK interfaces are in use. Unbinding them might cause following process to hang:\n%s' % cmdline) if not dpdk_nic_bind.confirm('Confirm (y/N):'): return drivers_table = { 'rte_ixgbe_pmd': 'ixgbe', 'rte_igb_pmd': 'igb', 'rte_i40e_pmd': 'i40e', 'rte_em_pmd': 'e1000', 'rte_vmxnet3_pmd': 'vmxnet3', 'rte_virtio_pmd': 'virtio', 'rte_enic_pmd': 'enic', } for pci, info in dpdk_nic_bind.get_info_from_trex(dpdk_interfaces).items(): if pci not in self.m_devices: raise DpdkSetup('Internal error: PCI %s is not found among devices' % pci) dev = self.m_devices[pci] if info['TRex_Driver'] not in drivers_table: print('Got unknown driver %s, description: %s' % (info['TRex_Driver'], dev['Device_str'])) else: print('Returning to Linux %s' % pci) dpdk_nic_bind.bind_one(pci, drivers_table[info['TRex_Driver']], False)
def do_run (self): self.run_dpdk_lspci () if map_driver.dump_interfaces is None or (map_driver.dump_interfaces == [] and map_driver.parent_cfg): self.load_config_file() if_list=self.m_cfg_dict[0]['interfaces'] else: if_list = map_driver.dump_interfaces if not if_list: for dev in self.m_devices.values(): if dev.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: if_list.append(dev['Slot']) if_list = list(map(self.pci_name_to_full_name, if_list)) for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Driver_str' in self.m_devices[key]: if self.m_devices[key]['Driver_str'] not in dpdk_nic_bind.dpdk_drivers : self.do_bind_one (key) else: self.do_bind_one (key) if if_list and map_driver.args.parent and dpdk_nic_bind.get_igb_uio_usage(): pid = dpdk_nic_bind.get_pid_using_pci(if_list) cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('Some or all of given interfaces are in use by following process:\n%s' % cmdline) if not dpdk_nic_bind.confirm('Ignore and proceed (y/N):'): sys.exit(1)
def do_interactive_create(self): ignore_numa = False cpu_topology = self._get_cpu_topology() total_lcores = sum([len(lcores) for cores in cpu_topology.values() for lcores in cores.values()]) if total_lcores < 1: print('Script could not determine cores of the system, exiting.') sys.exit(1) elif total_lcores < 2: if dpdk_nic_bind.confirm("You have only 1 core and can't run TRex at all. Ignore and continue? (y/N): "): ignore_numa = True else: sys.exit(1) elif total_lcores < 3: if dpdk_nic_bind.confirm("You have only 2 cores and will be able to run only Stateful without latency checks.\nIgnore and continue? (y/N): "): ignore_numa = True else: sys.exit(1) if not self.m_devices: self.run_dpdk_lspci() dpdk_nic_bind.show_table() print('Please choose even number of interfaces either by ID or PCI or Linux IF (look at columns above).') print('Stateful will use order of interfaces: Client1 Server1 Client2 Server2 etc. for flows.') print('Stateless can be in any order.') numa = None for dev in self.m_devices.values(): if numa is None: numa = dev['NUMA'] elif numa != dev['NUMA']: print('Try to choose each pair of interfaces to be on same NUMA within the pair for performance.') break while True: try: input = dpdk_nic_bind.read_line('Enter list of interfaces in line (for example: 1 3) : ') create_interfaces = input.replace(',', ' ').replace(';', ' ').split() wanted_interfaces = self._get_wanted_interfaces(create_interfaces) ConfigCreator._verify_devices_same_type(wanted_interfaces) except Exception as e: print(e) continue break print('') for interface in wanted_interfaces: if interface['Active']: print('Interface %s is active. Using it by TRex might close ssh connections etc.' % interface['Interface_argv']) if not dpdk_nic_bind.confirm('Ignore and continue? (y/N): '): sys.exit(1) for i, interface in enumerate(wanted_interfaces): if 'MAC' not in interface: raise DpdkSetup('Cound not determine MAC of interface: %s. Please verify with -t flag.' % interface['Interface_argv']) interface['src_mac'] = interface['MAC'] dual_index = i + 1 - (i % 2) * 2 dual_int = wanted_interfaces[dual_index] if not ignore_numa and interface['NUMA'] != dual_int['NUMA']: print('NUMA is different at pair of interfaces: %s and %s. It will reduce performance.' % (interface['Interface_argv'], dual_int['Interface_argv'])) if dpdk_nic_bind.confirm('Ignore and continue? (y/N): '): ignore_numa = True print('') else: return dest_mac = dual_int['MAC'] loopback_dest = True print("For interface %s, assuming loopback to it's dual interface %s." % (interface['Interface_argv'], dual_int['Interface_argv'])) if dpdk_nic_bind.confirm("Destination MAC is %s. Change it to MAC of DUT? (y/N)." % dest_mac): while True: input_mac = dpdk_nic_bind.read_line('Please enter new destination MAC of interface %s: ' % interface['Interface_argv']) try: if input_mac: ConfigCreator._convert_mac(input_mac) # verify format dest_mac = input_mac loopback_dest = False else: print('Leaving the loopback MAC.') except Exception as e: print(e) continue break wanted_interfaces[i]['dest_mac'] = dest_mac wanted_interfaces[i]['loopback_dest'] = loopback_dest config = ConfigCreator(cpu_topology, wanted_interfaces, include_lcores = map_driver.args.create_include, exclude_lcores = map_driver.args.create_exclude, only_first_thread = map_driver.args.no_ht, ignore_numa = map_driver.args.ignore_numa or ignore_numa, prefix = map_driver.args.prefix, zmq_rpc_port = map_driver.args.zmq_rpc_port, zmq_pub_port = map_driver.args.zmq_pub_port) if dpdk_nic_bind.confirm('Print preview of generated config? (Y/n)', default = True): config.create_config(print_config = True) if dpdk_nic_bind.confirm('Save the config to file? (Y/n)', default = True): print('Default filename is /etc/trex_cfg.yaml') filename = dpdk_nic_bind.read_line('Press ENTER to confirm or enter new file: ') if not filename: filename = '/etc/trex_cfg.yaml' config.create_config(filename = filename)
def create_config(self, filename = None, print_config = False): config_str = '### Config file generated by dpdk_setup_ports.py ###\n\n' config_str += '- port_limit: %s\n' % len(self.interfaces) config_str += ' version: 2\n' config_str += " interfaces: ['%s']\n" % "', '".join([interface['Slot_str'] for interface in self.interfaces]) if self.speed > 10: config_str += ' port_bandwidth_gb: %s\n' % self.speed if self.prefix: config_str += ' prefix: %s\n' % self.prefix if self.zmq_pub_port: config_str += ' zmq_pub_port: %s\n' % self.zmq_pub_port if self.zmq_rpc_port: config_str += ' zmq_rpc_port: %s\n' % self.zmq_rpc_port config_str += ' port_info:\n' for index, interface in enumerate(self.interfaces): config_str += ' '*6 + '- dest_mac: [%s]' % self._convert_mac(interface['dest_mac']) if interface.get('loopback_dest'): config_str += " # MAC OF LOOPBACK TO IT'S DUAL INTERFACE\n" else: config_str += '\n' config_str += ' '*8 + 'src_mac: [%s]\n' % self._convert_mac(interface['src_mac']) if index % 2: config_str += '\n' # dual if barrier if not self.ignore_numa: config_str += ' platform:\n' if len(self.interfaces_per_numa.keys()) == 1 and -1 in self.interfaces_per_numa: # VM, use any cores, 1 core per dual_if lcores_pool = sorted([lcore for lcores in self.lcores_per_numa.values() for lcore in lcores]) config_str += ' '*6 + 'master_thread_id: %s\n' % (0 if self.has_zero_lcore else lcores_pool.pop()) config_str += ' '*6 + 'latency_thread_id: %s\n' % lcores_pool.pop(0) lcores_per_dual_if = int(len(lcores_pool) / len(self.interfaces)) config_str += ' '*6 + 'dual_if:\n' for i in range(0, len(self.interfaces), 2): lcores_for_this_dual_if = [str(lcores_pool.pop(0)) for _ in range(lcores_per_dual_if)] config_str += ' '*8 + '- socket: 0\n' config_str += ' '*10 + 'threads: [%s]\n\n' % ','.join(lcores_for_this_dual_if) else: # we will take common minimum among all NUMAs, to satisfy all lcores_per_dual_if = 99 extra_lcores = 1 if self.has_zero_lcore else 2 # worst case 3 iterations, to ensure master and "rx" have cores left while (lcores_per_dual_if * sum(self.interfaces_per_numa.values()) / 2) + extra_lcores > sum([len(lcores) for lcores in self.lcores_per_numa.values()]): lcores_per_dual_if -= 1 for numa, cores in self.lcores_per_numa.items(): if not self.interfaces_per_numa[numa]: continue lcores_per_dual_if = min(lcores_per_dual_if, int(2 * len(cores) / self.interfaces_per_numa[numa])) lcores_pool = copy.deepcopy(self.lcores_per_numa) # first, allocate lcores for dual_if section dual_if_section = ' '*6 + 'dual_if:\n' for i in range(0, len(self.interfaces), 2): numa = self.interfaces[i]['NUMA'] dual_if_section += ' '*8 + '- socket: %s\n' % numa lcores_for_this_dual_if = [str(lcores_pool[numa].pop(0)) for _ in range(lcores_per_dual_if)] if not lcores_for_this_dual_if: raise DpdkSetup('Not enough cores at NUMA %s. This NUMA has %s processing units and %s interfaces.' % (numa, len(self.lcores_per_numa[numa]), self.interfaces_per_numa[numa])) dual_if_section += ' '*10 + 'threads: [%s]\n\n' % ','.join(lcores_for_this_dual_if) # take the cores left to master and rx lcores_pool_left = [lcore for lcores in lcores_pool.values() for lcore in lcores] config_str += ' '*6 + 'master_thread_id: %s\n' % (0 if self.has_zero_lcore else lcores_pool_left.pop(0)) config_str += ' '*6 + 'latency_thread_id: %s\n' % lcores_pool_left.pop(0) # add the dual_if section config_str += dual_if_section # verify config is correct YAML format try: yaml.safe_load(config_str) except Exception as e: raise DpdkSetup('Could not create correct yaml config.\nGenerated YAML:\n%s\nEncountered error:\n%s' % (config_str, e)) if print_config: print(config_str) if filename: if os.path.exists(filename): if not dpdk_nic_bind.confirm('File %s already exist, overwrite? (y/N)' % filename): print('Skipping.') return config_str with open(filename, 'w') as f: f.write(config_str) print('Saved.') return config_str
def create_config(self, filename = None, print_config = False): config_str = '### Config file generated by dpdk_setup_ports.py ###\n\n' config_str += '- port_limit: %s\n' % len(self.interfaces) config_str += ' version: 2\n' config_str += " interfaces: ['%s']\n" % "', '".join([interface['Slot_str'] for interface in self.interfaces]) if self.speed > 10: config_str += ' port_bandwidth_gb: %s\n' % self.speed if self.prefix: config_str += ' prefix: %s\n' % self.prefix if self.zmq_pub_port: config_str += ' zmq_pub_port: %s\n' % self.zmq_pub_port if self.zmq_rpc_port: config_str += ' zmq_rpc_port: %s\n' % self.zmq_rpc_port config_str += ' port_info:\n' for index, interface in enumerate(self.interfaces): config_str += ' '*6 + '- dest_mac: [%s]' % self._convert_mac(interface['dest_mac']) if interface.get('loopback_dest'): config_str += " # MAC OF LOOPBACK TO IT'S DUAL INTERFACE\n" else: config_str += '\n' config_str += ' '*8 + 'src_mac: [%s]\n' % self._convert_mac(interface['src_mac']) if index % 2: config_str += '\n' # dual if barrier if not self.ignore_numa: config_str += ' platform:\n' if len(self.interfaces_per_numa.keys()) == 1 and -1 in self.interfaces_per_numa: # VM, use any cores, 1 core per dual_if lcores_pool = sorted([lcore for lcores in self.lcores_per_numa.values() for lcore in lcores]) config_str += ' '*6 + 'master_thread_id: %s\n' % (0 if self.has_zero_lcore else lcores_pool.pop()) config_str += ' '*6 + 'latency_thread_id: %s\n' % lcores_pool.pop(0) config_str += ' '*6 + 'dual_if:\n' for i in range(0, len(self.interfaces), 2): config_str += ' '*8 + '- socket: 0\n' config_str += ' '*10 + 'threads: [%s]\n\n' % lcores_pool.pop(0) else: # we will take common minimum among all NUMAs, to satisfy all lcores_per_dual_if = 99 extra_lcores = 1 if self.has_zero_lcore else 2 # worst case 3 iterations, to ensure master and "rx" have cores left while (lcores_per_dual_if * sum(self.interfaces_per_numa.values()) / 2) + extra_lcores > sum([len(lcores) for lcores in self.lcores_per_numa.values()]): lcores_per_dual_if -= 1 for numa, cores in self.lcores_per_numa.items(): if not self.interfaces_per_numa[numa]: continue lcores_per_dual_if = min(lcores_per_dual_if, int(2 * len(cores) / self.interfaces_per_numa[numa])) lcores_pool = copy.deepcopy(self.lcores_per_numa) # first, allocate lcores for dual_if section dual_if_section = ' '*6 + 'dual_if:\n' for i in range(0, len(self.interfaces), 2): numa = self.interfaces[i]['NUMA'] dual_if_section += ' '*8 + '- socket: %s\n' % numa lcores_for_this_dual_if = [str(lcores_pool[numa].pop(0)) for _ in range(lcores_per_dual_if)] if not lcores_for_this_dual_if: raise DpdkSetup('Not enough cores at NUMA %s. This NUMA has %s processing units and %s interfaces.' % (numa, len(self.lcores_per_numa[numa]), self.interfaces_per_numa[numa])) dual_if_section += ' '*10 + 'threads: [%s]\n\n' % ','.join(lcores_for_this_dual_if) # take the cores left to master and rx lcores_pool_left = [lcore for lcores in lcores_pool.values() for lcore in lcores] config_str += ' '*6 + 'master_thread_id: %s\n' % (0 if self.has_zero_lcore else lcores_pool_left.pop(0)) config_str += ' '*6 + 'latency_thread_id: %s\n' % lcores_pool_left.pop(0) # add the dual_if section config_str += dual_if_section # verify config is correct YAML format try: yaml.safe_load(config_str) except Exception as e: raise DpdkSetup('Could not create correct yaml config.\nGenerated YAML:\n%s\nEncountered error:\n%s' % (config_str, e)) if print_config: print(config_str) if filename: if os.path.exists(filename): if not dpdk_nic_bind.confirm('File %s already exist, overwrite? (y/N)' % filename): print('Skipping.') return config_str with open(filename, 'w') as f: f.write(config_str) print('Saved.') return config_str
def do_run (self,only_check_all_mlx=False): """ return the number of mellanox drivers""" self.run_dpdk_lspci () if (map_driver.parent_args.dump_interfaces is None or (map_driver.parent_args.dump_interfaces == [] and map_driver.parent_args.cfg)): self.load_config_file() if_list=self.m_cfg_dict[0]['interfaces'] else: if_list = map_driver.parent_args.dump_interfaces if not if_list: for dev in self.m_devices.values(): if dev.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: if_list.append(dev['Slot']) if_list = list(map(self.pci_name_to_full_name, if_list)) # check how many mellanox cards we have Mellanox_cnt=0; for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Vendor_str' not in self.m_devices[key]: err=" %s does not have Vendor_str " %key; raise DpdkSetup(err) if self.m_devices[key]['Vendor_str'].find("Mellanox")>-1 : Mellanox_cnt=Mellanox_cnt+1 if not map_driver.parent_args.dump_interfaces: if ((Mellanox_cnt>0) and (Mellanox_cnt!= len(if_list))): err=" All driver should be from one vendor. you have at least one driver from Mellanox but not all "; raise DpdkSetup(err) if not map_driver.parent_args.dump_interfaces: if Mellanox_cnt>0 : self.set_only_mellanox_nics() if self.get_only_mellanox_nics(): if not map_driver.parent_args.no_ofed_check: self.verify_ofed_os() self.check_ofed_version() for key in if_list: pci_id=self.m_devices[key]['Slot_str'] self.tune_mlx5_device (pci_id) if 'Interface' in self.m_devices[key]: dev_id=self.m_devices[key]['Interface'] self.disable_flow_control_mlx5_device (dev_id) self.set_max_mtu_mlx5_device(dev_id) if only_check_all_mlx: if Mellanox_cnt >0: exit(1); else: exit(0); for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Driver_str' in self.m_devices[key]: if self.m_devices[key]['Driver_str'] not in (dpdk_nic_bind.dpdk_drivers+dpdk_nic_bind.dpdk_and_kernel) : self.do_bind_one (key,(Mellanox_cnt>0)) pass; else: self.do_bind_one (key,(Mellanox_cnt>0)) pass; if (Mellanox_cnt==0): # We are not in Mellanox case, we can do this check only in case of Intel (another process is running) if if_list and map_driver.args.parent and (dpdk_nic_bind.get_igb_uio_usage()): pid = dpdk_nic_bind.get_pid_using_pci(if_list) if pid: cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('Some or all of given interfaces are in use by following process:\npid: %s, cmd: %s' % (pid, cmdline)) if not dpdk_nic_bind.confirm('Ignore and proceed (y/N):'): sys.exit(-1) else: print('WARNING: Some other program is using DPDK driver.\nIf it is TRex and you did not configure it for dual run, current command will fail.') if map_driver.parent_args.stl and not map_driver.parent_args.no_scapy_server: try: master_core = self.m_cfg_dict[0]['platform']['master_thread_id'] except: master_core = 0 ret = os.system('%s scapy_daemon_server restart -c %s' % (sys.executable, master_core)) if ret: print("Could not start scapy_daemon_server, which is needed by GUI to create packets.\nIf you don't need it, use --no-scapy-server flag.") sys.exit(-1) if Mellanox_cnt: return 1 else: return 0
def do_run (self,only_check_all_mlx=False): self.run_dpdk_lspci () if map_driver.dump_interfaces is None or (map_driver.dump_interfaces == [] and map_driver.parent_cfg): self.load_config_file() if_list=self.m_cfg_dict[0]['interfaces'] else: if_list = map_driver.dump_interfaces if not if_list: for dev in self.m_devices.values(): if dev.get('Driver_str') in dpdk_nic_bind.dpdk_drivers: if_list.append(dev['Slot']) if_list = list(map(self.pci_name_to_full_name, if_list)) # check how many mellanox cards we have Mellanox_cnt=0; for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Vendor_str' not in self.m_devices[key]: err=" %s does not have Vendor_str " %key; raise DpdkSetup(err) if self.m_devices[key]['Vendor_str'].find("Mellanox")>-1 : Mellanox_cnt=Mellanox_cnt+1 if not map_driver.dump_interfaces : if ((Mellanox_cnt>0) and (Mellanox_cnt!= len(if_list))): err=" All driver should be from one vendor. you have at least one driver from Mellanox but not all "; raise DpdkSetup(err) if not map_driver.dump_interfaces : if Mellanox_cnt>0 : self.set_only_mellanox_nics() if self.get_only_mellanox_nics(): self.check_ofe_version () for key in if_list: pci_id=self.m_devices[key]['Slot_str'] self.tune_mlx5_device (pci_id) if 'Interface' in self.m_devices[key]: dev_id=self.m_devices[key]['Interface'] self.disable_flow_control_mlx5_device (dev_id) self.set_max_mtu_mlx5_device(dev_id) if only_check_all_mlx: if Mellanox_cnt >0: exit(1); else: exit(0); for key in if_list: if key not in self.m_devices: err=" %s does not exist " %key; raise DpdkSetup(err) if 'Driver_str' in self.m_devices[key]: if self.m_devices[key]['Driver_str'] not in (dpdk_nic_bind.dpdk_drivers+dpdk_nic_bind.dpdk_and_kernel) : self.do_bind_one (key,(Mellanox_cnt>0)) pass; else: self.do_bind_one (key,(Mellanox_cnt>0)) pass; if (Mellanox_cnt==0): # We are not in Mellanox case, we can do this check only in case of Intel (another process is running) if if_list and map_driver.args.parent and (dpdk_nic_bind.get_igb_uio_usage()): pid = dpdk_nic_bind.get_pid_using_pci(if_list) if pid: cmdline = dpdk_nic_bind.read_pid_cmdline(pid) print('Some or all of given interfaces are in use by following process:\npid: %s, cmd: %s' % (pid, cmdline)) if not dpdk_nic_bind.confirm('Ignore and proceed (y/N):'): sys.exit(1) else: print('WARNING: Some other program is using DPDK driver.\nIf it is TRex and you did not configure it for dual run, current command will fail.')