NFVBENCH-196: New NFVbench image for generator part (nfvbench and TRex codes inside VM)
[nfvbench.git] / nfvbenchvm / dib / elements / nfvbenchvm / static / nfvbench / configure-nfvbench.sh
1 #!/bin/bash
2
3 set -e
4
5 NFVBENCH_CONF=/etc/nfvbenchvm.conf
6 E2E_CFG=/etc/nfvbench/e2e.cfg
7 LOOPBACK_CFG=/etc/nfvbench/loopback.cfg
8 NFVBENCH_CFG=/etc/nfvbench/nfvbench.cfg
9 OPENRC=/etc/nfvbench/openrc
10
11 # Parse and obtain all configurations
12 eval $(cat $NFVBENCH_CONF)
13
14 if [ -f $OPENRC ]; then
15     source $OPENRC
16 fi
17
18 # WE assume there are at least 2 cores available for the VM
19 CPU_CORES=$(grep -c ^processor /proc/cpuinfo)
20
21 # We need at least 2 admin cores (one master and another latency).
22 if [ $CPU_CORES -le 3 ]; then
23     ADMIN_CORES=2
24 else
25     # If the number of cores is even we
26     # reserve 3 cores for admin (third being idle) so the number of
27     # workers is either 1 (if CPU_CORES is 4) or always even
28     if (( $CPU_CORES % 2 )); then
29         ADMIN_CORES=2
30     else
31         ADMIN_CORES=3
32     fi
33 fi
34 # 2 vcpus: AW (core 0: Admin, core 1: Worker)
35 # 3 vcpus: AWW (core 0: Admin, core 1,2: Worker)
36 # 4 vcpus: AWWU (core 0: Admin, core 1,2: Worker, core 3: Unused)
37 # 5 vcpus: AWWWW
38 # 6 vcpus: AWWWWU
39 WORKER_CORES=$(expr $CPU_CORES - $ADMIN_CORES)
40 # worker cores are all cores except the admin core (core 0) and the eventual unused core
41 # AW -> 1
42 # AWW -> 1,2
43 # AWWU -> 1,2
44 WORKER_CORE_LIST=$(seq -s, $ADMIN_CORES $WORKER_CORES)
45 # always use all cores
46 CORE_MASK=0x$(echo "obase=16; 2 ^ $CPU_CORES - 1" | bc)
47
48 logger "NFVBENCHVM: CPU_CORES=$CPU_CORES, ADMIN_CORES=$ADMIN_CORES, WORKER_CORES=$WORKER_CORES ($WORKER_CORE_LIST)"
49
50 # Isolate all cores that are reserved for workers
51 tuna -c $WORKER_CORE_LIST --isolate
52
53 NET_PATH=/sys/class/net
54
55 get_pci_address() {
56     # device mapping for CentOS Linux 7:
57     # lspci:
58     #   00.03.0 Ethernet controller: Red Hat, Inc. Virtio network device
59     #   00.04.0 Ethernet controller: Red Hat, Inc. Virtio network device
60     # /sys/class/net:
61     # /sys/class/net/eth0 -> ../../devices/pci0000:00/0000:00:03.0/virtio0/net/eth0
62     # /sys/class/net/eth1 -> ../../devices/pci0000:00/0000:00:04.0/virtio1/net/eth1
63
64     mac=$1
65     for f in $(ls $NET_PATH/); do
66         if grep -q "$mac" $NET_PATH/$f/address; then
67             pci_addr=$(readlink $NET_PATH/$f | cut -d "/" -f5)
68             # some virtual interfaces match on MAC and do not have a PCI address
69             if [ "$pci_addr" -a "$pci_addr" != "N/A" ]; then
70                 # Found matching interface
71                 logger "NFVBENCHVM: found interface $f ($pci_addr) matching $mac"
72                 break
73             else
74                 pci_addr=""
75             fi
76         fi;
77     done
78     if [ -z "$pci_addr" ]; then
79         echo "ERROR: Cannot find pci address for MAC $mac" >&2
80         logger "NFVBENCHVM ERROR: Cannot find pci address for MAC $mac"
81         return 1
82     fi
83     echo $pci_addr
84     return 0
85 }
86
87 get_interfaces_mac_values(){
88     # Set dynamically interfaces mac values, if VM is spawn with SRIOV PF ports
89     # and openstack API are accessible
90     if [ -z "$LOOPBACK_INTF_MAC1" ] && [ -z "$LOOPBACK_INTF_MAC2" ]; then
91         if [ -f $OPENRC ] && [ "$LOOPBACK_PORT_NAME1" ] && [ "$LOOPBACK_PORT_NAME2" ]; then
92             LOOPBACK_INTF_MAC1=$(openstack port list | grep $LOOPBACK_PORT_NAME1 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
93             LOOPBACK_INTF_MAC2=$(openstack port list | grep $LOOPBACK_PORT_NAME2 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
94         fi
95     fi
96     if [ -z "$E2E_INTF_MAC1" ] && [ -z "$E2E_INTF_MAC2" ]; then
97         if [ -f $OPENRC ] && [ "$E2E_PORT_NAME1" ] && [ "$E2E_PORT_NAME2" ]; then
98             E2E_INTF_MAC1=$(openstack port list | grep $E2E_PORT_NAME1 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
99             E2E_INTF_MAC2=$(openstack port list | grep $E2E_PORT_NAME2 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
100         fi
101     fi
102     if [ -z "$INTF_MAC1" ] && [ -z "$INTF_MAC2" ]; then
103         if [ -f $OPENRC ] && [ "$PORT_NAME1" ] && [ "$PORT_NAME2" ]; then
104             INTF_MAC1=$(openstack port list | grep $PORT_NAME1 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
105             INTF_MAC2=$(openstack port list | grep $PORT_NAME2 | grep -o -Ei '([a-fA-F0-9:]{17}|[a-fA-F0-9]{12}$)' | head -1)
106         fi
107     fi
108 }
109
110 get_interfaces_pci_address(){
111     # Sometimes the interfaces on the generator VM will use different physical networks. In this case,
112     # we have to make sure the generator uses them in the right order.
113     if [ $LOOPBACK_INTF_MAC1 ] && [ $LOOPBACK_INTF_MAC2 ]; then
114         LOOPBACK_PCI_ADDRESS_1=$(get_pci_address $LOOPBACK_INTF_MAC1)
115         LOOPBACK_PCI_ADDRESS_2=$(get_pci_address $LOOPBACK_INTF_MAC2)
116
117         echo LOOPBACK_PCI_ADDRESS_1=$LOOPBACK_PCI_ADDRESS_1 >> $NFVBENCH_CONF
118         echo LOOPBACK_PCI_ADDRESS_2=$LOOPBACK_PCI_ADDRESS_2 >> $NFVBENCH_CONF
119     fi
120     if [ $E2E_INTF_MAC1 ] && [ $E2E_INTF_MAC2 ]; then
121         E2E_PCI_ADDRESS_1=$(get_pci_address $E2E_INTF_MAC1)
122         E2E_PCI_ADDRESS_2=$(get_pci_address $E2E_INTF_MAC2)
123
124         echo E2E_PCI_ADDRESS_1=$E2E_PCI_ADDRESS_1 >> $NFVBENCH_CONF
125         echo E2E_PCI_ADDRESS_2=$E2E_PCI_ADDRESS_2 >> $NFVBENCH_CONF
126     fi
127     if [ $INTF_MAC1 ] && [ $INTF_MAC2 ]; then
128         PCI_ADDRESS_1=$(get_pci_address $INTF_MAC1)
129         PCI_ADDRESS_2=$(get_pci_address $INTF_MAC2)
130
131         echo PCI_ADDRESS_1=$PCI_ADDRESS_1 >> $NFVBENCH_CONF
132         echo PCI_ADDRESS_2=$PCI_ADDRESS_2 >> $NFVBENCH_CONF
133     fi
134 }
135
136 bind_interfaces(){
137     if [ $LOOPBACK_PCI_ADDRESS_1 ]; then
138         dpdk-devbind -b vfio-pci $LOOPBACK_PCI_ADDRESS_1
139     fi
140     if [ $LOOPBACK_PCI_ADDRESS_2 ]; then
141         dpdk-devbind -b vfio-pci $LOOPBACK_PCI_ADDRESS_2
142     fi
143     if [ $E2E_PCI_ADDRESS_1 ]; then
144         dpdk-devbind -b vfio-pci $E2E_PCI_ADDRESS_1
145     fi
146     if [ $E2E_PCI_ADDRESS_2 ]; then
147         dpdk-devbind -b vfio-pci $E2E_PCI_ADDRESS_2
148     fi
149     if [ $PCI_ADDRESS_1 ]; then
150         dpdk-devbind -b vfio-pci $PCI_ADDRESS_1
151     fi
152     if [ $PCI_ADDRESS_2 ]; then
153         dpdk-devbind -b vfio-pci $PCI_ADDRESS_2
154     fi
155 }
156
157 configure_loopback_mode(){
158     if [ $LOOPBACK_PCI_ADDRESS_1 ] && [ $LOOPBACK_PCI_ADDRESS_2 ]; then
159         logger "NFVBENCHVM: loopback - Using pci $LOOPBACK_PCI_ADDRESS_1 ($LOOPBACK_INTF_MAC1)"
160         logger "NFVBENCHVM: loopback - Using pci $LOOPBACK_PCI_ADDRESS_2 ($LOOPBACK_INTF_MAC2)"
161
162         echo "Configuring nfvbench and TRex for loopback mode..."
163         # execute env script to avoid no ENV in screen and a nfvbench error
164         source /etc/profile.d/nfvbench.sh
165         sed -i "s/{{PCI_ADDRESS_1}}/$LOOPBACK_PCI_ADDRESS_1/g" /etc/nfvbench/loopback.cfg
166         sed -i "s/{{PCI_ADDRESS_2}}/$LOOPBACK_PCI_ADDRESS_2/g" /etc/nfvbench/loopback.cfg
167         sed -i "s/{{CORES}}/$WORKER_CORES/g" /etc/nfvbench/loopback.cfg
168         CORE_THREADS=$(seq -s, 2 $((2+$WORKER_CORES)))
169         sed -i "s/{{CORE_THREADS}}/$CORE_THREADS/g" /etc/nfvbench/loopback.cfg
170     else
171         echo "ERROR: Cannot find PCI Address from MAC"
172         echo "$LOOPBACK_INTF_MAC1: $LOOPBACK_PCI_ADDRESS_1"
173         echo "$LOOPBACK_INTF_MAC2: $LOOPBACK_PCI_ADDRESS_2"
174         logger "NFVBENCHVM ERROR: Cannot find PCI Address from MAC (loopback mode)"
175     fi
176
177 }
178
179 configure_e2e_mode(){
180     if [ $E2E_PCI_ADDRESS_1 ] && [ $E2E_PCI_ADDRESS_2 ]; then
181         logger "NFVBENCHVM: e2e - Using pci $E2E_PCI_ADDRESS_1 ($E2E_INTF_MAC1)"
182         logger "NFVBENCHVM: e2e - Using pci $E2E_PCI_ADDRESS_2 ($E2E_INTF_MAC2)"
183
184         echo "Configuring nfvbench and TRex for e2e mode..."
185         # execute env script to avoid no ENV in screen and a nfvbench error
186         source /etc/profile.d/nfvbench.sh
187         sed -i "s/{{PCI_ADDRESS_1}}/$E2E_PCI_ADDRESS_1/g" /etc/nfvbench/e2e.cfg
188         sed -i "s/{{PCI_ADDRESS_2}}/$E2E_PCI_ADDRESS_2/g" /etc/nfvbench/e2e.cfg
189         sed -i "s/{{CORES}}/$WORKER_CORES/g" /etc/nfvbench/e2e.cfg
190         CORE_THREADS=$(seq -s, 2 $((2+$WORKER_CORES)))
191         sed -i "s/{{CORE_THREADS}}/$CORE_THREADS/g" /etc/nfvbench/e2e.cfg
192     else
193         echo "ERROR: Cannot find PCI Address from MAC"
194         echo "$E2E_INTF_MAC1: $E2E_PCI_ADDRESS_1"
195         echo "$E2E_INTF_MAC2: $E2E_PCI_ADDRESS_2"
196         logger "NFVBENCHVM ERROR: Cannot find PCI Address from MAC (e2e mode)"
197     fi
198 }
199
200 configure_nfvbench(){
201     if [ $PCI_ADDRESS_1 ] && [ $PCI_ADDRESS_2 ]; then
202         logger "NFVBENCHVM: Using pci $PCI_ADDRESS_1 ($INTF_MAC1)"
203         logger "NFVBENCHVM: Using pci $PCI_ADDRESS_2 ($INTF_MAC2)"
204
205         echo "Configuring nfvbench and TRex..."
206         # execute env script to avoid no ENV in screen and a nfvbench error
207         source /etc/profile.d/nfvbench.sh
208
209         if [ $DEFAULT ]; then
210             cp /nfvbench/nfvbench.conf /etc/nfvbench/nfvbench.cfg
211         fi
212         sed -i "s/{{PCI_ADDRESS_1}}/$PCI_ADDRESS_1/g" /etc/nfvbench/nfvbench.cfg
213         sed -i "s/{{PCI_ADDRESS_2}}/$PCI_ADDRESS_2/g" /etc/nfvbench/nfvbench.cfg
214         sed -i "s/{{CORES}}/$WORKER_CORES/g" /etc/nfvbench/nfvbench.cfg
215         CORE_THREADS=$(seq -s, 2 $((2+$WORKER_CORES)))
216         sed -i "s/{{CORE_THREADS}}/$CORE_THREADS/g" /etc/nfvbench/nfvbench.cfg
217
218     else
219         echo "ERROR: Cannot find PCI Address from MAC"
220         echo "$INTF_MAC1: $PCI_ADDRESS_1"
221         echo "$INTF_MAC2: $PCI_ADDRESS_2"
222         logger "NFVBENCHVM ERROR: Cannot find PCI Address from MAC"
223     fi
224 }
225
226 # Check if config files are provided by config drive (CLI command) or Ansible script
227 # and configure NFVbench accordingly to these files
228 if [ -f $E2E_CFG ]; then
229     if [ -z $E2E_PCI_ADDRESS_1 ] && [ -z $E2E_PCI_ADDRESS_2 ]; then
230         get_interfaces_mac_values
231         get_interfaces_pci_address
232         bind_interfaces
233     fi
234     configure_e2e_mode
235 fi
236 if [ -f $LOOPBACK_CFG ]; then
237     if [ -z $LOOPBACK_PCI_ADDRESS_1 ] && [ -z $LOOPBACK_PCI_ADDRESS_2 ]; then
238         get_interfaces_mac_values
239         get_interfaces_pci_address
240         bind_interfaces
241     fi
242     configure_loopback_mode
243 fi
244 # if nfvbench.cfg is provided by config drive (CLI command) or Ansible script
245 # configure nfvbench using this file otherwise untemplate default config if no file exists
246 if [ -f $NFVBENCH_CFG ]; then
247     if [ -z $PCI_ADDRESS_1 ] && [ -z $PCI_ADDRESS_2 ]; then
248         get_interfaces_mac_values
249         get_interfaces_pci_address
250         bind_interfaces
251     fi
252     configure_nfvbench
253 elif [ ! -f $E2E_CFG ] && [ ! -f $LOOPBACK_CFG ]; then
254     if [ -z $PCI_ADDRESS_1 ] && [ -z $PCI_ADDRESS_2 ]; then
255         get_interfaces_mac_values
256         get_interfaces_pci_address
257         bind_interfaces
258     fi
259     DEFAULT=true
260     configure_nfvbench
261 fi
262
263 exit 0