summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaroslav Brustinov <ybrustin@cisco.com>2016-08-21 23:22:19 +0300
committerYaroslav Brustinov <ybrustin@cisco.com>2016-08-21 23:22:19 +0300
commite939511acbb16cda3dab34fe255160ae7ae19258 (patch)
tree529e3df8b1e4ac7f8a406861cd23eba0f6d5f46a
parent5f9c0e65223f26de99958260420601670df4e012 (diff)
Check if interfaces are in use at binding/unbinding/starting TRex.
-rwxr-xr-xscripts/dpdk_nic_bind.py87
-rwxr-xr-xscripts/dpdk_setup_ports.py53
-rwxr-xr-xscripts/trex-cfg14
3 files changed, 125 insertions, 29 deletions
diff --git a/scripts/dpdk_nic_bind.py b/scripts/dpdk_nic_bind.py
index dcb84823..b1f38c09 100755
--- a/scripts/dpdk_nic_bind.py
+++ b/scripts/dpdk_nic_bind.py
@@ -317,6 +317,51 @@ def dev_id_from_dev_name(dev_name):
"Please specify device in \"bus:slot.func\" format" % dev_name)
sys.exit(1)
+def get_igb_uio_usage():
+ for driver in dpdk_drivers:
+ refcnt_file = '/sys/module/%s/refcnt' % driver
+ if not os.path.exists(refcnt_file):
+ continue
+ with open(refcnt_file) as f:
+ ref_cnt = int(f.read().strip())
+ if ref_cnt:
+ return True
+ return False
+
+def get_pid_using_pci(pci_list):
+ if not isinstance(pci_list, list):
+ pci_list = [pci_list]
+ pci_list = map(dev_id_from_dev_name, pci_list)
+ for pid in os.listdir('/proc'):
+ try:
+ int(pid)
+ except ValueError:
+ continue
+ with open('/proc/%s/maps' % pid) as f:
+ f_cont = f.read()
+ for pci in pci_list:
+ if '/%s/' % pci in f_cont:
+ with open('/proc/%s/status' % pid) as f:
+ for line in f.readlines():
+ key, val = line.split(':', 1)
+ if key.strip() == 'Tgid' and val.strip() == pid:
+ return int(pid)
+
+def read_pid_cmdline(pid):
+ cmdline_file = '/proc/%s/cmdline' % pid
+ if not os.path.exists(cmdline_file):
+ return None
+ with open(cmdline_file, 'rb') as f:
+ return f.read().replace(b'\0', b' ').decode()
+
+def confirm(msg, default = False):
+ try:
+ if not os.isatty(1):
+ return default
+ return strtobool(raw_input(msg))
+ except:
+ return default
+
def unbind_one(dev_id, force):
'''Unbind the device identified by "dev_id" from its current driver'''
dev = devices[dev_id]
@@ -325,17 +370,22 @@ def unbind_one(dev_id, force):
(dev[b"Slot"], dev[b"Device_str"], dev[b"Interface"]))
return
- # prevent us disconnecting ourselves
- if dev["Active"] and not force:
- print("netstat indicates that interface %s is active." % dev_id)
- result = None
- try:
- result = strtobool(raw_input("Confirm unbind (y/N)"))
- finally:
- if not result:
+ if not force and dev.get('Driver_str') in dpdk_drivers and get_igb_uio_usage():
+ pid = get_pid_using_pci(dev_id)
+ if pid:
+ cmdline = read_pid_cmdline(pid)
+ print('Interface %s is in use by process:\n%s' % (dev_id, cmdline))
+ if not confirm('Unbinding might hang the process. Confirm unbind (y/N)'):
print('Not unbinding.')
return
+ # prevent us disconnecting ourselves
+ if dev["Active"] and not force:
+ print('netstat indicates that interface %s is active.' % dev_id)
+ if not confirm('Confirm unbind (y/N)'):
+ print('Not unbinding.')
+ return
+
# write to /sys to unbind
filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]
try:
@@ -355,13 +405,9 @@ def bind_one(dev_id, driver, force):
# prevent disconnection of our ssh session
if dev["Active"] and not force:
print("netstat indicates that interface %s is active" % dev_id)
- result = None
- try:
- result = strtobool(raw_input("Confirm bind (y/N)"))
- finally:
- if not result:
- print('Not binding.')
- return
+ if not confirm("Confirm bind (y/N)"):
+ print('Not binding.')
+ return
# unbind any existing drivers we don't want
if has_driver(dev_id):
@@ -370,6 +416,15 @@ def bind_one(dev_id, driver, force):
return
else:
saved_driver = dev["Driver_str"]
+ if not force and get_igb_uio_usage():
+ pid = get_pid_using_pci(dev_id)
+ if pid:
+ cmdline = read_pid_cmdline(pid)
+ print('Interface %s is in use by process:\n%s' % (dev_id, cmdline))
+ if not confirm('Binding to other driver might hang the process. Confirm unbind (y/N)'):
+ print('Not binding.')
+ return
+
unbind_one(dev_id, force)
dev["Driver_str"] = "" # clear driver string
@@ -507,7 +562,7 @@ def get_macs_from_trex(pci_addr_list):
if 'PANIC in rte_eal_init' in stdout:
print("Could not run TRex to get MAC info about interfaces, check if it's already running.")
else:
- print('Error upon running TRex to get MAC info:\n%s.' % stdout)
+ print('Error upon running TRex to get MAC info:\n%s' % stdout)
sys.exit(1)
pci_mac_str = 'PCI: (\S+).+?MAC: (\S+)'
pci_mac_re = re.compile(pci_mac_str)
diff --git a/scripts/dpdk_setup_ports.py b/scripts/dpdk_setup_ports.py
index 252779a7..b32163da 100755
--- a/scripts/dpdk_setup_ports.py
+++ b/scripts/dpdk_setup_ports.py
@@ -239,7 +239,6 @@ Other network devices
raise DpdkSetup(s)
def load_config_file (self):
- #return
fcfg=self.m_cfg_file
@@ -302,30 +301,60 @@ Other network devices
def run_dpdk_lspci (self):
- dpdk_nic_bind.get_nic_details()
- self.m_devices= dpdk_nic_bind.devices
+ dpdk_nic_bind.get_nic_details()
+ self.m_devices= dpdk_nic_bind.devices
def do_run (self):
self.run_dpdk_lspci ()
- if map_driver.dump_interfaces is None or (map_driver.dump_interfaces is [] and map_driver.parent_cfg):
+ 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'])
- for obj in if_list:
- key= self.pci_name_to_full_name (obj)
+ 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'] !='igb_uio' :
+ 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_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
+ print('TODO: unbind %s' % dpdk_interfaces)
def do_create(self):
create_interfaces = map_driver.args.create_interfaces
@@ -357,7 +386,7 @@ Other network devices
if 'Driver_str' not in interface:
self.do_bind_one(interface['Slot'])
dpdk_bound.append(interface['Slot'])
- elif interface['Driver_str'] == 'igb_uio':
+ elif interface['Driver_str'] in dpdk_nic_bind.dpdk_drivers:
dpdk_bound.append(interface['Slot'])
if dpdk_bound:
for pci, mac in dpdk_nic_bind.get_macs_from_trex(dpdk_bound).items():
@@ -414,7 +443,7 @@ def process_options ():
Examples:
---------
-To unbind the interfaces using the trex configuration file
+To return to Linux the DPDK bound interfaces (for ifconfig etc.)
sudo ./dpdk_set_ports.py -l
To create a default config file (example1)
@@ -433,8 +462,8 @@ To see more detailed info on interfaces (table):
description=" unbind dpdk interfaces ",
epilog=" written by hhaim");
- parser.add_argument("-l", "--load", action='store_true',
- help=""" unbind the interfaces using the configuration file given """,
+ parser.add_argument("-l", "--linux", action='store_true',
+ help=""" Return all DPDK interfaces to Linux driver """,
)
parser.add_argument("--cfg",
@@ -524,6 +553,8 @@ def main ():
if map_driver.args.create_interfaces is not None:
obj.do_create();
+ elif map_driver.args.linux:
+ obj.do_return_to_linux();
else:
obj.do_run();
except DpdkSetup as e:
diff --git a/scripts/trex-cfg b/scripts/trex-cfg
index 02421001..55eb18fb 100755
--- a/scripts/trex-cfg
+++ b/scripts/trex-cfg
@@ -65,5 +65,15 @@ fi
# try to bind the ports from the configuration file (new DPDK)
PARENT_ARGS="$0 $@"
-(/usr/bin/python -V &> /dev/null && ./dpdk_setup_ports.py --parent "$PARENT_ARGS") ||
- (/usr/bin/python3 -V &> /dev/null && /usr/bin/python3 dpdk_setup_ports.py --parent "$PARENT_ARGS") || exit 1
+
+if /usr/bin/python -V &> /dev/null; then
+ ./dpdk_setup_ports.py --parent "$PARENT_ARGS"
+elif /usr/bin/python3 -V &> /dev/null; then
+ /usr/bin/python3 dpdk_setup_ports.py --parent "$PARENT_ARGS"
+elif python -V &> /dev/null; then
+ python ./dpdk_setup_ports.py --parent "$PARENT_ARGS"
+else
+ echo "Could not find python to run dpdk_setup_ports.py script"
+ exit 1
+fi
+