diff options
| author | songyanchao <[email protected]> | 2023-03-16 10:03:57 +0000 |
|---|---|---|
| committer | songyanchao <[email protected]> | 2023-03-16 10:23:26 +0000 |
| commit | c1023ce42bd9081dd35809be39071fc968ca799a (patch) | |
| tree | f634ae1dd73c30d03ee2a586a6ec6dedb90455f9 | |
| parent | dfbfd088b56614ea09aa976633f10a99da2a3c17 (diff) | |
✨ feat(DPISDN-2): 将 mrenv 拆分为 hugepages setup 和 hwdb setup 两个servicev4.6.18-20230317
将 mrenv 拆分为 hugepages setup 和 hwdb setup 两个service
| -rw-r--r-- | cmake/InstallDPDK.cmake | 4 | ||||
| -rw-r--r-- | tools/devbind/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | tools/devbind/devbind.py | 547 | ||||
| -rw-r--r-- | tools/systemd/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | tools/systemd/mrenv-script | 441 | ||||
| -rw-r--r-- | tools/systemd/mrenv.service.in | 14 | ||||
| -rw-r--r-- | tools/systemd/mrzcpd-hugepages-setup.service.in | 13 | ||||
| -rw-r--r-- | tools/systemd/mrzcpd-hwdb-setup.service.in | 11 | ||||
| -rw-r--r-- | tools/systemd/mrzcpd.service.in | 8 |
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 |
