summaryrefslogtreecommitdiff
path: root/automated/linux/nginx-server/nginx-server.sh
blob: d4e39a96431d7323b8f1edadf33bbb6c0fd74eaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/bin/bash
set -o errexit

THIS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
TEST_DEFS_DIR=$(readlink -f "${THIS_DIR}/../../..")
GET_VLAND_IFACE=${TEST_DEFS_DIR}/automated/utils/vland/get_vland_interface.sh
GET_VLAND_PCI_DEV=${TEST_DEFS_DIR}/automated/utils/vland/get_vland_pci_dev.sh

# vlnad name to use
VLAND_NAME=${VLAND_NAME:-vlan_one}
VLAND_IFACE=$($GET_VLAND_IFACE "$VLAND_NAME")
VLAND_PCI_DEV=$($GET_VLAND_PCI_DEV "$VLAND_NAME")

# Do not run tests on more than MAX_CORES cores
# 0 means use all cores
MAX_CORES=${MAX_CORES:-0}

# IP address of the server
SERVER_IP=${SERVER_IP:-192.168.1.4}

# What kind of configuration to use:
#   linux-ip: plain Linux IP stack
#   odp-dpdk: NGiNX with OFP+ODP+DPDK
CONFIG_TYPE=${CONFIG_TYPE:-linux-ip}

function exit_error {
	echo "-- SERVER ERROR"
	journalctl -u nginx
	lava-test-case server_up --status fail
}
trap exit_error ERR

# Use this function to configure Linux IP stack
function config_linux_ip {
	ip address add "${SERVER_IP}/24" dev "$VLAND_IFACE"
	ip link set "$VLAND_IFACE" up
	lava-test-case server_ifup --result pass

	sysctl -w net.ipv4.ip_local_port_range="1500 65500"
}

# Use this function to configure a device for DPDK usage
function config_dpdk_dev {
	local driver=${1:-igb_uio}

	if ! which dpdk-devbind &>/dev/null; then
		echo "ERROR: dpdk not installed"
		exit 1
	fi

	modprobe "$driver"

	dpdk-devbind -u "$VLAND_PCI_DEV"
	dpdk-devbind -b "${driver}" "$VLAND_PCI_DEV"
	dpdk-devbind -s

	apt-get install -y nginx
	systemctl stop nginx

	# FIXME: for now NGiNX for OFP only supports one core worker
	echo "-- NOTICE: setting MAX_CORES to 1"
	MAX_CORES=1
}

# Callback to call before starting nginx when using OFP-DPDK
# First parameter of callback is the number of cores
function odp_dpdk_pre_cb {
	# clean hugepages
	rm -rf /dev/hugepages/*
}

function odp_dpdk_post_cb {
	local cores=$1

	systemctl status nginx
	echo "-- AFFINITY $cores"
	for pid in $(pgrep nginx); do
		taskset -p "$pid"
	done
}

function linux_ip_pre_cb {
	local cores=$1

	ethtool -L "$VLAND_IFACE" combined "$cores"
}

function linux_ip_post_cb {
	local cores=$1

	systemctl status nginx
	echo "-- AFFINITY $cores"
	for pid in $(pgrep nginx); do
		taskset -p "$pid"
	done
	echo "-- INTERRUPTS $cores"
	grep "$VLAND_IFACE" /proc/interrupts
	echo "--- MPSTAT $cores"
	mpstat -P ALL | cat
}

function configure_ramdisk {
	local ROOT=/www
	mkdir "$ROOT"
	mount -t tmpfs -o size=1M tmpfs "$ROOT"
	echo "-- Ramdisk created: "
	df -h "$ROOT"
	echo "-- END"
	lava-test-case server_www_ramdisk --result pass

	cat > "$ROOT/index.html" <<-EOF
	<html>
	<head><title>NGiNX test</title></head>
	<body>
	IT WORKS
	</body>
	</html>
	EOF
}

function write_config {
	# Simple configuration file for NGiNX
	cat > /etc/nginx/nginx.conf <<-EOF
	user www-data;
	worker_processes $1;
	timer_resolution 1s;
	worker_rlimit_nofile 4096;
	error_log /dev/null crit;
	pid /run/nginx.pid;
	${WRITE_CONFIG_CORE}

	events {
	    worker_connections 1024;
	    ${WRITE_CONFIG_EVENTS}
	}

	http {
	    access_log off;
	    sendfile on;
	    tcp_nopush on;
	    tcp_nodelay on;
	    keepalive_timeout 0;
	    open_file_cache max=10;
	    server {
	        # TODO: investigate backlog value
	        listen ${SERVER_IP}:80 default_server ${REUSEPORT} so_keepalive=off;
	        location / {
	            root /www;
	        }
	    }
	}
	EOF
	echo "-- CONFIG FOR $1:"
	cat /etc/nginx/nginx.conf
	echo "-- END --"
}

function get_num_real_cores {
	local cores_socket
	local num_sockets
	local num_cores

	cores_socket=$(lscpu | awk -F : '/^Core\(s\) per/ {print $2;}')
	num_sockets=$(lscpu | awk -F : '/^Socket\(s\)/ {print $2;}')
	num_cores=$((cores_socket * num_sockets))

	if [ "${MAX_CORES}" -ne 0 ] && [ "${num_cores}" -gt "${MAX_CORES}" ]; then
		num_cores=$MAX_CORES
	fi
	echo "$num_cores"
}

configure_ramdisk

case ${CONFIG_TYPE} in
	linux-ip)
		echo "-- CONFIGURING Linux Kernel IP stack"
		config_linux_ip
		PRE_TEST_CB="linux_ip_pre_cb"
		POST_TEST_CB="linux_ip_post_cb"
		WRITE_CONFIG_CORE="worker_cpu_affinity auto;"
		WRITE_CONFIG_EVENTS=""
		REUSEPORT="reuseport"
		;;
	odp-dpdk)
		echo "-- CONFIGURING OFP IP Stack"
		config_dpdk_dev igb_uio
		PRE_TEST_CB="odp_dpdk_pre_cb"
		POST_TEST_CB="odp_dpdk_post_cb"
		WRITE_CONFIG_CORE=""
		WRITE_CONFIG_EVENTS="use select;"
		REUSEPORT=""
		;;
	*)
		echo "Invalid CONFIG_TYPE: $CONFIG_TYPE"
		exit 1
		;;
esac

NUM_CORES=$(get_num_real_cores)
echo ">> SEND num_cores cores=$NUM_CORES"
lava-send num_cores cores="$NUM_CORES"

echo "<< WAIT client_ready"
lava-wait client_ready

for num_cores in 1 $(seq 2 2 "$NUM_CORES"); do
	echo "-- BEGIN $num_cores"
	echo "-- Stopping NGiNX"
	systemctl stop nginx
	echo "-- Writing configuration file for $num_cores"
	write_config "$num_cores"
	echo "-- CALLING PRE-TEST CALLBACK $PRE_TEST_CB"
	$PRE_TEST_CB "$num_cores"
	echo "-- STARTING NGiNX for test $num_cores"
	systemctl start nginx
	echo ">> SEND server_num_cores_${num_cores}_ready"
	lava-send "server_num_cores_${num_cores}_ready"
	echo "<< WAIT client_num_cores_${num_cores}_done"
	lava-wait "client_num_cores_${num_cores}_done"
	echo "-- CALLING POST-TEST CALLBACK $POST_TEST_CB"
	$POST_TEST_CB "$num_cores"
	echo "-- END $num_cores"
done

echo "<< WAIT client_done"
lava-wait client_done
echo "A10"