Redhat and small system support
Initial 17.10 commit Final 17.07 cleanup, 17.10 next Added CentOS grub support, this should complete the CentOS support Added Centos install/unistall Added TCP parameters. Change-Id: I064e3a4118969ac36e62924a6a3f8a98f132ba60 Signed-off-by: John DeNisco <jdenisco@cisco.com> Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
committed by
Dave Barach
parent
35830af800
commit
68b0ee3a38
202
extras/vpp_config/LICENSE.txt
Normal file
202
extras/vpp_config/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
515
extras/vpp_config/README.rst
Normal file
515
extras/vpp_config/README.rst
Normal file
File diff suppressed because it is too large
Load Diff
0
extras/vpp_config/__init__.py
Normal file
0
extras/vpp_config/__init__.py
Normal file
15
extras/vpp_config/data/80-vpp.conf.template
Normal file
15
extras/vpp_config/data/80-vpp.conf.template
Normal file
@@ -0,0 +1,15 @@
|
||||
# Number of 2MB hugepages desired
|
||||
vm.nr_hugepages=1024
|
||||
|
||||
# Must be greater than or equal to (2 * vm.nr_hugepages).
|
||||
vm.max_map_count=3096
|
||||
|
||||
# All groups allowed to access hugepages
|
||||
vm.hugetlb_shm_group=0
|
||||
|
||||
# Shared Memory Max must be greator or equal to the total size of hugepages.
|
||||
# For 2MB pages, TotalHugepageSize = vm.nr_hugepages * 2 * 1024 * 1024
|
||||
# If the existing kernel.shmmax setting (cat /sys/proc/kernel/shmmax)
|
||||
# is greater than the calculated TotalHugepageSize then set this parameter
|
||||
# to current shmmax value.
|
||||
kernel.shmmax=2147483648
|
||||
23
extras/vpp_config/data/auto-config.yaml
Normal file
23
extras/vpp_config/data/auto-config.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
metadata:
|
||||
system_config_file: /vpp/vpp-config/configs/system-config.yaml
|
||||
version: 0.1
|
||||
nodes:
|
||||
DUT1:
|
||||
cpu:
|
||||
grub_config_file: /vpp/vpp-config/dryrun/default/grub
|
||||
reserve_vpp_main_core: true
|
||||
total_other_cpus: 0
|
||||
total_vpp_cpus: 2
|
||||
host: localhost
|
||||
hugepages:
|
||||
hugepage_config_file: /vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf
|
||||
total: '1024'
|
||||
interfaces:
|
||||
tcp:
|
||||
active_open_sessions: 0
|
||||
passive_open_sessions: 0
|
||||
type: DUT
|
||||
vpp:
|
||||
startup_config_file: /vpp/vpp-config/dryrun/vpp/startup.conf
|
||||
unix:
|
||||
interactive: false
|
||||
34
extras/vpp_config/data/grub.template
Normal file
34
extras/vpp_config/data/grub.template
Normal file
@@ -0,0 +1,34 @@
|
||||
# If you change this file, run 'update-grub' afterwards to update
|
||||
# /boot/grub/grub.cfg.
|
||||
# For full documentation of the options in this file, see:
|
||||
# info -f grub -n 'Simple configuration'
|
||||
|
||||
GRUB_DEFAULT=0
|
||||
#GRUB_HIDDEN_TIMEOUT=0
|
||||
GRUB_HIDDEN_TIMEOUT_QUIET=true
|
||||
GRUB_TIMEOUT=2
|
||||
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
|
||||
GRUB_CMDLINE_LINUX_DEFAULT=""
|
||||
GRUB_CMDLINE_LINUX=""
|
||||
|
||||
# Uncomment to enable BadRAM filtering, modify to suit your needs
|
||||
# This works with Linux (no patch required) and with any kernel that obtains
|
||||
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
|
||||
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
|
||||
|
||||
# Uncomment to disable graphical terminal (grub-pc only)
|
||||
#GRUB_TERMINAL=console
|
||||
|
||||
# The resolution used on graphical terminal
|
||||
# note that you can use only modes which your graphic card supports via VBE
|
||||
# you can see them in real GRUB with the command `vbeinfo'
|
||||
#GRUB_GFXMODE=640x480
|
||||
|
||||
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
|
||||
#GRUB_DISABLE_LINUX_UUID=true
|
||||
|
||||
# Uncomment to disable generation of recovery mode menu entries
|
||||
#GRUB_DISABLE_RECOVERY="true"
|
||||
|
||||
# Uncomment to get a beep at grub start
|
||||
#GRUB_INIT_TUNE="480 440 1"
|
||||
123
extras/vpp_config/data/startup.conf.template
Normal file
123
extras/vpp_config/data/startup.conf.template
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
unix {{
|
||||
{unix}
|
||||
log /tmp/vpp.log
|
||||
full-coredump
|
||||
cli-listen /run/vpp/cli.sock
|
||||
}}
|
||||
|
||||
api-trace {{
|
||||
on
|
||||
}}
|
||||
|
||||
cpu {{
|
||||
{cpu}
|
||||
scheduler-policy fifo
|
||||
scheduler-priority 50
|
||||
|
||||
## In the VPP there is one main thread and optionally the user can create worker(s)
|
||||
## The main thread and worker thread(s) can be pinned to CPU core(s) manually or automatically
|
||||
|
||||
## Manual pinning of thread(s) to CPU core(s)
|
||||
|
||||
## Set logical CPU core where main thread runs
|
||||
# main-core 1
|
||||
|
||||
## Set logical CPU core(s) where worker threads are running
|
||||
# corelist-workers 2-3,18-19
|
||||
|
||||
## Automatic pinning of thread(s) to CPU core(s)
|
||||
|
||||
## Sets number of CPU core(s) to be skipped (1 ... N-1)
|
||||
## Skipped CPU core(s) are not used for pinning main thread and working thread(s).
|
||||
## The main thread is automatically pinned to the first available CPU core and worker(s)
|
||||
## are pinned to next free CPU core(s) after core assigned to main thread
|
||||
# skip-cores 4
|
||||
|
||||
## Specify a number of workers to be created
|
||||
## Workers are pinned to N consecutive CPU cores while skipping "skip-cores" CPU core(s)
|
||||
## and main thread's CPU core
|
||||
# workers 2
|
||||
|
||||
## Set scheduling policy and priority of main and worker threads
|
||||
|
||||
## Scheduling policy options are: other (SCHED_OTHER), batch (SCHED_BATCH)
|
||||
## idle (SCHED_IDLE), fifo (SCHED_FIFO), rr (SCHED_RR)
|
||||
# scheduler-policy fifo
|
||||
|
||||
## Scheduling priority is used only for "real-time policies (fifo and rr),
|
||||
## and has to be in the range of priorities supported for a particular policy
|
||||
# scheduler-priority 50
|
||||
}}
|
||||
|
||||
dpdk {{
|
||||
{devices}
|
||||
|
||||
## Change default settings for all intefaces
|
||||
# dev default {{
|
||||
## Number of receive queues, enables RSS
|
||||
## Default is 1
|
||||
# num-rx-queues 3
|
||||
|
||||
## Number of transmit queues, Default is equal
|
||||
## to number of worker threads or 1 if no workers treads
|
||||
# num-tx-queues 3
|
||||
|
||||
## Number of descriptors in transmit and receive rings
|
||||
## increasing or reducing number can impact performance
|
||||
## Default is 1024 for both rx and tx
|
||||
# num-rx-desc 512
|
||||
# num-tx-desc 512
|
||||
|
||||
## VLAN strip offload mode for interface
|
||||
## Default is off
|
||||
# vlan-strip-offload on
|
||||
# }}
|
||||
|
||||
## Whitelist specific interface by specifying PCI address
|
||||
# dev 0000:02:00.0
|
||||
|
||||
## Whitelist specific interface by specifying PCI address and in
|
||||
## addition specify custom parameters for this interface
|
||||
# dev 0000:02:00.1 {{
|
||||
# num-rx-queues 2
|
||||
# }}
|
||||
|
||||
## Specify bonded interface and its slaves via PCI addresses
|
||||
##
|
||||
## Bonded interface in XOR load balance mode (mode 2) with L3 and L4 headers
|
||||
# vdev eth_bond0,mode=2,slave=0000:02:00.0,slave=0000:03:00.0,xmit_policy=l34
|
||||
# vdev eth_bond1,mode=2,slave=0000:02:00.1,slave=0000:03:00.1,xmit_policy=l34
|
||||
##
|
||||
## Bonded interface in Active-Back up mode (mode 1)
|
||||
# vdev eth_bond0,mode=1,slave=0000:02:00.0,slave=0000:03:00.0
|
||||
# vdev eth_bond1,mode=1,slave=0000:02:00.1,slave=0000:03:00.1
|
||||
|
||||
## Change UIO driver used by VPP, Options are: igb_uio, vfio-pci
|
||||
## and uio_pci_generic (default)
|
||||
# uio-driver vfio-pci
|
||||
|
||||
## Disable mutli-segment buffers, improves performance but
|
||||
## disables Jumbo MTU support
|
||||
# no-multi-seg
|
||||
|
||||
## Increase number of buffers allocated, needed only in scenarios with
|
||||
## large number of interfaces and worker threads. Value is per CPU socket.
|
||||
## Default is 16384
|
||||
# num-mbufs 128000
|
||||
|
||||
## Change hugepages allocation per-socket, needed only if there is need for
|
||||
## larger number of mbufs. Default is 256M on each detected CPU socket
|
||||
# socket-mem 2048,2048
|
||||
}}
|
||||
|
||||
# Adjusting the plugin path depending on where the VPP plugins are:
|
||||
#plugins
|
||||
#{{
|
||||
# path /home/bms/vpp/build-root/install-vpp-native/vpp/lib64/vpp_plugins
|
||||
#}}
|
||||
|
||||
# Alternate syntax to choose plugin path
|
||||
#plugin_path /home/bms/vpp/build-root/install-vpp-native/vpp/lib64/vpp_plugins
|
||||
|
||||
{tcp}
|
||||
73
extras/vpp_config/scripts/clean.sh
Executable file
73
extras/vpp_config/scripts/clean.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash -x
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
check_os()
|
||||
{
|
||||
|
||||
# perform some very rudimentary platform detection
|
||||
lsb_dist=''
|
||||
if command_exists lsb_release; then
|
||||
lsb_dist="$(lsb_release -si)"
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then
|
||||
lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")"
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then
|
||||
lsb_dist='fedora'
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/centos-release ]; then
|
||||
lsb_dist='centos'
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then
|
||||
lsb_dist="$(. /etc/os-release && echo "$ID")"
|
||||
fi
|
||||
|
||||
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
|
||||
case "$lsb_dist" in
|
||||
fedora|centos|ubuntu|debian)
|
||||
;;
|
||||
*)
|
||||
echo "Operating system [$lsb_dist] is unsupported"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
LSB=$lsb_dist
|
||||
}
|
||||
|
||||
check_os
|
||||
case "$LSB" in
|
||||
centos)
|
||||
ROOTDIR='/usr'
|
||||
;;
|
||||
ubuntu)
|
||||
ROOTDIR='/usr/local'
|
||||
;;
|
||||
*)
|
||||
echo "$LSB is not supported"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
sudo -H pip uninstall vpp-config
|
||||
sudo rm *~
|
||||
sudo rm *.pyc
|
||||
sudo rm vpplib/*~
|
||||
sudo rm vpplib/*.pyc
|
||||
sudo rm scripts/*~
|
||||
sudo rm data/*~
|
||||
sudo rm -r build
|
||||
sudo rm -r dist
|
||||
sudo rm -r vpp_config.egg-info
|
||||
sudo rm -r $ROOTDIR/vpp/vpp-config
|
||||
sudo rm $ROOTDIR/bin/vpp-config
|
||||
74
extras/vpp_config/scripts/cp-data.sh
Executable file
74
extras/vpp_config/scripts/cp-data.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash -x
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
check_os()
|
||||
{
|
||||
|
||||
# perform some very rudimentary platform detection
|
||||
lsb_dist=''
|
||||
if command_exists lsb_release; then
|
||||
lsb_dist="$(lsb_release -si)"
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then
|
||||
lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")"
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then
|
||||
lsb_dist='fedora'
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/centos-release ]; then
|
||||
lsb_dist='centos'
|
||||
fi
|
||||
if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then
|
||||
lsb_dist="$(. /etc/os-release && echo "$ID")"
|
||||
fi
|
||||
|
||||
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
|
||||
case "$lsb_dist" in
|
||||
fedora|centos|ubuntu|debian)
|
||||
;;
|
||||
*)
|
||||
echo "Operating system [$lsb_dist] is unsupported"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
LSB=$lsb_dist
|
||||
}
|
||||
|
||||
check_os
|
||||
case "$LSB" in
|
||||
centos)
|
||||
ROOTDIR='/usr'
|
||||
;;
|
||||
ubuntu)
|
||||
ROOTDIR='/usr/local'
|
||||
;;
|
||||
*)
|
||||
echo "$LSB is not supported"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
sudo mkdir $ROOTDIR/vpp
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/scripts
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/configs
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/default
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d
|
||||
sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/vpp
|
||||
sudo cp data/auto-config.yaml $ROOTDIR/vpp/vpp-config/configs/.
|
||||
sudo cp data/grub.template $ROOTDIR/vpp/vpp-config/dryrun/default/.
|
||||
sudo cp data/startup.conf.template $ROOTDIR/vpp/vpp-config/dryrun/vpp/.
|
||||
sudo cp data/80-vpp.conf.template $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d/.
|
||||
sudo cp scripts/dpdk-devbind.py $ROOTDIR/vpp/vpp-config/scripts/.
|
||||
651
extras/vpp_config/scripts/dpdk-devbind.py
Executable file
651
extras/vpp_config/scripts/dpdk-devbind.py
Executable file
File diff suppressed because it is too large
Load Diff
30
extras/vpp_config/scripts/vpp-config
Executable file
30
extras/vpp_config/scripts/vpp-config
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""VPP Configuration Utility Wrapper"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import vpp_config as vppcfg
|
||||
|
||||
# Check for root
|
||||
if not os.geteuid() == 0:
|
||||
sys.exit('\nPlease run the VPP Configuration Utility as root.')
|
||||
|
||||
# Setup
|
||||
vppcfg.autoconfig_setup()
|
||||
|
||||
# Main menu
|
||||
vppcfg.autoconfig_main()
|
||||
5
extras/vpp_config/setup.cfg
Normal file
5
extras/vpp_config/setup.cfg
Normal file
@@ -0,0 +1,5 @@
|
||||
[bdist_wheel]
|
||||
# This flag says that the code is written to work on both Python 2 and Python
|
||||
# 3. If at all possible, it is good practice to do this. If you cannot, you
|
||||
# will need to generate wheels for each Python version that you support.
|
||||
universal=1
|
||||
22
extras/vpp_config/setup.py
Normal file
22
extras/vpp_config/setup.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(name="vpp_config",
|
||||
version="17.10.1",
|
||||
author="John DeNisco",
|
||||
author_email="jdenisco@cisco.com",
|
||||
description="VPP Configuration Utility",
|
||||
license = 'Apache-2.0',
|
||||
keywords="vppconfig",
|
||||
url = 'https://wiki.fd.io/view/VPP',
|
||||
py_modules=['vpp_config'],
|
||||
install_requires=['pyyaml'],
|
||||
packages=['vpplib'],
|
||||
scripts=['scripts/vpp-config'],
|
||||
data_files=[('vpp/vpp-config/scripts', ['scripts/dpdk-devbind.py']),
|
||||
('vpp/vpp-config/configs', ['data/auto-config.yaml']),
|
||||
('vpp/vpp-config/dryrun/sysctl.d', ['data/80-vpp.conf.template']),
|
||||
('vpp/vpp-config/dryrun/default', ['data/grub.template']),
|
||||
('vpp/vpp-config/dryrun/vpp', ['data/startup.conf.template']),
|
||||
],
|
||||
long_description="The VPP configuration utility can be used to easily configure VPP.",
|
||||
)
|
||||
573
extras/vpp_config/vpp_config.py
Executable file
573
extras/vpp_config/vpp_config.py
Executable file
File diff suppressed because it is too large
Load Diff
1427
extras/vpp_config/vpplib/AutoConfig.py
Normal file
1427
extras/vpp_config/vpplib/AutoConfig.py
Normal file
File diff suppressed because it is too large
Load Diff
287
extras/vpp_config/vpplib/CpuUtils.py
Normal file
287
extras/vpp_config/vpplib/CpuUtils.py
Normal file
@@ -0,0 +1,287 @@
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""CPU utilities library."""
|
||||
|
||||
import re
|
||||
|
||||
from vpplib.VPPUtil import VPPUtil
|
||||
|
||||
__all__ = ["CpuUtils"]
|
||||
|
||||
|
||||
class CpuUtils(object):
|
||||
"""CPU utilities"""
|
||||
|
||||
# Number of threads per core.
|
||||
NR_OF_THREADS = 2
|
||||
|
||||
@staticmethod
|
||||
def __str2int(string):
|
||||
"""Conversion from string to integer, 0 in case of empty string.
|
||||
|
||||
:param string: Input string.
|
||||
:type string: str
|
||||
:returns: Integer converted from string, 0 in case of ValueError.
|
||||
:rtype: int
|
||||
"""
|
||||
try:
|
||||
return int(string)
|
||||
except ValueError:
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def is_smt_enabled(cpu_info):
|
||||
"""Uses CPU mapping to find out if SMT is enabled or not. If SMT is
|
||||
enabled, the L1d,L1i,L2,L3 setting is the same for two processors. These
|
||||
two processors are two threads of one core.
|
||||
|
||||
:param cpu_info: CPU info, the output of "lscpu -p".
|
||||
:type cpu_info: list
|
||||
:returns: True if SMT is enabled, False if SMT is disabled.
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
cpu_mems = [item[-4:] for item in cpu_info]
|
||||
cpu_mems_len = len(cpu_mems) / CpuUtils.NR_OF_THREADS
|
||||
count = 0
|
||||
for cpu_mem in cpu_mems[:cpu_mems_len]:
|
||||
if cpu_mem in cpu_mems[cpu_mems_len:]:
|
||||
count += 1
|
||||
return bool(count == cpu_mems_len)
|
||||
|
||||
@staticmethod
|
||||
def get_cpu_layout_from_all_nodes(nodes):
|
||||
"""Retrieve cpu layout from all nodes, assuming all nodes
|
||||
are Linux nodes.
|
||||
|
||||
:param nodes: DICT__nodes from Topology.DICT__nodes.
|
||||
:type nodes: dict
|
||||
:raises RuntimeError: If the ssh command "lscpu -p" fails.
|
||||
"""
|
||||
for node in nodes.values():
|
||||
cmd = "lscpu -p"
|
||||
ret, stdout, stderr = VPPUtil.exec_command(cmd)
|
||||
# parsing of "lscpu -p" output:
|
||||
# # CPU,Core,Socket,Node,,L1d,L1i,L2,L3
|
||||
# 0,0,0,0,,0,0,0,0
|
||||
# 1,1,0,0,,1,1,1,0
|
||||
if ret != 0:
|
||||
raise RuntimeError(
|
||||
"Failed to execute ssh command, ret: {} err: {}".format(
|
||||
ret, stderr))
|
||||
node['cpuinfo'] = list()
|
||||
for line in stdout.split("\n"):
|
||||
if line != '' and line[0] != "#":
|
||||
node['cpuinfo'].append([CpuUtils.__str2int(x) for x in
|
||||
line.split(",")])
|
||||
|
||||
@staticmethod
|
||||
def cpu_node_count(node):
|
||||
"""Return count of numa nodes.
|
||||
|
||||
:param node: Targeted node.
|
||||
:type node: dict
|
||||
:returns: Count of numa nodes.
|
||||
:rtype: int
|
||||
:raises RuntimeError: If node cpuinfo is not available.
|
||||
"""
|
||||
cpu_info = node.get("cpuinfo")
|
||||
if cpu_info is not None:
|
||||
return node["cpuinfo"][-1][3] + 1
|
||||
else:
|
||||
raise RuntimeError("Node cpuinfo not available.")
|
||||
|
||||
@staticmethod
|
||||
def cpu_list_per_node(node, cpu_node, smt_used=False):
|
||||
"""Return node related list of CPU numbers.
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:param cpu_node: Numa node number.
|
||||
:param smt_used: True - we want to use SMT, otherwise false.
|
||||
:type node: dict
|
||||
:type cpu_node: int
|
||||
:type smt_used: bool
|
||||
:returns: List of cpu numbers related to numa from argument.
|
||||
:rtype: list of int
|
||||
:raises RuntimeError: If node cpuinfo is not available or if SMT is not
|
||||
enabled.
|
||||
"""
|
||||
|
||||
cpu_node = int(cpu_node)
|
||||
cpu_info = node.get("cpuinfo")
|
||||
if cpu_info is None:
|
||||
raise RuntimeError("Node cpuinfo not available.")
|
||||
|
||||
smt_enabled = CpuUtils.is_smt_enabled(cpu_info)
|
||||
if not smt_enabled and smt_used:
|
||||
raise RuntimeError("SMT is not enabled.")
|
||||
|
||||
cpu_list = []
|
||||
for cpu in cpu_info:
|
||||
if cpu[3] == cpu_node:
|
||||
cpu_list.append(cpu[0])
|
||||
|
||||
if not smt_enabled or smt_enabled and smt_used:
|
||||
pass
|
||||
|
||||
if smt_enabled and not smt_used:
|
||||
cpu_list_len = len(cpu_list)
|
||||
cpu_list = cpu_list[:cpu_list_len / CpuUtils.NR_OF_THREADS]
|
||||
|
||||
return cpu_list
|
||||
|
||||
@staticmethod
|
||||
def cpu_slice_of_list_per_node(node, cpu_node, skip_cnt=0, cpu_cnt=0,
|
||||
smt_used=False):
|
||||
"""Return string of node related list of CPU numbers.
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:param cpu_node: Numa node number.
|
||||
:param skip_cnt: Skip first "skip_cnt" CPUs.
|
||||
:param cpu_cnt: Count of cpus to return, if 0 then return all.
|
||||
:param smt_used: True - we want to use SMT, otherwise false.
|
||||
:type node: dict
|
||||
:type cpu_node: int
|
||||
:type skip_cnt: int
|
||||
:type cpu_cnt: int
|
||||
:type smt_used: bool
|
||||
:returns: Cpu numbers related to numa from argument.
|
||||
:rtype: list
|
||||
:raises RuntimeError: If we require more cpus than available.
|
||||
"""
|
||||
|
||||
cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node, smt_used)
|
||||
|
||||
cpu_list_len = len(cpu_list)
|
||||
if cpu_cnt + skip_cnt > cpu_list_len:
|
||||
raise RuntimeError("cpu_cnt + skip_cnt > length(cpu list).")
|
||||
|
||||
if cpu_cnt == 0:
|
||||
cpu_cnt = cpu_list_len - skip_cnt
|
||||
|
||||
if smt_used:
|
||||
cpu_list_0 = cpu_list[:cpu_list_len / CpuUtils.NR_OF_THREADS]
|
||||
cpu_list_1 = cpu_list[cpu_list_len / CpuUtils.NR_OF_THREADS:]
|
||||
cpu_list = [cpu for cpu in cpu_list_0[skip_cnt:skip_cnt + cpu_cnt]]
|
||||
cpu_list_ex = [cpu for cpu in
|
||||
cpu_list_1[skip_cnt:skip_cnt + cpu_cnt]]
|
||||
cpu_list.extend(cpu_list_ex)
|
||||
else:
|
||||
cpu_list = [cpu for cpu in cpu_list[skip_cnt:skip_cnt + cpu_cnt]]
|
||||
|
||||
return cpu_list
|
||||
|
||||
@staticmethod
|
||||
def cpu_list_per_node_str(node, cpu_node, skip_cnt=0, cpu_cnt=0, sep=",",
|
||||
smt_used=False):
|
||||
"""Return string of node related list of CPU numbers.
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:param cpu_node: Numa node number.
|
||||
:param skip_cnt: Skip first "skip_cnt" CPUs.
|
||||
:param cpu_cnt: Count of cpus to return, if 0 then return all.
|
||||
:param sep: Separator, default: 1,2,3,4,....
|
||||
:param smt_used: True - we want to use SMT, otherwise false.
|
||||
:type node: dict
|
||||
:type cpu_node: int
|
||||
:type skip_cnt: int
|
||||
:type cpu_cnt: int
|
||||
:type sep: str
|
||||
:type smt_used: bool
|
||||
:returns: Cpu numbers related to numa from argument.
|
||||
:rtype: str
|
||||
"""
|
||||
|
||||
cpu_list = CpuUtils.cpu_slice_of_list_per_node(node, cpu_node,
|
||||
skip_cnt=skip_cnt,
|
||||
cpu_cnt=cpu_cnt,
|
||||
smt_used=smt_used)
|
||||
return sep.join(str(cpu) for cpu in cpu_list)
|
||||
|
||||
@staticmethod
|
||||
def cpu_range_per_node_str(node, cpu_node, skip_cnt=0, cpu_cnt=0, sep="-",
|
||||
smt_used=False):
|
||||
"""Return string of node related range of CPU numbers, e.g. 0-4.
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:param cpu_node: Numa node number.
|
||||
:param skip_cnt: Skip first "skip_cnt" CPUs.
|
||||
:param cpu_cnt: Count of cpus to return, if 0 then return all.
|
||||
:param sep: Separator, default: "-".
|
||||
:param smt_used: True - we want to use SMT, otherwise false.
|
||||
:type node: dict
|
||||
:type cpu_node: int
|
||||
:type skip_cnt: int
|
||||
:type cpu_cnt: int
|
||||
:type sep: str
|
||||
:type smt_used: bool
|
||||
:returns: String of node related range of CPU numbers.
|
||||
:rtype: str
|
||||
"""
|
||||
|
||||
cpu_list = CpuUtils.cpu_slice_of_list_per_node(node, cpu_node,
|
||||
skip_cnt=skip_cnt,
|
||||
cpu_cnt=cpu_cnt,
|
||||
smt_used=smt_used)
|
||||
if smt_used:
|
||||
cpu_list_len = len(cpu_list)
|
||||
cpu_list_0 = cpu_list[:cpu_list_len / CpuUtils.NR_OF_THREADS]
|
||||
cpu_list_1 = cpu_list[cpu_list_len / CpuUtils.NR_OF_THREADS:]
|
||||
cpu_range = "{}{}{},{}{}{}".format(cpu_list_0[0], sep,
|
||||
cpu_list_0[-1],
|
||||
cpu_list_1[0], sep,
|
||||
cpu_list_1[-1])
|
||||
else:
|
||||
cpu_range = "{}{}{}".format(cpu_list[0], sep, cpu_list[-1])
|
||||
|
||||
return cpu_range
|
||||
|
||||
@staticmethod
|
||||
def get_cpu_info_per_node(node):
|
||||
"""Return node related list of CPU numbers.
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:type node: dict
|
||||
:returns: Important CPU information.
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
cmd = "lscpu"
|
||||
ret, stdout, stderr = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError("lscpu command failed on node {} {}."
|
||||
.format(node['host'], stderr))
|
||||
|
||||
cpuinfo = {}
|
||||
lines = stdout.split('\n')
|
||||
for line in lines:
|
||||
if line != '':
|
||||
linesplit = re.split(r':\s+', line)
|
||||
cpuinfo[linesplit[0]] = linesplit[1]
|
||||
|
||||
cmd = "cat /proc/*/task/*/stat | awk '{print $1" "$2" "$39}'"
|
||||
ret, stdout, stderr = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError("cat command failed on node {} {}."
|
||||
.format(node['host'], stderr))
|
||||
|
||||
vpp_processes = {}
|
||||
vpp_lines = re.findall(r'\w+\(vpp_\w+\)\w+', stdout)
|
||||
for line in vpp_lines:
|
||||
linesplit = re.split(r'\w+\(', line)[1].split(')')
|
||||
vpp_processes[linesplit[0]] = linesplit[1]
|
||||
|
||||
cpuinfo['vpp_processes'] = vpp_processes
|
||||
|
||||
return cpuinfo
|
||||
680
extras/vpp_config/vpplib/QemuUtils.py
Normal file
680
extras/vpp_config/vpplib/QemuUtils.py
Normal file
File diff suppressed because it is too large
Load Diff
662
extras/vpp_config/vpplib/VPPUtil.py
Normal file
662
extras/vpp_config/vpplib/VPPUtil.py
Normal file
File diff suppressed because it is too large
Load Diff
236
extras/vpp_config/vpplib/VppGrubUtil.py
Normal file
236
extras/vpp_config/vpplib/VppGrubUtil.py
Normal file
@@ -0,0 +1,236 @@
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""VPP Grub Utility Library."""
|
||||
|
||||
import re
|
||||
|
||||
from vpplib.VPPUtil import VPPUtil
|
||||
|
||||
__all__ = ['VppGrubUtil']
|
||||
|
||||
|
||||
class VppGrubUtil(object):
|
||||
""" VPP Grub Utilities."""
|
||||
|
||||
def _get_current_cmdline(self):
|
||||
"""
|
||||
Using /proc/cmdline return the current grub cmdline
|
||||
|
||||
:returns: The current grub cmdline
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
# Get the memory information using /proc/meminfo
|
||||
cmd = 'sudo cat /proc/cmdline'
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} on node {} {} {}'.
|
||||
format(cmd, self._node['host'],
|
||||
stdout, stderr))
|
||||
|
||||
self._current_cmdline = stdout.strip('\n')
|
||||
|
||||
def _get_default_cmdline(self):
|
||||
"""
|
||||
Using /etc/default/grub return the default grub cmdline
|
||||
|
||||
:returns: The default grub cmdline
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
# Get the default grub cmdline
|
||||
rootdir = self._node['rootdir']
|
||||
gfile = self._node['cpu']['grub_config_file']
|
||||
grubcmdline = self._node['cpu']['grubcmdline']
|
||||
cmd = 'cat {}'.format(rootdir + gfile)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} Executing failed on node {} {}'.
|
||||
format(cmd, self._node['host'], stderr))
|
||||
|
||||
# Get the Default Linux command line, ignoring commented lines
|
||||
lines = stdout.split('\n')
|
||||
for line in lines:
|
||||
if line == '' or line[0] == '#':
|
||||
continue
|
||||
ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
|
||||
if ldefault:
|
||||
self._default_cmdline = ldefault[0]
|
||||
break
|
||||
|
||||
def get_current_cmdline(self):
|
||||
"""
|
||||
Returns the saved grub cmdline
|
||||
|
||||
:returns: The saved grub cmdline
|
||||
:rtype: string
|
||||
"""
|
||||
return self._current_cmdline
|
||||
|
||||
def get_default_cmdline(self):
|
||||
"""
|
||||
Returns the default grub cmdline
|
||||
|
||||
:returns: The default grub cmdline
|
||||
:rtype: string
|
||||
"""
|
||||
return self._default_cmdline
|
||||
|
||||
def create_cmdline(self, isolated_cpus):
|
||||
"""
|
||||
Create the new grub cmdline
|
||||
|
||||
:param isolated_cpus: The isolated cpu string
|
||||
:type isolated_cpus: string
|
||||
:returns: The command line
|
||||
:rtype: string
|
||||
"""
|
||||
grubcmdline = self._node['cpu']['grubcmdline']
|
||||
cmdline = self._default_cmdline
|
||||
value = cmdline.split('{}='.format(grubcmdline))[1]
|
||||
value = value.rstrip('"').lstrip('"')
|
||||
|
||||
iommu = re.findall(r'iommu=\w+', value)
|
||||
pstate = re.findall(r'intel_pstate=\w+', value)
|
||||
# If there is already some iommu commands set, leave them,
|
||||
# if not use ours
|
||||
if iommu == [] and pstate == []:
|
||||
value = '{} intel_pstate=disable'.format(value)
|
||||
|
||||
# Replace isolcpus with ours
|
||||
isolcpus = re.findall(r'isolcpus=[\w+\-,]+', value)
|
||||
if not isolcpus:
|
||||
if isolated_cpus != '':
|
||||
value = "{} isolcpus={}".format(value, isolated_cpus)
|
||||
else:
|
||||
if isolated_cpus != '':
|
||||
value = re.sub(r'isolcpus=[\w+\-,]+',
|
||||
'isolcpus={}'.format(isolated_cpus),
|
||||
value)
|
||||
else:
|
||||
value = re.sub(r'isolcpus=[\w+\-,]+', '', value)
|
||||
|
||||
nohz = re.findall(r'nohz_full=[\w+\-,]+', value)
|
||||
if not nohz:
|
||||
if isolated_cpus != '':
|
||||
value = "{} nohz_full={}".format(value, isolated_cpus)
|
||||
else:
|
||||
if isolated_cpus != '':
|
||||
value = re.sub(r'nohz_full=[\w+\-,]+',
|
||||
'nohz_full={}'.format(isolated_cpus),
|
||||
value)
|
||||
else:
|
||||
value = re.sub(r'nohz_full=[\w+\-,]+', '', value)
|
||||
|
||||
rcu = re.findall(r'rcu_nocbs=[\w+\-,]+', value)
|
||||
if not rcu:
|
||||
if isolated_cpus != '':
|
||||
value = "{} rcu_nocbs={}".format(value, isolated_cpus)
|
||||
else:
|
||||
if isolated_cpus != '':
|
||||
value = re.sub(r'rcu_nocbs=[\w+\-,]+',
|
||||
'rcu_nocbs={}'.format(isolated_cpus),
|
||||
value)
|
||||
else:
|
||||
value = re.sub(r'rcu_nocbs=[\w+\-,]+', '', value)
|
||||
|
||||
value = value.lstrip(' ').rstrip(' ')
|
||||
cmdline = '{}="{}"'.format(grubcmdline, value)
|
||||
return cmdline
|
||||
|
||||
def apply_cmdline(self, node, isolated_cpus):
|
||||
"""
|
||||
Apply cmdline to the default grub file
|
||||
|
||||
:param node: Node dictionary with cpuinfo.
|
||||
:param isolated_cpus: The isolated cpu string
|
||||
:type node: dict
|
||||
:type isolated_cpus: string
|
||||
:return The vpp cmdline
|
||||
:rtype string
|
||||
"""
|
||||
|
||||
vpp_cmdline = self.create_cmdline(isolated_cpus)
|
||||
if vpp_cmdline == '':
|
||||
return vpp_cmdline
|
||||
|
||||
# Update grub
|
||||
# Save the original file
|
||||
rootdir = node['rootdir']
|
||||
grubcmdline = node['cpu']['grubcmdline']
|
||||
ofilename = rootdir + node['cpu']['grub_config_file'] + '.orig'
|
||||
filename = rootdir + node['cpu']['grub_config_file']
|
||||
|
||||
# Write the output file
|
||||
# Does a copy of the original file exist, if not create one
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(ofilename))
|
||||
if ret != 0:
|
||||
if stdout.strip('\n') != ofilename:
|
||||
cmd = 'sudo cp {} {}'.format(filename, ofilename)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} failed on node {} {}'.
|
||||
format(cmd, self._node['host'], stderr))
|
||||
|
||||
# Get the contents of the current grub config file
|
||||
cmd = 'cat {}'.format(filename)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} failed on node {} {}'.format(
|
||||
cmd,
|
||||
self._node['host'],
|
||||
stderr))
|
||||
|
||||
# Write the new contents
|
||||
# Get the Default Linux command line, ignoring commented lines
|
||||
content = ""
|
||||
lines = stdout.split('\n')
|
||||
for line in lines:
|
||||
if line == '':
|
||||
content += line + '\n'
|
||||
continue
|
||||
if line[0] == '#':
|
||||
content += line + '\n'
|
||||
continue
|
||||
|
||||
ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
|
||||
if ldefault:
|
||||
content += vpp_cmdline + '\n'
|
||||
else:
|
||||
content += line + '\n'
|
||||
|
||||
content = content.replace(r"`", r"\`")
|
||||
content = content.rstrip('\n')
|
||||
cmd = "sudo cat > {0} << EOF\n{1}\n".format(filename, content)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} failed on node {} {}'.format(
|
||||
cmd,
|
||||
self._node['host'],
|
||||
stderr))
|
||||
|
||||
return vpp_cmdline
|
||||
|
||||
def __init__(self, node):
|
||||
distro = VPPUtil.get_linux_distro()
|
||||
if distro[0] == 'Ubuntu':
|
||||
node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX_DEFAULT'
|
||||
else:
|
||||
node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX'
|
||||
|
||||
self._node = node
|
||||
self._current_cmdline = ""
|
||||
self._default_cmdline = ""
|
||||
self._get_current_cmdline()
|
||||
self._get_default_cmdline()
|
||||
122
extras/vpp_config/vpplib/VppHugePageUtil.py
Normal file
122
extras/vpp_config/vpplib/VppHugePageUtil.py
Normal file
@@ -0,0 +1,122 @@
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""VPP Huge Page Utilities"""
|
||||
|
||||
import re
|
||||
|
||||
from vpplib.VPPUtil import VPPUtil
|
||||
|
||||
# VPP Huge page File
|
||||
DEFAULT_VPP_HUGE_PAGE_CONFIG_FILENAME = "/etc/vpp/80-vpp.conf"
|
||||
VPP_HUGEPAGE_CONFIG = """
|
||||
vm.nr_hugepages={nr_hugepages}
|
||||
vm.max_map_count={max_map_count}
|
||||
vm.hugetlb_shm_group=0
|
||||
kernel.shmmax={shmmax}
|
||||
"""
|
||||
|
||||
|
||||
class VppHugePageUtil(object):
|
||||
"""
|
||||
Huge Page Utilities
|
||||
"""
|
||||
def hugepages_dryrun_apply(self):
|
||||
"""
|
||||
Apply the huge page configuration
|
||||
|
||||
"""
|
||||
|
||||
node = self._node
|
||||
hugepages = node['hugepages']
|
||||
|
||||
vpp_hugepage_config = VPP_HUGEPAGE_CONFIG.format(
|
||||
nr_hugepages=hugepages['total'],
|
||||
max_map_count=hugepages['max_map_count'],
|
||||
shmmax=hugepages['shmax'])
|
||||
|
||||
rootdir = node['rootdir']
|
||||
filename = rootdir + node['hugepages']['hugepage_config_file']
|
||||
|
||||
cmd = 'echo "{0}" | sudo tee {1}'.\
|
||||
format(vpp_hugepage_config, filename)
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError('{} failed on node {} {} {}'.
|
||||
format(cmd, node['host'],
|
||||
stdout, stderr))
|
||||
|
||||
def get_actual_huge_pages(self):
|
||||
"""
|
||||
Get the current huge page configuration
|
||||
|
||||
:returns the hugepage total, hugepage free, hugepage size,
|
||||
total memory, and total memory free
|
||||
:rtype: tuple
|
||||
"""
|
||||
|
||||
# Get the memory information using /proc/meminfo
|
||||
cmd = 'sudo cat /proc/meminfo'
|
||||
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
||||
if ret != 0:
|
||||
raise RuntimeError(
|
||||
'{} failed on node {} {} {}'.format(
|
||||
cmd, self._node['host'],
|
||||
stdout, stderr))
|
||||
|
||||
total = re.findall(r'HugePages_Total:\s+\w+', stdout)
|
||||
free = re.findall(r'HugePages_Free:\s+\w+', stdout)
|
||||
size = re.findall(r'Hugepagesize:\s+\w+\s+\w+', stdout)
|
||||
memtotal = re.findall(r'MemTotal:\s+\w+\s+\w+', stdout)
|
||||
memfree = re.findall(r'MemFree:\s+\w+\s+\w+', stdout)
|
||||
|
||||
total = total[0].split(':')[1].lstrip()
|
||||
free = free[0].split(':')[1].lstrip()
|
||||
size = size[0].split(':')[1].lstrip()
|
||||
memtotal = memtotal[0].split(':')[1].lstrip()
|
||||
memfree = memfree[0].split(':')[1].lstrip()
|
||||
return total, free, size, memtotal, memfree
|
||||
|
||||
def show_huge_pages(self):
|
||||
"""
|
||||
Print the current huge page configuration
|
||||
|
||||
"""
|
||||
|
||||
node = self._node
|
||||
hugepages = node['hugepages']
|
||||
print " {:30}: {}".format("Total System Memory",
|
||||
hugepages['memtotal'])
|
||||
print " {:30}: {}".format("Total Free Memory",
|
||||
hugepages['memfree'])
|
||||
print " {:30}: {}".format("Actual Huge Page Total",
|
||||
hugepages['actual_total'])
|
||||
print " {:30}: {}".format("Configured Huge Page Total",
|
||||
hugepages['total'])
|
||||
print " {:30}: {}".format("Huge Pages Free", hugepages['free'])
|
||||
print " {:30}: {}".format("Huge Page Size", hugepages['size'])
|
||||
|
||||
def get_huge_page_config(self):
|
||||
"""
|
||||
Returns the huge page config.
|
||||
|
||||
:returns: The map max count and shmmax
|
||||
"""
|
||||
|
||||
total = self._node['hugepages']['total']
|
||||
max_map_count = int(total) * 2 + 1024
|
||||
shmmax = int(total) * 2 * 1024 * 1024
|
||||
return max_map_count, shmmax
|
||||
|
||||
def __init__(self, node):
|
||||
self._node = node
|
||||
330
extras/vpp_config/vpplib/VppPCIUtil.py
Normal file
330
extras/vpp_config/vpplib/VppPCIUtil.py
Normal file
File diff suppressed because it is too large
Load Diff
16
extras/vpp_config/vpplib/__init__.py
Normal file
16
extras/vpp_config/vpplib/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
__init__ file for directory lib
|
||||
"""
|
||||
48
extras/vpp_config/vpplib/constants.py
Normal file
48
extras/vpp_config/vpplib/constants.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Constants used in CSIT."""
|
||||
|
||||
|
||||
class Constants(object):
|
||||
"""Constants used in CSIT."""
|
||||
|
||||
# OpenVPP testing directory location at topology nodes
|
||||
REMOTE_FW_DIR = '/tmp/openvpp-testing'
|
||||
|
||||
# shell scripts location
|
||||
RESOURCES_LIB_SH = 'resources/libraries/bash'
|
||||
|
||||
# vat templates location
|
||||
RESOURCES_TPL_VAT = 'resources/templates/vat'
|
||||
|
||||
# OpenVPP VAT binary name
|
||||
VAT_BIN_NAME = 'vpp_api_test'
|
||||
|
||||
# QEMU version to install
|
||||
QEMU_INSTALL_VERSION = 'qemu-2.5.0'
|
||||
|
||||
# QEMU install directory
|
||||
QEMU_INSTALL_DIR = '/opt/qemu-2.5.0'
|
||||
|
||||
# Honeycomb directory location at topology nodes:
|
||||
REMOTE_HC_DIR = '/opt/honeycomb'
|
||||
|
||||
# Honeycomb persistence files location
|
||||
REMOTE_HC_PERSIST = '/var/lib/honeycomb/persist'
|
||||
|
||||
# Honeycomb templates location
|
||||
RESOURCES_TPL_HC = 'resources/templates/honeycomb'
|
||||
|
||||
# ODL Client Restconf listener port
|
||||
ODL_PORT = 8181
|
||||
Reference in New Issue
Block a user