@@ -107,37 +107,44 @@ find /usr/blueos/userdata -type f -exec chmod a+rw {} \;
107107# and ~1min30s using this strategy.
108108# From that 1min30s, the startup time is about ~25s, and originally, ~37s, meaning that the
109109# remaining (~65 seconds) is the docker shutting down, and the Linux booting up.
110+ #
111+ # Service tuple format:
112+ # NAME,MEMORY_MB,CPU_PERCENT,IO_READ_MBPS,IO_WRITE_MBPS,COMMAND
113+ # - MEMORY_MB: Memory limit in MB (0 = no limit)
114+ # - CPU_PERCENT: CPU limit as percentage (100 = 1 core, 200 = 2 cores, 0 = no limit)
115+ # - IO_READ_MBPS: I/O read limit in MB/s (0 = no limit)
116+ # - IO_WRITE_MBPS: I/O write limit in MB/s (0 = no limit)
110117PRIORITY_SERVICES=(
111- ' autopilot' ,0," nice --19 $SERVICES_PATH /ardupilot_manager/main.py"
112- ' cable_guy' ,0," $SERVICES_PATH /cable_guy/main.py"
113- ' video' ,0," nice --19 mavlink-camera-manager --default-settings BlueROVUDP --mavlink tcpout:127.0.0.1:5777 --mavlink-system-id $MAV_SYSTEM_ID --mavlink-camera-component-id-range=100-105 --gst-feature-rank omxh264enc=0,v4l2h264enc=250,x264enc=260 --log-path /var/logs/blueos/services/mavlink-camera-manager --stun-server stun://stun.l.google.com:19302 --zenoh --verbose"
114- ' mavlink2rest' ,0," mavlink2rest --connect=udpout:127.0.0.1:14001 --server [::]:6040 --system-id $MAV_SYSTEM_ID --component-id $MAV_COMPONENT_ID_ONBOARD_COMPUTER4 "
118+ ' autopilot' ,0,0,0,0, " nice --19 $SERVICES_PATH /ardupilot_manager/main.py"
119+ ' cable_guy' ,0,0,0,0, " $SERVICES_PATH /cable_guy/main.py"
120+ ' video' ,0,0,0,0, " nice --19 mavlink-camera-manager --default-settings BlueROVUDP --mavlink tcpout:127.0.0.1:5777 --mavlink-system-id $MAV_SYSTEM_ID --mavlink-camera-component-id-range=100-105 --gst-feature-rank omxh264enc=0,v4l2h264enc=250,x264enc=260 --log-path /var/logs/blueos/services/mavlink-camera-manager --stun-server stun://stun.l.google.com:19302 --zenoh --verbose"
121+ ' mavlink2rest' ,0,0,0,0, " mavlink2rest --connect=udpout:127.0.0.1:14001 --server [::]:6040 --system-id $MAV_SYSTEM_ID --component-id $MAV_COMPONENT_ID_ONBOARD_COMPUTER4 "
115122)
116123
117124SERVICES=(
118125 # This services are not prioritized because they are not fundamental for the vehicle to work
119- ' kraken' ,0," nice -19 $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /kraken/main.py"
120- ' wifi' ,0," nice -19 $SERVICES_PATH /wifi/main.py --socket wlan0"
121- ' zenohd' ,0," ZENOH_BACKEND_FS_ROOT=$TOOLS_PATH /zenoh zenohd -c $TOOLS_PATH /zenoh/blueos-zenoh.json5"
126+ ' kraken' ,0,0,0,0, " nice -19 $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /kraken/main.py"
127+ ' wifi' ,0,0,0,0, " nice -19 $SERVICES_PATH /wifi/main.py --socket wlan0"
128+ ' zenohd' ,0,0,0,0, " ZENOH_BACKEND_FS_ROOT=$TOOLS_PATH /zenoh zenohd -c $TOOLS_PATH /zenoh/blueos-zenoh.json5"
122129 # This services are not as important as the others
123- ' beacon' ,250," $SERVICES_PATH /beacon/main.py"
124- ' bridget' ,0," nice -19 $RUN_AS_REGULAR_USER_BEGIN $SERVICES_PATH /bridget/main.py $RUN_AS_REGULAR_USER_END "
125- ' commander' ,250," $SERVICES_PATH /commander/main.py"
126- ' nmea_injector' ,250," nice -19 $SERVICES_PATH /nmea_injector/main.py"
127- ' helper' ,250," $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /helper/main.py"
128- ' iperf3' ,250," iperf3 --server --port 5201"
129- ' linux2rest' ,250," linux2rest --log-settings netstat=30,platform=10,serial-ports=10,cpu=10,disk=30,info=10,memory=10,network=10,process=60,temperature=10,unix-time-seconds=10,usb=60"
130- ' filebrowser' ,250," nice -19 filebrowser --database /etc/filebrowser/filebrowser.db --baseurl /file-browser"
131- ' versionchooser' ,0," $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /versionchooser/main.py"
132- ' pardal' ,250," nice -19 $SERVICES_PATH /pardal/main.py"
133- ' ping' ,0," nice -19 $RUN_AS_REGULAR_USER_BEGIN $SERVICES_PATH /ping/main.py $RUN_AS_REGULAR_USER_END "
134- ' user_terminal' ,0," cat /etc/motd"
135- ' ttyd' ,250,' nice -19 ttyd -p 8088 sh -c "/usr/bin/tmux attach -t user_terminal || /usr/bin/tmux new -s user_terminal"'
136- ' nginx' ,250," nice -18 nginx -g \" daemon off;\" -c $TOOLS_PATH /nginx/nginx.conf"
137- ' bag_of_holding' ,250," $SERVICES_PATH /bag_of_holding/main.py"
138- ' recorder' ,250," blueos-recorder --recorder-path /usr/blueos/userdata/recorder"
139- ' recorder_extractor' ,250," $SERVICES_PATH /recorder_extractor/main.py"
140- ' disk_usage' ,250," $SERVICES_PATH /disk_usage/main.py"
130+ ' beacon' ,250,0,0,0, " $SERVICES_PATH /beacon/main.py"
131+ ' bridget' ,0,0,0,0, " nice -19 $RUN_AS_REGULAR_USER_BEGIN $SERVICES_PATH /bridget/main.py $RUN_AS_REGULAR_USER_END "
132+ ' commander' ,250,0,0,0, " $SERVICES_PATH /commander/main.py"
133+ ' nmea_injector' ,250,0,0,0, " nice -19 $SERVICES_PATH /nmea_injector/main.py"
134+ ' helper' ,250,0,0,0, " $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /helper/main.py"
135+ ' iperf3' ,250,0,0,0, " iperf3 --server --port 5201"
136+ ' linux2rest' ,250,0,0,0, " linux2rest --log-settings netstat=30,platform=10,serial-ports=10,cpu=10,disk=30,info=10,memory=10,network=10,process=60,temperature=10,unix-time-seconds=10,usb=60"
137+ ' filebrowser' ,250,0,0,0, " nice -19 filebrowser --database /etc/filebrowser/filebrowser.db --baseurl /file-browser"
138+ ' versionchooser' ,0,0,0,0, " $BLUEOS_PYTHON_BIN_SECONDARY $SERVICES_PATH /versionchooser/main.py"
139+ ' pardal' ,250,0,0,0, " nice -19 $SERVICES_PATH /pardal/main.py"
140+ ' ping' ,0,0,0,0, " nice -19 $RUN_AS_REGULAR_USER_BEGIN $SERVICES_PATH /ping/main.py $RUN_AS_REGULAR_USER_END "
141+ ' user_terminal' ,0,0,0,0, " cat /etc/motd"
142+ ' ttyd' ,250,0,0,0, ' nice -19 ttyd -p 8088 sh -c "/usr/bin/tmux attach -t user_terminal || /usr/bin/tmux new -s user_terminal"'
143+ ' nginx' ,250,0,0,0, " nice -18 nginx -g \" daemon off;\" -c $TOOLS_PATH /nginx/nginx.conf"
144+ ' bag_of_holding' ,250,0,0,0, " $SERVICES_PATH /bag_of_holding/main.py"
145+ ' recorder' ,250,0,0,0, " blueos-recorder --recorder-path /usr/blueos/userdata/recorder"
146+ ' recorder_extractor' ,250,0,0,0, " $SERVICES_PATH /recorder_extractor/main.py"
147+ ' disk_usage' ,250,0,0,0, " $SERVICES_PATH /disk_usage/main.py"
141148)
142149
143150tmux -f /etc/tmux.conf start-server
@@ -147,10 +154,29 @@ function create_service {
147154 SESSION_NAME=" $1 :0"
148155 SERVICE_NAME=" $1 "
149156 local command=" $2 " # Store the command as a string
150- local memory_limit_mb=$3
157+ local memory_limit_mb=${3:- 0}
158+ local cpu_limit_percent=${4:- 0}
159+ local io_read_mbps=${5:- 0}
160+ local io_write_mbps=${6:- 0}
161+
162+ if [ -n " ${BLUEOS_DISABLE_RESOURCE_LIMITS} " ]; then
163+ memory_limit_mb=0
164+ cpu_limit_percent=0
165+ io_read_mbps=0
166+ io_write_mbps=0
167+ fi
151168
152169 if [ -n " ${BLUEOS_DISABLE_MEMORY_LIMIT} " ]; then
153- memory_limit_mb=$TOTAL_RAM_MB
170+ memory_limit_mb=0
171+ fi
172+
173+ if [ -n " ${BLUEOS_DISABLE_CPU_LIMIT} " ]; then
174+ cpu_limit_percent=0
175+ fi
176+
177+ if [ -n " ${BLUEOS_DISABLE_IO_LIMIT} " ]; then
178+ io_read_mbps=0
179+ io_write_mbps=0
154180 fi
155181
156182 # Check if the service is disabled
@@ -159,16 +185,18 @@ function create_service {
159185 tmux send-keys -t $SESSION_NAME " echo 'Service $1 is disabled'; sleep infinity" C-m
160186 return
161187 fi
162- echo " Service: $NAME : $EXECUTABLE with memory limit: $memory_limit_mb MB "
188+ echo " Service: $SERVICE_NAME : mem= ${memory_limit_mb} MB cpu= ${cpu_limit_percent} % io_r= ${io_read_mbps} MB/s io_w= ${io_write_mbps} MB/s "
163189
164190 # Set all necessary environment variables for the new tmux session
165191 for NAME in $( compgen -v | grep -e MAV_ -e BLUEOS_) ; do
166192 VALUE=${! NAME}
167193 tmux setenv -t " $SESSION_NAME " -g " $NAME " " $VALUE "
168194 done
195+ # Pass DOCKER_CGROUP for cgroup path resolution in run-service
196+ tmux setenv -t " $SESSION_NAME " -g " DOCKER_CGROUP" " $DOCKER_CGROUP "
169197
170- # Use run_service to start the service with the memory limit
171- tmux send-keys -t $SESSION_NAME " run-service '$SERVICE_NAME ' '$command ' $memory_limit_mb " C-m
198+ # Use run_service to start the service with resource limits
199+ tmux send-keys -t $SESSION_NAME " run-service '$SERVICE_NAME ' '$command ' $memory_limit_mb $cpu_limit_percent $io_read_mbps $io_write_mbps " C-m
172200}
173201
174202SSH_USER=${SSH_USER:- pi}
@@ -220,24 +248,24 @@ prepare_cgroups() {
220248 cat $DOCKER_CGROUP_PATH /cgroup.procs
221249 fi
222250
223- echo " Enabling subtree_control..."
224- echo " +memory" > $DOCKER_CGROUP_PATH /cgroup.subtree_control && echo " subtree_control enabled"
251+ echo " Enabling subtree_control for memory, cpu, and io on container cgroup ..."
252+ echo " +memory +cpu +io " > $DOCKER_CGROUP_PATH /cgroup.subtree_control && echo " subtree_control enabled on container cgroup "
225253}
226254
227255prepare_cgroups
228256
229257echo " Starting high priority services.."
230258for TUPLE in " ${PRIORITY_SERVICES[@]} " ; do
231- IFS=' ,' read -r NAME MEMORY_LIMIT_MB EXECUTABLE <<< " $TUPLE"
232- create_service " $NAME " " $EXECUTABLE " " $MEMORY_LIMIT_MB "
259+ IFS=' ,' read -r NAME MEMORY_MB CPU_PERCENT IO_READ_MBPS IO_WRITE_MBPS EXECUTABLE <<< " $TUPLE"
260+ create_service " $NAME " " $EXECUTABLE " " $MEMORY_MB " " $CPU_PERCENT " " $IO_READ_MBPS " " $IO_WRITE_MBPS "
233261done
234262
235263sleep 5
236264
237265echo " Starting other services.."
238266for TUPLE in " ${SERVICES[@]} " ; do
239- IFS=' ,' read -r NAME MEMORY_LIMIT_MB EXECUTABLE <<< " $TUPLE"
240- create_service " $NAME " " $EXECUTABLE " " $MEMORY_LIMIT_MB "
267+ IFS=' ,' read -r NAME MEMORY_MB CPU_PERCENT IO_READ_MBPS IO_WRITE_MBPS EXECUTABLE <<< " $TUPLE"
268+ create_service " $NAME " " $EXECUTABLE " " $MEMORY_MB " " $CPU_PERCENT " " $IO_READ_MBPS " " $IO_WRITE_MBPS "
241269done
242270
243271echo " BlueOS running!"
0 commit comments