summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsongyanchao <[email protected]>2023-03-16 10:03:57 +0000
committersongyanchao <[email protected]>2023-03-16 10:23:26 +0000
commitc1023ce42bd9081dd35809be39071fc968ca799a (patch)
treef634ae1dd73c30d03ee2a586a6ec6dedb90455f9
parentdfbfd088b56614ea09aa976633f10a99da2a3c17 (diff)
✨ feat(DPISDN-2): 将 mrenv 拆分为 hugepages setup 和 hwdb setup 两个servicev4.6.18-20230317
将 mrenv 拆分为 hugepages setup 和 hwdb setup 两个service
-rw-r--r--cmake/InstallDPDK.cmake4
-rw-r--r--tools/devbind/CMakeLists.txt16
-rw-r--r--tools/devbind/devbind.py547
-rw-r--r--tools/systemd/CMakeLists.txt23
-rw-r--r--tools/systemd/mrenv-script441
-rw-r--r--tools/systemd/mrenv.service.in14
-rw-r--r--tools/systemd/mrzcpd-hugepages-setup.service.in13
-rw-r--r--tools/systemd/mrzcpd-hwdb-setup.service.in11
-rw-r--r--tools/systemd/mrzcpd.service.in8
9 files changed, 132 insertions, 945 deletions
diff --git a/cmake/InstallDPDK.cmake b/cmake/InstallDPDK.cmake
index 3cc5893..38b59ce 100644
--- a/cmake/InstallDPDK.cmake
+++ b/cmake/InstallDPDK.cmake
@@ -35,6 +35,10 @@ install(PROGRAMS ${DPDK_BINARY_TOOLS_PATH}/dpdk-pdump DESTINATION ${TOOLS_INSTAL
install(PROGRAMS ${DPDK_BINARY_TOOLS_PATH}/dpdk-proc-info DESTINATION ${TOOLS_INSTALL_PATH}
RENAME mrtools-pinfo COMPONENT Program)
+install(PROGRAMS ${DPDK_BINARY_TOOLS_PATH}/dpdk-devbind.py DESTINATION ${TOOLS_INSTALL_PATH} COMPONENT Program)
+
+install(PROGRAMS ${DPDK_BINARY_TOOLS_PATH}/dpdk-hugepages.py DESTINATION ${TOOLS_INSTALL_PATH} COMPONENT Program)
+
# MLX5 GLUE
file(GLOB PMD_MLX5_GLUE_LIST "${DPDK_LIBRARY_DIR}/dpdk/pmds-*-glue/*")
foreach(PMD_MLX5_GLUE_ITEM ${PMD_MLX5_GLUE_LIST})
diff --git a/tools/devbind/CMakeLists.txt b/tools/devbind/CMakeLists.txt
index 3103646..c2ef01f 100644
--- a/tools/devbind/CMakeLists.txt
+++ b/tools/devbind/CMakeLists.txt
@@ -1,15 +1 @@
-
-set(PI_DIST_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_dist)
-set(PI_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_build)
-set(PI_SPEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_spec)
-
-add_custom_command(OUTPUT ${PI_DIST_PATH}/devbind
- COMMAND pyinstaller -F -y --distpath ${PI_DIST_PATH}
- --workpath ${PI_BUILD_PATH}
- --specpath ${PI_SPEC_PATH}
- --noconsole ${CMAKE_CURRENT_SOURCE_DIR}/devbind.py
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/devbind.py)
-
-add_custom_target(devbind ALL DEPENDS ${PI_DIST_PATH}/devbind)
-install(PROGRAMS ${PI_DIST_PATH}/devbind DESTINATION bin
- RENAME mrtools-devbind COMPONENT Program) \ No newline at end of file
+install(PROGRAMS devbind.py DESTINATION bin COMPONENT Program) \ No newline at end of file
diff --git a/tools/devbind/devbind.py b/tools/devbind/devbind.py
index cac493c..62d4a5b 100644
--- a/tools/devbind/devbind.py
+++ b/tools/devbind/devbind.py
@@ -1,473 +1,98 @@
-#! /usr/bin/env python
-#
-# BSD LICENSE
-#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-# Copyright(c) 2017-2020 Institute of Information Engineering, CAS
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Intel Corporation nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-import sys
import os
-import getopt
import subprocess
+import configparser
+import re
import json
-import argparse
-import platform
-from os.path import exists, abspath, dirname, basename
-from glob import glob
-from os.path import join as path_join
-
-# The PCI base class for NETWORK devices
-NETWORK_BASE_CLASS = "02"
-CRYPTO_BASE_CLASS = "0b"
-
-# global dict ethernet devices present. Dictionary indexed by PCI address.
-# Each device within this is itself a dictionary of device properties
-devices = {}
-# list of supported DPDK drivers
-dpdk_drivers = ["uio_pci_generic", "igb_uio", "vfio-pci"]
-
-# hwfile location
-default_hwfile_location = '/var/run/mrzcpd/hwfile.json'
-default_gcfg_location = '/usr/local/etc/mrglobal.conf'
-
-# This is roughly compatible with check_output function in subprocess module
-# which is only available in python 2.7.
-def check_output(args, stderr=None):
- '''Run a command and capture its output'''
- return subprocess.Popen(args, stdout=subprocess.PIPE,
- stderr=stderr).communicate()[0]
-
-
-def check_modules():
- '''Checks that igb_uio is loaded'''
- global dpdk_drivers
-
- # list of supported modules
- mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers]
-
- # first check if module is loaded
- try:
- # Get list of sysfs modules (both built-in and dynamically loaded)
- sysfs_path = '/sys/module/'
-
- # Get the list of directories in sysfs_path
- sysfs_mods = [os.path.join(sysfs_path, o) for o
- in os.listdir(sysfs_path)
- if os.path.isdir(os.path.join(sysfs_path, o))]
-
- # Extract the last element of '/sys/module/abc' in the array
- sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]
-
- # special case for vfio_pci (module is named vfio-pci,
- # but its .ko is named vfio_pci)
- sysfs_mods = map(lambda a:
- a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods)
-
- for mod in mods:
- if mod["Name"] in sysfs_mods:
- mod["Found"] = True
- except:
- pass
-
- # check if we have at least one loaded module
- if True not in [mod["Found"] for mod in mods]:
- print("Error - no supported modules(DPDK driver) are loaded")
- sys.exit(1)
-
- # change DPDK driver list to only contain drivers that are loaded
- dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]]
- print dpdk_drivers
-
-
-def has_driver(devices, dev_id):
- '''return true if a device is assigned to a driver. False otherwise'''
- return "Driver_str" in devices[dev_id]
-
-
-def get_pci_device_details(dev_id):
- '''This function gets additional details for a PCI device'''
- device = {}
-
- extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines()
-
- # parse lspci details
- for line in extra_info:
- if len(line) == 0:
- continue
- name, value = line.decode().split("\t", 1)
- name = name.strip(":") + "_str"
- device[name] = value
- # check for a unix interface name
- device["Interface"] = ""
- for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id):
- if "net" in dirs:
- device["Interface"] = \
- ",".join(os.listdir(os.path.join(base, "net")))
- break
- # check if a port is used for ssh connection
- device["Ssh_if"] = False
- device["Active"] = ""
-
- return device
-
-
-def get_nic_details():
- '''This function populates the "devices" dictionary. The keys used are
- the pci addresses (domain:bus:slot.func). The values are themselves
- dictionaries - one for each NIC.'''
- global dpdk_drivers
-
- # clear any old data
- devices = {}
- # first loop through and read details for all devices
- # request machine readable format, with numeric IDs
- dev = {}
- dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
- for dev_line in dev_lines:
- if len(dev_line) == 0:
- if dev["Class"][0:2] == NETWORK_BASE_CLASS:
- # convert device and vendor ids to numbers, then add to global
- dev["Vendor"] = int(dev["Vendor"], 16)
- dev["Device"] = int(dev["Device"], 16)
- # use dict to make copy of dev
- devices[dev["Slot"]] = dict(dev)
- else:
- name, value = dev_line.decode().split("\t", 1)
- dev[name.rstrip(":")] = value
-
- # check what is the interface if any for an ssh connection if
- # any to this host, so we can mark it later.
- ssh_if = []
- route = check_output(["ip", "-o", "route"])
- # filter out all lines for 169.254 routes
- route = "\n".join(filter(lambda ln: not ln.startswith("169.254"),
- route.decode().splitlines()))
- rt_info = route.split()
- for i in range(len(rt_info) - 1):
- if rt_info[i] == "dev":
- ssh_if.append(rt_info[i+1])
-
- # based on the basic info, get extended text details
- for d in devices.keys():
- # get additional info and add it to existing data
- devices[d] = devices[d].copy()
- devices[d].update(get_pci_device_details(d).items())
-
- for _if in ssh_if:
- if _if in devices[d]["Interface"].split(","):
- devices[d]["Ssh_if"] = True
- devices[d]["Active"] = "*Active*"
- break
-
- # add igb_uio to list of supporting modules if needed
- if "Module_str" in devices[d]:
- for driver in dpdk_drivers:
- if driver not in devices[d]["Module_str"]:
- devices[d]["Module_str"] = \
- devices[d]["Module_str"] + ",%s" % driver
- else:
- devices[d]["Module_str"] = ",".join(dpdk_drivers)
-
- # make sure the driver and module strings do not have any duplicates
- if has_driver(devices, d):
- modules = devices[d]["Module_str"].split(",")
- if devices[d]["Driver_str"] in modules:
- modules.remove(devices[d]["Driver_str"])
- devices[d]["Module_str"] = ",".join(modules)
-
- return devices
-
-
-def dev_id_from_dev_name(devices, dev_name, quite=False):
- '''Take a device "name" - a string passed in by user to identify a NIC
- device, and determine the device id - i.e. the domain:bus:slot.func - for
- it, which can then be used to index into the devices array'''
-
- # check if it's already a suitable index
- if dev_name in devices:
- return dev_name
- # check if it's an index just missing the domain part
- elif "0000:" + dev_name in devices:
- return "0000:" + dev_name
- else:
- # check if it's an interface name, e.g. eth1
- for d in devices.keys():
- if dev_name in devices[d]["Interface"].split(","):
- return devices[d]["Slot"]
- # if nothing else matches - error
+import sys
- if not quite:
- print("Unknown device: %s. "
- "Please specify device in \"bus:slot.func\" format" % dev_name)
+mrzcpd_root = "/opt/tsg/mrzcpd"
+mrzcpd_cfg = ""
+dpdk_bind = ""
+dpdk_driver = "vfio-pci"
+interfaces = []
+hwfile_location = '/var/run/mrzcpd/hwfile.json'
+hwinfo = {}
+
+
+def init():
+ global mrzcpd_root
+ global mrzcpd_cfg
+ global dpdk_bind
+ global dpdk_driver
+ global interfaces
+ global hwinfo
+
+ # Get driver mode
+ with open("/etc/sysconfig/mrzcpd", 'r') as drive_fp:
+ for line in drive_fp.readlines():
+ if re.search("DEFAULT_UIO_MODULE=*", line):
+ dpdk_driver = line.split('DEFAULT_UIO_MODULE=')[1]
+ if re.search("MRZCPD_ROOT=*", line):
+ mrzcpd_root = line.split('MRZCPD_ROOT=')[1]
+
+ # Get cfg path
+ mrzcpd_cfg = mrzcpd_root.replace("\n", "") + "/etc/mrglobal.conf"
+ dpdk_bind = mrzcpd_root.replace("\n", "") + "/bin/dpdk-devbind.py"
+
+ # Check driver mode
+ if dpdk_driver.strip() not in {"vfio-pci", "uio_pci_generic", "igb_uio"}:
+ print("driver mode invalid.", dpdk_driver)
sys.exit(1)
- return None
-
-def unbind_one(devices, dev_id, force):
- '''Unbind the device identified by "dev_id" from its current driver'''
- dev = devices[dev_id]
- if not has_driver(devices,dev_id):
- print("Notice: %s %s %s is not currently managed by any driver" %
- (dev["Slot"], dev["Device_str"], dev["Interface"]))
- return
-
- # prevent us disconnecting ourselves
- if dev["Ssh_if"] and not force:
- print("Warning: routing table indicates that interface %s is active. "
- "Skipping unbind" % dev_id)
- return
-
- # write to /sys to unbind
- filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]
- try:
- f = open(filename, "a")
- except :
- sys.exit("Error: unbind failed for %s - Cannot open %s" %(dev_id, filename))
- f.write(dev_id)
- f.close()
-
-def is_mlx_dev(dev,devices):
- dev_item = devices.get(dev)
- dev_driver = dev_item.get('Driver_str')
- if 'mlx5_core' == dev_driver:
- return True
- else:
- return False
-
-
-def bind_one(devices,dev_id, driver, force):
- '''Bind the device given by "dev_id" to the driver "driver". If the device
- is already bound to a different driver, it will be unbound first'''
- dev = devices[dev_id]
- saved_driver = None # used to rollback any unbind in case of failure
-
- # prevent disconnection of our ssh session
- if dev["Ssh_if"] and not force:
- print("Warning: routing table indicates that interface %s is active. "
- "Not modifying" % dev_id)
- return
-
- # unbind any existing drivers we don't want
- if has_driver(devices,dev_id):
- if dev["Driver_str"] == driver:
- print("Notice: %s already bound to driver %s, skipping" %
- (dev_id, driver))
- return
- saved_driver = dev["Driver_str"]
- unbind_one(devices,dev_id, force)
- dev["Driver_str"] = "" # clear driver string
-
- # For kernels >= 3.15 driver_override can be used to specify the driver
- # for a device rather than relying on the driver to provide a positive
- # match of the device. The existing process of looking up
- # the vendor and device ID, adding them to the driver new_id,
- # will erroneously bind other devices too which has the additional burden
- # of unbinding those devices
- if driver in dpdk_drivers:
- filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id
- if exists(filename):
- try:
- f = open(filename, "w")
- except :
- print("Error: bind failed for %s - Cannot open %s" % (dev_id, filename))
- return
- try:
- f.write("%s" % driver)
- f.close()
- except :
- print("Error: bind failed for %s - Cannot write driver %s " % (dev_id, driver))
- return
- # For kernels < 3.15 use new_id to add PCI id's to the driver
- else:
- filename = "/sys/bus/pci/drivers/%s/new_id" % driver
- try:
- f = open(filename, "w")
- except :
- print("Error: bind failed for %s - Cannot open %s" % (dev_id, filename))
- return
- try:
- # Convert Device and Vendor Id to int to write to new_id
- f.write("%04x %04x" % (int(dev["Vendor"], 16),
- int(dev["Device"], 16)))
- f.close()
- except :
- print("Error: bind failed for %s - Cannot write new PCI ID to " "driver %s" % (dev_id, driver))
- return
-
- # do the bind by writing to /sys
- filename = "/sys/bus/pci/drivers/%s/bind" % driver
- try:
- f = open(filename, "a")
- except :
- print("Error: bind failed for %s - Cannot open %s"% (dev_id, filename))
- if saved_driver is not None: # restore any previous driver
- bind_one(devices,dev_id, saved_driver, force)
- return
- try:
- f.write(dev_id)
- f.close ()
- except :
- # for some reason, closing dev_id after adding a new PCI ID to new_id
- # results in IOError. however, if the device was successfully bound,
- # we don't care for any errors and can safely ignore IOError
- tmp = get_pci_device_details(dev_id)
- if "Driver_str" in tmp and tmp["Driver_str"] == driver:
- return
- print("Error: bind failed for %s - Cannot bind to driver %s"% (dev_id, driver))
- if saved_driver is not None: # restore any previous driver
- bind_one(devices,dev_id, saved_driver, force)
- return
-
- # For kernels > 3.15 driver_override is used to bind a device to a driver.
- # Before unbinding it, overwrite driver_override with empty string so that
- # the device can be bound to any other driver
- filename = "/sys/bus/pci/devices/%s/driver_override" % dev_id
- if exists(filename):
- try:
- f = open(filename, "w")
- except :
- sys.exit("Error: unbind failed for %s - Cannot open %s"% (dev_id, filename))
- try:
- f.write("\00")
- f.close()
- except :
- sys.exit("Error: unbind failed for %s - Cannot write %s"% (dev_id, filename))
-
-def unbind_all(devices, dev_list, force=False):
- """Unbind method, takes a list of device locations"""
- dev_list = map(lambda x: dev_id_from_dev_name(devices, x), dev_list)
- for d in dev_list:
- unbind_one(devices, d, force)
-
-
-def bind_all(devices, dev_list, driver, force=False):
- """Bind method, takes a list of device locations"""
-
- dev_list = map(lambda x: dev_id_from_dev_name(devices, x), dev_list)
- for d in dev_list:
- if is_mlx_dev(d,devices) == False:
- bind_one(devices, d, driver, force)
-
- # when binding devices to a generic driver (i.e. one that doesn't have a
- # PCI ID table), some devices that are not bound to any other driver could
- # be bound even if no one has asked them to. hence, we check the list of
- # drivers again, and see if some of the previously-unbound devices were
- # erroneously bound.
- for d in devices.keys():
- # skip devices that were already bound or that we know should be bound
- if "Driver_str" in devices[d] or d in dev_list:
- continue
-
- # update information about this device
- devices[d] = dict(devices[d].items() +
- get_pci_device_details(d).items())
-
- # check if updated information indicates that the device was bound
- if "Driver_str" in devices[d]:
- unbind_one(devices, d, force)
-
-def hwfile_encode(location):
- devices = get_nic_details()
- _dirname = os.path.dirname(location)
- if not os.path.exists(_dirname):
- os.makedirs(_dirname)
-
- with open(location, 'w') as json_fp:
- json.dump(devices, json_fp)
- return
-
-def hwfile_decode(location):
- with open(location, 'r') as json_fp:
- devices = json.load(json_fp)
- return devices
-
-def setup_argv_parser():
-
- parser = argparse.ArgumentParser(description='Marsio ZeroCopy Tools -- Network Interface Card Tools',
- version = 'Marsio ZeroCopy Tools Suite 4.1')
-
- parser.add_argument('--hwfile', help = 'Hardware file location', nargs=1, metavar = 'FILE')
- parser.add_argument('--action', help = 'Action, bind modules or unbind modules, or dump hwfiles',
- choices=['bind','unbind','dump'])
- parser.add_argument('--gcfg', help = 'Global configure file location', nargs=1, metavar = 'FILE')
- parser.add_argument('interfaces', metavar='INTERFACES', help = 'symbol of interfaces', nargs ='*')
- return parser.parse_args()
-
-def global_configure_parser(g_file):
- import ConfigParser
- config = ConfigParser.ConfigParser()
- config.read(g_file)
- return config.get('device','device', 0).split(',')
-
-def nics_bind(hwinfo, niclist):
- devices_info = get_nic_details()
- print dpdk_drivers
- bind_all(devices_info, niclist, dpdk_drivers[0], True)
- return
-
-def nics_unbind(hwinfo, niclist):
- devices_info = get_nic_details()
- dev_addr_list = map(lambda x: dev_id_from_dev_name(hwinfo, x), niclist)
- kmod_list = map(lambda x: hwinfo[x]["Driver_str"], dev_addr_list)
- map(lambda x,y: bind_one(devices_info, x, y, True), dev_addr_list, kmod_list)
- return
+ # Get dev list from mrglobal
+ config = configparser.ConfigParser()
+ config.read(mrzcpd_cfg)
+ interfaces = config.get('device', 'device').split(',')
+
+ # hwfile decode
+ with open(hwfile_location, 'r') as json_fp:
+ json_info = json.load(json_fp)
+ for item in json_info:
+ dev_info = {}
+ dev_name = item.get('Interface', None)
+ dev_info['pci'] = item.get('Slot_str', None)
+ dev_info['driver'] = item.get('Driver_str', None)
+ hwinfo[dev_name] = dev_info
+
+
+def module_load():
+ # vfio_pci
+ if dpdk_driver.strip() == "vfio-pci".strip():
+ if os.system("modprobe vfio") or os.system("echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode") or os.system("modprobe vfio_pci"):
+ print("modprode vfio err")
+ sys.exit(1)
+
+ # uio_pci_generic
+ if dpdk_driver.strip() == "uio_pci_generic".strip():
+ if os.system("modprobe uio_pci_generic"):
+ print("modprode uio_pci_generic err")
+ sys.exit(1)
+
+ # igb_uio
+ if dpdk_driver.strip() == "igb_uio".strip():
+ if os.system("modprobe igb_uio"):
+ print("modprode igb_uio err")
+ sys.exit(1)
+
+
+def nic_bind():
+ for d in interfaces:
+ if d in hwinfo and hwinfo.get(d).get('driver') != 'mlx5_core':
+ bind_cmd = dpdk_bind + ' --bind=' + \
+ dpdk_driver.replace("\n", " ") + hwinfo.get(d).get('pci')
+ print("bind cmd:", bind_cmd)
+ if os.system(bind_cmd):
+ print("bind dev err")
+ sys.exit(1)
def main():
- r_options = setup_argv_parser()
- hwfile_location = r_options.hwfile[0] if r_options.hwfile else default_hwfile_location
- gcfg_location = r_options.gcfg[0] if r_options.gcfg else default_gcfg_location
- niclist = r_options.interfaces if r_options.interfaces else global_configure_parser(gcfg_location)
-
- if r_options.action == 'dump':
- return hwfile_encode(hwfile_location)
-
- if not os.path.exists(hwfile_location):
- print('Hardware information file %s is not exists.' % hwfile_location)
- sys.exit(1)
- if not os.path.exists(gcfg_location):
- print('Global configure file %s is not exists.' % gcfg_location)
- sys.exit(1)
-
- hwinfo = hwfile_decode(hwfile_location)
- check_modules()
-
- niclist = [ d for d in niclist if dev_id_from_dev_name(hwinfo, d, quite=True)]
- print niclist
+ # module load
+ module_load()
+ # bind dev
+ nic_bind()
- if r_options.action == 'bind':
- return nics_bind(hwinfo, niclist)
- if r_options.action == 'unbind':
- return nics_unbind(hwinfo, niclist)
- return
if __name__ == "__main__":
- main() \ No newline at end of file
+ init()
+ main()
diff --git a/tools/systemd/CMakeLists.txt b/tools/systemd/CMakeLists.txt
index ea91982..2cb6de4 100644
--- a/tools/systemd/CMakeLists.txt
+++ b/tools/systemd/CMakeLists.txt
@@ -1,22 +1,25 @@
-configure_file(mrenv.service.in mrenv.service)
+configure_file(mrzcpd-hwdb-setup.service.in mrzcpd-hwdb-setup.service)
+configure_file(mrzcpd-hugepages-setup.service.in mrzcpd-hugepages-setup.service)
configure_file(mrzcpd.service.in mrzcpd.service)
configure_file(mrtunnat.service.in mrtunnat.service)
configure_file(mrapm_device.service.in mrapm_device.service)
configure_file(mrapm_stream.service.in mrapm_stream.service)
-install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrenv.service
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrzcpd-hwdb-setup.service
DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
-install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrzcpd.service
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrzcpd-hugepages-setup.service
DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
-
-install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrtunnat.service
+
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrzcpd.service
DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
-
-install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrapm_device.service
+
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrtunnat.service
DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
-install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrapm_stream.service
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrapm_device.service
DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
-
-install(PROGRAMS mrenv-script DESTINATION bin COMPONENT Program) \ No newline at end of file
+
+install(FILES ${CMAKE_BINARY_DIR}/tools/systemd/mrapm_stream.service
+ DESTINATION ${MR_INSTALL_SYSUNITDIR} COMPONENT Program)
+
diff --git a/tools/systemd/mrenv-script b/tools/systemd/mrenv-script
deleted file mode 100644
index d8a598a..0000000
--- a/tools/systemd/mrenv-script
+++ /dev/null
@@ -1,441 +0,0 @@
-#!/bin/bash
-#
-
-if [ -z "$MRZCPD_ROOT" ]; then
- MRZCPD_ROOT=$(pkg-config mrzcpd --variable=prefix)
-fi
-
-if [ -z "$HUGEPAGE_NUM_2M" ]; then
- HUGEPAGE_NUM_2M=0
-fi
-
-if [ -z "$HUGEPAGE_NUM_1G" ]; then
- HUGEPAGE_NUM_1G=0
-fi
-
-if [ -z "$PCI_ADDR_IXGBE" ]; then
- PCI_ADDR_IXGBE=""
-fi
-
-if [ -z "$PCI_ADDR_IGB" ]; then
- PCI_ADDR_IGB=""
-fi
-
-if [ -z "$DEFAULT_UIO_MODULE" ]; then
- DEFAULT_UIO_MODULE="uio_pci_generic"
-fi
-
-if [ -z "$PCI_ADDR_IGB" ] && [ -z "$PCI_ADDR_IXGBE" ]; then
- NIC_BIND_AUTO=1
-fi
-
-MODULE_PATH=$MRZCPD_ROOT/lib/modules/$(uname -r)/extra/dpdk
-BIN_PATH=$MRZCPD_ROOT/bin/
-KNI_MODULE=rte_kni
-UIO_MODULE=igb_uio
-
-NR_HUGEPAGE_FILE_2M=/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
-NR_HUGEPAGE_FILE_1G=/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
-HUGEPAGE_PATH_2M=$(readlink -fsm /run/mrzcpd/huge_2M)
-HUGEPAGE_PATH_1G=$(readlink -fsm /run/mrzcpd/huge_1G)
-
-DAEMON=$BIN_PATH/mrzcpd
-NICTOOL=$BIN_PATH/mrtools-devinfo
-NICBIND=$BIN_PATH/mrtools-devbind
-KNI_MODULE_FILENAME=$KNI_MODULE.ko
-UIO_MODULE_FILENAME=$UIO_MODULE.ko
-NICBIND_CFG=$MRZCPD_ROOT/etc/mrglobal.conf
-
-function module_unload_kni()
-{
- lsmod | grep -s $KNI_MODULE > /dev/null 2>&1
- [ $? -eq 0 ] && rmmod $KNI_MODULE 2>&1
- [ ! $? -eq 0 ] && return 1
- return 0
-}
-
-function module_load_kni()
-{
- if [ ! -e $MODULE_PATH/$KNI_MODULE_FILENAME ]; then
- echo -n "$KNI_MODULE_FILENAME does not existed. "
- return 1
- fi
-
- module_unload_kni
- insmod $MODULE_PATH/$KNI_MODULE_FILENAME > /dev/null 2>&1
- [ ! $? -eq 0 ] && echo -n " $MODULE_PATH/$KNI_MODULE_FILENAME load failure." && return 1
- return 0
-}
-
-function module_unload_igb_uio()
-{
- lsmod | grep -s $UIO_MODULE > /dev/null 2>&1
- [ ! $? -eq 0 ] && return 0
-
- rmmod $UIO_MODULE
- return $?
-}
-
-function module_load_igb_uio()
-{
- modprobe igb_uio
- return $?
-}
-
-function module_unload_vfio_pci()
-{
- lsmod | grep -s vfio_pci > /dev/null 2>&1
- [ ! $? -eq 0 ] && return 0
-
- rmmod vfio_pci
- return $?
-}
-
-function module_load_vfio_pci()
-{
- modprobe vfio
- [ ! $? -eq 0 ] && echo "failed at modprobe vfio" && return 1
-
- echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
- modprobe vfio_pci
- return $?
-}
-
-function module_load_uio_pci_generic()
-{
- modprobe uio_pci_generic
- return $?
-}
-
-function module_unload_uio_pci_generic()
-{
- lsmod | grep -s uio_pci_generic > /dev/null 2>&1
- [ ! $? -eq 0 ] && return 0
-
- rmmod uio_pci_generic
- return $?
-}
-
-function huge_release_1G()
-{
- cat /proc/mounts | grep "$HUGEPAGE_PATH_1G" > /dev/null
- grep -s "$HUGEPAGE_PATH_1G" /proc/mounts > /dev/null
-
- if [ $? -eq 0 ]; then
- umount $HUGEPAGE_PATH_1G > /dev/null
- [ ! $? -eq 0 ] && echo "umount 1G hugepage failure, maybe in use" && return 1
- fi
-
- if [ -d $HUGEPAGE_PATH_1G ] ; then
- rm -R $HUGEPAGE_PATH_1G
- [ ! $? -eq 0 ] && echo "Cannot delete 2M hugepage" && return 1
- fi
-
- if [ $HUGEPAGE_NUM_1G -ne 0 ]; then
- echo -n 0 > $NR_HUGEPAGE_FILE_1G
- fi
-
- return 0
-}
-
-function huge_release_2M()
-{
- cat /proc/mounts | grep "$HUGEPAGE_PATH_2M" > /dev/null
- grep -s "$HUGEPAGE_PATH_2M" /proc/mounts > /dev/null
-
- if [ $? -eq 0 ]; then
- umount $HUGEPAGE_PATH_2M > /dev/null
- [ ! $? -eq 0 ] && echo "umount 2M hugepage failure, maybe in use" && return 1
- fi
-
- if [ -d $HUGEPAGE_PATH_2M ] ; then
- rm -R $HUGEPAGE_PATH_2M
- [ ! $? -eq 0 ] && echo "Cannot delete 2M hugepage" && return 1
- fi
-
- if [ $HUGEPAGE_NUM_2M -ne 0 ]; then
- echo -n 0 > $NR_HUGEPAGE_FILE_2M
- fi
-
- return 0
-}
-
-function huge_alloc_1G()
-{
- if [ ! -e $NR_HUGEPAGE_FILE_1G ]; then
- return 1
- fi
-
- echo -n $HUGEPAGE_NUM_1G > $NR_HUGEPAGE_FILE_1G
- [ $? -eq 0 ] && return 0
- return 1
-}
-
-function huge_alloc_2M()
-{
- if [ ! -e $NR_HUGEPAGE_FILE_2M ]; then
- return 1
- fi
-
- echo -n $HUGEPAGE_NUM_2M > $NR_HUGEPAGE_FILE_2M
- [ $? -eq 0 ] && return 0
- return 1
-}
-
-function huge_mount_1G()
-{
- if [ ! -e $NR_HUGEPAGE_FILE_1G ]; then
- return 0
- fi
-
- SIZE_1G=$(cat $NR_HUGEPAGE_FILE_1G)
- if [ $SIZE_1G -eq 0 ]; then
- return 0
- fi
-
- mkdir -p $HUGEPAGE_PATH_1G
- mount -t hugetlbfs nodev -o pagesize=1G $HUGEPAGE_PATH_1G
- [ $? -eq 0 ] && return 0
- return 1
-}
-
-function huge_mount_2M()
-{
- if [ ! -e $NR_HUGEPAGE_FILE_2M ]; then
- return 0
- fi
-
- SIZE_2M=$(cat $NR_HUGEPAGE_FILE_2M)
- if [ $SIZE_2M -eq 0 ]; then
- return 0
- fi
-
- mkdir -p $HUGEPAGE_PATH_2M
- mount -t hugetlbfs nodev -o pagesize=2M $HUGEPAGE_PATH_2M
- [ $? -eq 0 ] && return 0
- return 1
-}
-
-function huge_alloc()
-{
- if [ ! $HUGEPAGE_NUM_1G -eq 0 ]; then
- #huge_release_1G
- #huge_alloc_1G
- huge_mount_1G
- fi
-
- if [ ! $HUGEPAGE_NUM_2M -eq 0 ]; then
- #huge_release_2M
- #huge_alloc_2M
- huge_mount_2M
- fi
-
- if [ $HUGEPAGE_NUM_1G -eq 0 ]; then
- #huge_release_1G
- huge_mount_1G
- fi
-
- if [ $HUGEPAGE_NUM_2M -eq 0 ]; then
- #huge_release_2M
- huge_mount_2M
- fi
-
- return $?
-}
-
-function huge_release()
-{
- huge_release_1G
- [ ! $? -eq 0 ] && return 1
- huge_release_2M
- [ ! $? -eq 0 ] && return 1
- return 0
-}
-
-function nic_unbind_ixgbe()
-{
- OLDIFS=$IFS; IFS=,
- for ITER_PCI_ADDR in $PCI_ADDR_IXGBE; do
- $NICTOOL --force -b ixgbe $ITER_PCI_ADDR
- [ ! $? -eq 0 ] && return 1
- done
- IFS=$OLDIFS
- return 0
-}
-
-function nic_unbind_igb()
-{
- OLDIFS=$IFS; IFS=,
- for ITER_PCI_ADDR in $PCI_ADDR_IGB; do
- $NICTOOL --force -b igb $ITER_PCI_ADDR
- [ ! $? -eq 0 ] && return 1
- done
- IFS=$OLDIFS
- return 0
-}
-
-function nic_bind_ixgbe()
-{
- OLDIFS=$IFS; IFS=,
- for ITER_PCI_ADDR in $PCI_ADDR_IXGBE; do
- $NICTOOL --force -b igb_uio $ITER_PCI_ADDR
- [ ! $? -eq 0 ] && return 1
- done
- IFS=$OLDIFS
- return 0
-}
-
-function nic_bind_igb()
-{
- OLDIFS=$IFS; IFS=,
- for ITER_PCI_ADDR in $PCI_ADDR_IGB; do
- $NICTOOL --force -b igb_uio $ITER_PCI_ADDR
- [ ! $? -eq 0 ] && return 1
- done
- IFS=$OLDIFS
- return 0
-}
-
-function nic_bind_auto()
-{
- if [ $NIC_BIND_AUTO -eq 0 ]; then
- return 0
- fi
-
- $NICBIND --action dump --gcfg $NICBIND_CFG
- [ ! $? -eq 0 ] && return 1
- $NICBIND --action bind --gcfg $NICBIND_CFG
- [ ! $? -eq 0 ] && return 1
-
- return 0
-}
-
-function nic_unbind_auto()
-{
- if [ $NIC_BIND_AUTO -eq 0 ]; then
- return 0
- fi
-
- $NICBIND --action unbind --gcfg $NICBIND_CFG
- [ ! $? -eq 0 ] && return 1
- return 0
-}
-
-function check_app_exist()
-{
- APP_USE_HUGE_2M=$(lsof -t $HUGEPAGE_PATH_2M 2>/dev/null)
- RET1=$?
- APP_USE_HUGE_1G=$(lsof -t $HUGEPAGE_PATH_1G 2>/dev/null)
- RET2=$?
-
- return $RET1 || $RET2
-}
-
-function kill_app()
-{
- fuser -km $HUGEPAGE_PATH_2M
- fuser -km $HUGEPAGE_PATH_1G
- return 0
-}
-
-function marsiod_stop()
-{
- kill_app
- return 0
-}
-
-function marsiod_start()
-{
- echo 0 > /proc/sys/kernel/randomize_va_space
- return 0
-}
-
-function module_unload()
-{
- echo "unload module"
-
- module_unload_igb_uio
- module_unload_uio_pci_generic
- module_unload_vfio_pci
-}
-
-function module_load()
-{
- if [ "$DEFAULT_UIO_MODULE" == "uio_pci_generic" ]; then
- module_load_uio_pci_generic
- return $?
- fi
-
- if [ "$DEFAULT_UIO_MODULE" == "igb_uio" ]; then
- module_load_igb_uio
- return $?
- fi
-
- if [ "$DEFAULT_UIO_MODULE" == "vfio_pci" ]; then
- module_load_vfio_pci
- return $?
- fi
-
- return 0
-}
-
-function start()
-{
- # Require Step, if failure, all step should be stop.
- module_load
- [ ! $? -eq 0 ] && return 1
- huge_alloc
- [ ! $? -eq 0 ] && return 1
- nic_bind_ixgbe
- [ ! $? -eq 0 ] && return 1
- nic_bind_igb
- [ ! $? -eq 0 ] && return 1
- nic_bind_auto
- [ ! $? -eq 0 ] && return 1
- marsiod_start
- [ ! $? -eq 0 ] && return 1
- return 0
-}
-
-function stop()
-{
- marsiod_stop
- #[ ! $? -eq 0 ] && return 1
- #huge_release
- [ ! $? -eq 0 ] && return 1
- nic_unbind_ixgbe
- [ ! $? -eq 0 ] && return 1
- nic_unbind_igb
- [ ! $? -eq 0 ] && return 1
- nic_unbind_auto
- [ ! $? -eq 0 ] && return 1
- module_unload
- [ ! $? -eq 0 ] && return 1
- return 0
-}
-
-function restart()
-{
- stop
- start $*
-}
-
-action=$1
-shift
-
-case $action in
- start)
- start $*
- ;;
- stop)
- stop
- ;;
- restart)
- restart $*
- ;;
- *)
- echo "Usage: service $0 {start|stop|restart}"
- exit 1
-esac
-
-exit $?
diff --git a/tools/systemd/mrenv.service.in b/tools/systemd/mrenv.service.in
deleted file mode 100644
index 69f0dc0..0000000
--- a/tools/systemd/mrenv.service.in
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=Setup/Unsetup mrzcpd runtime environment
-After=network.target
-Conflicts=dev-hugepages.mount
-
-[Service]
-Type=oneshot
-EnvironmentFile=/etc/sysconfig/mrzcpd
-ExecStart=@MR_INSTALL_BINDIR@/mrenv-script start
-ExecStop=@MR_INSTALL_BINDIR@/mrenv-script stop
-RemainAfterExit=yes
-
-[Install]
-WantedBy=multi-user.target \ No newline at end of file
diff --git a/tools/systemd/mrzcpd-hugepages-setup.service.in b/tools/systemd/mrzcpd-hugepages-setup.service.in
new file mode 100644
index 0000000..2973a09
--- /dev/null
+++ b/tools/systemd/mrzcpd-hugepages-setup.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=Setup hugepages
+
+[Service]
+Type=oneshot
+ExecStartPre=mkdir -p /var/run/mrzcpd/huge_pages
+ExecStart=python3 @MR_INSTALL_BINDIR@/dpdk-hugepages.py -m
+RemainAfterExit=yes
+ExecStop=umount /var/run/mrzcpd/huge_pages
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/tools/systemd/mrzcpd-hwdb-setup.service.in b/tools/systemd/mrzcpd-hwdb-setup.service.in
new file mode 100644
index 0000000..8a51487
--- /dev/null
+++ b/tools/systemd/mrzcpd-hwdb-setup.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=Setup hwdb
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=python3 @MR_INSTALL_BINDIR@/dpdk-devbind.py --status-dev net --dump /var/run/mrzcpd/hwfile.json
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/tools/systemd/mrzcpd.service.in b/tools/systemd/mrzcpd.service.in
index 3943a0b..2521991 100644
--- a/tools/systemd/mrzcpd.service.in
+++ b/tools/systemd/mrzcpd.service.in
@@ -1,15 +1,15 @@
[Unit]
Description=Marsio ZeroCopy Driver Daemon
-Requires=mrenv.service
-After=mrenv.service
+Requires=mrzcpd-hugepages-setup.service mrzcpd-hwdb-setup.service k3s.service
+After=mrzcpd-hugepages-setup.service mrzcpd-hwdb-setup.service k3s.service
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
Environment=MLX5_GLUE_PATH=@MR_INSTALL_LIBDIR@
EnvironmentFile=/etc/sysconfig/mrzcpd
+ExecStartPre=python3 @MR_INSTALL_BINDIR@/devbind.py
ExecStart=@MR_INSTALL_BINDIR@/mrzcpd -c @MR_INSTALL_SYSCONFDIR@/mrglobal.conf
-ExecStopPost=/bin/bash -c 'rm -f /run/mrzcpd/huge_2M/rtemap_*'
-ExecStopPost=/bin/bash -c 'rm -f /run/mrzcpd/huge_1G/rtemap_*'
+ExecStopPost=/bin/bash -c 'rm -f /run/mrzcpd/huge_pages/rtemap_*'
ExecStopPost=/usr/bin/rm -f /run/.rte_config
ExecStopPost=/usr/bin/rm -f /run/.rte_hugepage_info
ExecStopPost=/usr/bin/rm -rf /run/.dpdk