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