#!/bin/bash { #//////////////////////////////////// # DietPi Process Tool # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com # #//////////////////////////////////// # # Info: # - Menu system that allows users to configure and set system wide process/program attributes: Nice, Affinity, Scheduler Policy/Priority. # - Called from /DietPi/dietpi/dietpi-services start (eg: after all installed dietpi-software has been started) # # Usage: # dietpi-process_tool 0/no input = Menu # dietpi-process_tool 1 = Apply #//////////////////////////////////// #Grab Input INPUT=0 if [[ $1 =~ ^-?[0-9]+$ ]]; then INPUT=$1 fi #Import DietPi-Globals --------------------------------------------------------------- . /DietPi/dietpi/func/dietpi-globals G_CHECK_ROOT_USER export G_PROGRAM_NAME='DietPi-Process_tool' #Import DietPi-Globals --------------------------------------------------------------- #///////////////////////////////////////////////////////////////////////////////////// # Globals #///////////////////////////////////////////////////////////////////////////////////// EXIT_CODE=0 MAX_PROGRAMS=0 aNICE=() aAFFINITY=() aSCHEDULE_POLICY=() aSCHEDULE_PRIORITY=() aPID=() aNAME=() aPROCESS_NAME=() aAVAILABLE=() aSCHEDULE_AVAILABLE_POLICY=() aSCHEDULE_AVAILABLE_PRIORITY_MIN=() aSCHEDULE_AVAILABLE_PRIORITY_MAX=() MAX_SCHEDULE_POLICIES=0 Apply_Process_Tool(){ G_DIETPI-NOTIFY 3 DietPi-Process_Tool Apply local status_text="" local status_text_ok="$(G_DIETPI-NOTIFY 0)" local status_text_failed="$(G_DIETPI-NOTIFY 1)" for ((i=0; i<$MAX_PROGRAMS; i++)) do if (( ${aAVAILABLE[$i]} == 1 )); then # - Find all processes with target name cat "$FP_PS_LIST" | grep "${aPROCESS_NAME[$i]}" | awk '{print $1}' > "$FP_TEMP" while read -r line do #Obtain PID aPID[$i]=$line #info echo -e "${aNAME[$i]} (${aPID[$i]})" # - Check if PID exists (this can occur with programs like netdata that run as root initally, create a new process under a different user, then terminate the original root process. if (( ! $( ps ax | awk '{print $1}' | grep -ci -m1 "${aPID[$i]}") )); then G_DIETPI-NOTIFY 2 PID "${aPID[$i]}" no longer exists else # - nice renice -n ${aNICE[$i]} ${aPID[$i]} &> /dev/null if (( $? == 0 )); then status_text=$status_text_ok else status_text=$status_text_failed EXIT_CODE=1 fi status_text+="\e[90mNice ${aNICE[$i]}\e[0m" echo -e "$status_text" # - Affinity taskset -pc ${aAFFINITY[$i]} ${aPID[$i]} &> /dev/null if (( $? == 0 )); then status_text=$status_text_ok else status_text=$status_text_failed EXIT_CODE=2 fi status_text+="\e[90mAffinity ${aAFFINITY[$i]}\e[0m" echo -e "$status_text" # - schedule # -- Match scheduler policy to array list of available for ((j=0; j<$MAX_SCHEDULE_POLICIES; j++)) do if [ "${aSCHEDULE_POLICY[$i]}" = "${aSCHEDULE_AVAILABLE_POLICY[$j]}" ]; then # -- cap to min/max against array of available if (( ${aSCHEDULE_PRIORITY[$i]} < ${aSCHEDULE_AVAILABLE_PRIORITY_MIN[$j]} )) || (( ${aSCHEDULE_PRIORITY[$i]} > ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$j]} )); then aSCHEDULE_PRIORITY[$i]=${aSCHEDULE_AVAILABLE_PRIORITY_MIN[$j]} fi break fi done local chrt_mode='' if [ "${aSCHEDULE_POLICY[$i]}" = "SCHED_OTHER" ]; then chrt_mode='-o' elif [ "${aSCHEDULE_POLICY[$i]}" = "SCHED_FIFO" ]; then chrt_mode='-f' elif [ "${aSCHEDULE_POLICY[$i]}" = "SCHED_RR" ]; then chrt_mode='-r' elif [ "${aSCHEDULE_POLICY[$i]}" = "SCHED_BATCH" ]; then chrt_mode='-b' elif [ "${aSCHEDULE_POLICY[$i]}" = "SCHED_IDLE" ]; then chrt_mode='-i' fi # - Apply chrt $chrt_mode -p ${aSCHEDULE_PRIORITY[$i]} ${aPID[$i]} &> /dev/null if (( $? == 0 )); then status_text=$status_text_ok else status_text=$status_text_failed EXIT_CODE=3 fi status_text+="\e[90mScheduler ${aSCHEDULE_POLICY[$i]} ${aSCHEDULE_PRIORITY[$i]}\e[0m" echo -e "$status_text" fi done < "$FP_TEMP" rm "$FP_TEMP" fi done echo -e "" } #///////////////////////////////////////////////////////////////////////////////////// # Init #///////////////////////////////////////////////////////////////////////////////////// Init(){ #-------------------------------------------------------------------------------- #Init array local index=0 aNAME[$index]='Aria2';aPROCESS_NAME[$index]='aria2c';((index++)) aNAME[$index]='Avahi Daemon';aPROCESS_NAME[$index]='avahi-daemon';((index++)) aNAME[$index]='Bluetooth (Service)';aPROCESS_NAME[$index]='bluetooth';((index++)) aNAME[$index]='Bluetooth (Hciuart)';aPROCESS_NAME[$index]='hciattach';((index++)) aNAME[$index]='Blynk Server';aPROCESS_NAME[$index]='blynkserver';((index++)) aNAME[$index]='BruteFIR';aPROCESS_NAME[$index]='brutefir';((index++)) aNAME[$index]='CAVA';aPROCESS_NAME[$index]='cava';((index++)) aNAME[$index]='Cuberite';aPROCESS_NAME[$index]='Cuberite';((index++)) aNAME[$index]='CloudPrint';aPROCESS_NAME[$index]='cloudprintd';((index++)) aNAME[$index]='CouchPotato';aPROCESS_NAME[$index]='CouchPotato.py';((index++)) aNAME[$index]='Cron';aPROCESS_NAME[$index]='cron';((index++)) aNAME[$index]='CUPS';aPROCESS_NAME[$index]='cupsd';((index++)) aNAME[$index]='DarkIce';aPROCESS_NAME[$index]='darkice';((index++)) aNAME[$index]='Deluge (Daemon)';aPROCESS_NAME[$index]='deluged';((index++)) aNAME[$index]='Deluge (Web interface)';aPROCESS_NAME[$index]='deluge-web';((index++)) aNAME[$index]='DHCP Client';aPROCESS_NAME[$index]='dhclient';((index++)) aNAME[$index]='DHCP Server';aPROCESS_NAME[$index]='dhcpd';((index++)) aNAME[$index]='Docker';aPROCESS_NAME[$index]='docker';((index++)) aNAME[$index]='Dropbear';aPROCESS_NAME[$index]='dropbear';((index++)) aNAME[$index]='Emby Server';aPROCESS_NAME[$index]='emby-server';((index++)) aNAME[$index]='EmonHUB';aPROCESS_NAME[$index]='emonhub';((index++)) aNAME[$index]='Fail2Ban';aPROCESS_NAME[$index]='fail2ban-server';((index++)) aNAME[$index]='FuguHub';aPROCESS_NAME[$index]='bdd';((index++)) aNAME[$index]='Gitea';aPROCESS_NAME[$index]='gitea';((index++)) aNAME[$index]='Gogs';aPROCESS_NAME[$index]='gogs';((index++)) aNAME[$index]='Google AIY';aPROCESS_NAME[$index]='main.py';((index++)) aNAME[$index]='Gmediarender';aPROCESS_NAME[$index]='gmediarender';((index++)) aNAME[$index]='Home Assistant';aPROCESS_NAME[$index]='hass';((index++)) aNAME[$index]='HTPC Manager';aPROCESS_NAME[$index]='Htpc.py';((index++)) aNAME[$index]='IceCast';aPROCESS_NAME[$index]='icecast2';((index++)) aNAME[$index]='MPD';aPROCESS_NAME[$index]='bin/mpd';((index++)) #Tomcat8 triggers 'mpd' aNAME[$index]='YMPD (HiFi)';aPROCESS_NAME[$index]='ympd';((index++)) aNAME[$index]='Jackett';aPROCESS_NAME[$index]='JackettConsole.exe';((index++)) aNAME[$index]='Jack Server';aPROCESS_NAME[$index]='jackd';((index++)) aNAME[$index]='Jconvolver';aPROCESS_NAME[$index]='jconvolver';((index++)) aNAME[$index]='Minio';aPROCESS_NAME[$index]='minio';((index++)) aNAME[$index]='MiniDLNA';aPROCESS_NAME[$index]='minidlna';((index++)) #aNAME[$index]='moOde (worker.php)';aPROCESS_NAME[$index]='worker.php';((index++)) aNAME[$index]='Mopidy';aPROCESS_NAME[$index]='mopidy';((index++)) aNAME[$index]='Mosquitto';aPROCESS_NAME[$index]='mosquitto';((index++)) aNAME[$index]='MotionEye';aPROCESS_NAME[$index]='motioneye';((index++)) aNAME[$index]='Mumble Server';aPROCESS_NAME[$index]='murmurd';((index++)) aNAME[$index]='NAA Daemon';aPROCESS_NAME[$index]='networkaudiod';((index++)) aNAME[$index]='NetData';aPROCESS_NAME[$index]='netdata';((index++)) aNAME[$index]='Nukkit';aPROCESS_NAME[$index]='nukkit.jar';((index++)) aNAME[$index]='Node-Red';aPROCESS_NAME[$index]='node-red';((index++)) aNAME[$index]='NoIp';aPROCESS_NAME[$index]='noip2';((index++)) aNAME[$index]='NZBget';aPROCESS_NAME[$index]='nzbget';((index++)) aNAME[$index]='OctoPrint';aPROCESS_NAME[$index]='octoprint';((index++)) aNAME[$index]='OpenBazaar';aPROCESS_NAME[$index]='openbazaard.py';((index++)) aNAME[$index]='Open Media Vault';aPROCESS_NAME[$index]='omv-engined';((index++)) aNAME[$index]='OpenSSH Server';aPROCESS_NAME[$index]='sshd';((index++)) aNAME[$index]='OpenVPN Server';aPROCESS_NAME[$index]='openvpn';((index++)) aNAME[$index]='Pi-SPC';aPROCESS_NAME[$index]='sds.sh';((index++)) aNAME[$index]='Pi-hole';aPROCESS_NAME[$index]='dnsmasq';((index++)) aNAME[$index]='Pi-hole FTL';aPROCESS_NAME[$index]='pihole-FTL';((index++)) aNAME[$index]='ProFTP';aPROCESS_NAME[$index]='proftpd';((index++)) aNAME[$index]='qBitTorrent';aPROCESS_NAME[$index]='qbittorrent-nox';((index++)) aNAME[$index]='Radarr';aPROCESS_NAME[$index]='Radarr.exe';((index++)) aNAME[$index]='Raspotify';aPROCESS_NAME[$index]='librespot';((index++)) aNAME[$index]='RoonBridge';aPROCESS_NAME[$index]='RoonBridge';((index++)) aNAME[$index]='RoonBridge (Helper)';aPROCESS_NAME[$index]='RoonBridgeHelper';((index++)) aNAME[$index]='RoonBridge/Server (RAATServer)';aPROCESS_NAME[$index]='RAATServer';((index++)) aNAME[$index]='RoonBridge/Server (Appliance)';aPROCESS_NAME[$index]='RoonAppliance';((index++)) aNAME[$index]='RoonServer';aPROCESS_NAME[$index]='RoonServer';((index++)) aNAME[$index]='rTorrent';aPROCESS_NAME[$index]='rtorrent';((index++)) aNAME[$index]='SABnzbd';aPROCESS_NAME[$index]='SABnzbd.py';((index++)) aNAME[$index]='Samba Server (Daemon)';aPROCESS_NAME[$index]='smbd';((index++)) aNAME[$index]='Samba Server (NetBios)';aPROCESS_NAME[$index]='nmbd';((index++)) aNAME[$index]='Shairport Sync';aPROCESS_NAME[$index]='shairport-sync';((index++)) aNAME[$index]='SickRage';aPROCESS_NAME[$index]='SickBeard.py';((index++)) aNAME[$index]='Sonarr';aPROCESS_NAME[$index]='NzbDrone.exe';((index++)) aNAME[$index]='Spotify Connect Web';aPROCESS_NAME[$index]='spotify-connect-web';((index++)) aNAME[$index]='Supervisor';aPROCESS_NAME[$index]='supervisor';((index++)) aNAME[$index]='Squeezebox Server (LMS)';aPROCESS_NAME[$index]='squeezeboxserver';((index++)) aNAME[$index]='Squeezelite';aPROCESS_NAME[$index]='squeezelite';((index++)) aNAME[$index]='Syncthing';aPROCESS_NAME[$index]='syncthing';((index++)) aNAME[$index]='Syncthing-inotify';aPROCESS_NAME[$index]='syncthing-inotify';((index++)) aNAME[$index]='Tomcat8';aPROCESS_NAME[$index]='tomcat8';((index++)) aNAME[$index]='Tonido';aPROCESS_NAME[$index]='tonidoconsole';((index++)) aNAME[$index]='Transmission';aPROCESS_NAME[$index]='transmission-daemon';((index++)) aNAME[$index]='AmiBerry';aPROCESS_NAME[$index]='amiberry';((index++)) aNAME[$index]='UrBackup Server';aPROCESS_NAME[$index]='urbackupsrv';((index++)) aNAME[$index]='Webserver Apache2';aPROCESS_NAME[$index]='apache2';((index++)) aNAME[$index]='Webserver Nginx';aPROCESS_NAME[$index]='nginx';((index++)) aNAME[$index]='Webserver Lighttpd';aPROCESS_NAME[$index]='lighttpd';((index++)) aNAME[$index]='Webserver MariaDB';aPROCESS_NAME[$index]='mariadb';((index++)) aNAME[$index]='Webserver MySql';aPROCESS_NAME[$index]='mysqld';((index++)) aNAME[$index]='Webserver Php-fpm';aPROCESS_NAME[$index]='php-fpm';((index++)) aNAME[$index]='Webserver Redis';aPROCESS_NAME[$index]='redis-server';((index++)) aNAME[$index]='WiFi Hotspot';aPROCESS_NAME[$index]='hostapd';((index++)) aNAME[$index]='WiFi Monitor';aPROCESS_NAME[$index]='dietpi-wifi-monitor.sh';((index++)) aNAME[$index]='VirtualHere';aPROCESS_NAME[$index]='vhusbd';((index++)) aNAME[$index]='YaCy search engine';aPROCESS_NAME[$index]='yacy';((index++)) MAX_PROGRAMS=${#aNAME[@]} # - Find out which programs are running (impies installed) | exclude kernel threads ([]) ps ax | grep -v '\[' > "$FP_PS_LIST" # - Enable affinity for all cores and all programs by default local init_affinity_value=0 if (( $(nproc --all) > 1 )); then init_affinity_value="0-$(( $(nproc --all) - 1))" fi # - Init other arrays for ((i=0; i<$MAX_PROGRAMS; i++)) do aNICE[$i]=0 aAFFINITY[$i]=$init_affinity_value aSCHEDULE_POLICY[$i]="SCHED_OTHER" aSCHEDULE_PRIORITY[$i]=0 aPID[$i]=0 aAVAILABLE[$i]=0 # - Obtain list of available programs if (( $(cat "$FP_PS_LIST" | awk '{string=""; for (i=5; i<=NF; i++) string=string $i " "; print string}' | grep -ci -m1 "${aPROCESS_NAME[$i]}") == 1 )); then aAVAILABLE[$i]=1 fi # - Apply default nice to specific programs if [ "${aPROCESS_NAME[$i]}" = "netdata" ]; then aNICE[$i]=19 fi done #Obtain list of available system schedulers/priorites chrt -m > "$FP_TEMP" index=0 while read line do # - available schedulers aSCHEDULE_AVAILABLE_POLICY[$index]=$(echo -e "$line" | awk '{print $1}') # - available priorities # -- min aSCHEDULE_AVAILABLE_PRIORITY_MIN[$index]=$(echo -e "$line" | sed 's/.*: //' | sed 's/\// /' | awk '{print $1}') # -- max aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index]=$(echo -e "$line" | sed 's/.*: //' | sed 's/\// /' | awk '{print $2}') ((index++)) done < "$FP_TEMP" MAX_SCHEDULE_POLICIES=${#aSCHEDULE_AVAILABLE_POLICY[@]} #-------------------------------------------------------------------------------- #Load Settings file. Generate if required. if [ ! -f "$FP_SETTINGS" ]; then Write_Settings_File else Read_Settings_File fi } #///////////////////////////////////////////////////////////////////////////////////// # Settings File #///////////////////////////////////////////////////////////////////////////////////// #Define Location FP_SETTINGS="/DietPi/dietpi/.dietpi-process_tool" FP_TEMP="/tmp/.dietpi-process_tool_temp" # - ps-aux > ram FP_PS_LIST="/tmp/.dietpi-process_tool_ps_list" Read_Settings_File(){ local string="" for ((i=0; i<$MAX_PROGRAMS; i++)) do #Match settings against process name local string=$( cat "$FP_SETTINGS" | grep -m1 "^${aPROCESS_NAME[$i]}") if [ -n "$string" ]; then #- nice aNICE[$i]=$( echo -e "$string" | awk '{print $2}') #- affinity aAFFINITY[$i]=$(echo -e "$string" | awk '{print $3}') #- schedule aSCHEDULE_POLICY[$i]=$(echo -e "$string" | awk '{print $4}') aSCHEDULE_PRIORITY[$i]=$(echo -e "$string" | awk '{print $5}') fi done } Write_Settings_File(){ rm "$FP_SETTINGS" &> /dev/null for ((i=0; i<$MAX_PROGRAMS; i++)) do if (( ${aAVAILABLE[$i]} == 1 )); then echo -e "${aPROCESS_NAME[$i]} ${aNICE[$i]} ${aAFFINITY[$i]} ${aSCHEDULE_POLICY[$i]} ${aSCHEDULE_PRIORITY[$i]}" >> $FP_SETTINGS fi done } #///////////////////////////////////////////////////////////////////////////////////// # Menu System #///////////////////////////////////////////////////////////////////////////////////// PROGRAM_NAME="DietPi-Process Tool" WHIP_QUESTION=0 CHOICE=0 TARGETMENUID=0 LAST_SELECTED_NAME=0 Menu_Exit(){ whiptail --title "Exit $PROGRAM_NAME?" --yesno "Exit $PROGRAM_NAME?" --backtitle "$PROGRAM_NAME" --yes-button "Ok" --no-button "Back" --defaultno 9 55 CHOICE=$? if (( $CHOICE == 0 )); then #exit TARGETMENUID=-1 else #Return to Main Menu TARGETMENUID=0 fi } #TARGETMENUID=0 Menu_Main(){ TARGETMENUID=0 local whiptail_menu_array=() for ((i=0; i<$MAX_PROGRAMS; i++)) do if (( ${aAVAILABLE[$i]} == 1 )); then whiptail_menu_array+=("${aNAME[$i]}" ": Nice ${aNICE[$i]} | Affinity ${aAFFINITY[$i]}") fi done WHIP_QUESTION='Select a program:' OPTION=$(whiptail --title "$PROGRAM_NAME" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Exit" --default-item "$LAST_SELECTED_NAME" 16 70 8 "${whiptail_menu_array[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then LAST_SELECTED_NAME=$OPTION #Find selected program index local index_current=0 for ((i=0; i<$MAX_PROGRAMS; i++)) do if [ "${aNAME[$i]}" = "$OPTION" ]; then index_current=$i break fi done #Installed? if (( ${aAVAILABLE[$index_current]} == 0 )); then whiptail --title "Not available." --msgbox "${aNAME[$index_current]} is not running and/or installed." 8 70 #Prompt for nice/affinity/schedule choice else #return back to this section. local run_loop=1 while (( $run_loop == 1 )) do #menu, choose nice/affinity etc WHIP_QUESTION="Select an option for ${aNAME[$index_current]}:" local whiptail_menu_array=() whiptail_menu_array+=("Nice" ": ${aNICE[$index_current]}") whiptail_menu_array+=("Affinity" ": ${aAFFINITY[$index_current]}") whiptail_menu_array+=("Schedule Policy" ": ${aSCHEDULE_POLICY[$index_current]}") whiptail_menu_array+=("Schedule Priority" ": ${aSCHEDULE_PRIORITY[$index_current]}") OPTION=$(whiptail --title "${aNAME[$index_current]}" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Back" 11 60 4 "${whiptail_menu_array[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then case "$OPTION" in Nice) #Get existing nice level local nice_current=0 # - note: Whiptail will not work with negative numbers. The string cannot start with "-" as it throws subscript error. nice_current="Nice : ${aNICE[$index_current]}" local whiptail_menu_array=() for ((i=-20; i<20; i++)) do local desc="" if (( $i == -20 )); then desc="(Highest priority)" elif (( $i == -10 )); then desc="(Higher priority)" elif (( $i == -5 )); then desc="(High priority)" elif (( $i == 0 )); then desc="(Default priority)" elif (( $i == 5 )); then desc="(Low priority)" elif (( $i == 10 )); then desc="(Lower priority)" elif (( $i == 19 )); then desc="(Lowest priority)" fi whiptail_menu_array+=("Nice : $i" " $desc") done WHIP_QUESTION="Please select your nice level for:\n${aNAME[$index_current]}\n\nInfo:\n - Negative values have a higher priority (eg: -10).\n - Positive values have a lower priority (eg: 15).\n - The default value is 0." OPTION=$(whiptail --title "Nice : ${aNAME[$index_current]}" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "$nice_current" 19 60 5 "${whiptail_menu_array[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then #Convert back to int aNICE[$index_current]=$(echo "$OPTION" | sed 's/[A-Za-z :]*//g') #Apply Apply_Process_Tool fi ;; Affinity) # - Get existing affinity #NB: currently enables all local whiptail_menu_array=() for ((i=0; i<$(nproc --all); i++)) do whiptail_menu_array+=("$i" "CPU " "on") done WHIP_QUESTION="Please select your CPU affinity for:\n${aNAME[$index_current]}\n\n- Use the spacebar to enable/disable access to specific cores, for this program.\n- The default value is to enable all items." whiptail --title "Affinity : ${aNAME[$index_current]}" --backtitle "$PROGRAM_NAME" --checklist --separate-output "$WHIP_QUESTION" --cancel-button "Back" 18 65 6 "${whiptail_menu_array[@]}" 2> "$FP_TEMP" CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then local new_affinity="" local loop_count=0 while read choice do if [ "$choice" != "" ]; then #taskset requires , (comma) seperated cpu index indexs after 1st entry. if (( $loop_count == 0 )); then new_affinity+="$choice" #Add comma for future entries else new_affinity+=",$choice" fi ((loop_count++)) fi done < "$FP_TEMP" #Update affinity array with new value, if at least 1 item was selected. if [ "$new_affinity" != "" ] ; then aAFFINITY[$index_current]="$new_affinity" fi #Apply Apply_Process_Tool fi rm "$FP_TEMP" &> /dev/null ;; "Schedule Policy") local whiptail_menu_array=() local description='' for ((i=0; i<$MAX_SCHEDULE_POLICIES; i++)) do # - add descriptions if [ "${aSCHEDULE_AVAILABLE_POLICY[$i]}" = "SCHED_OTHER" ]; then description='Normal (Default)' elif [ "${aSCHEDULE_AVAILABLE_POLICY[$i]}" = "SCHED_FIFO" ]; then description='First In, First Out (Real-time, time-critical)' elif [ "${aSCHEDULE_AVAILABLE_POLICY[$i]}" = "SCHED_RR" ]; then description='Round Robin (Real-time, time-critical)' elif [ "${aSCHEDULE_AVAILABLE_POLICY[$i]}" = "SCHED_BATCH" ]; then description='Batch style execution' elif [ "${aSCHEDULE_AVAILABLE_POLICY[$i]}" = "SCHED_IDLE" ]; then description='Background Jobs (Very low priority)' fi whiptail_menu_array+=("${aSCHEDULE_AVAILABLE_POLICY[$i]}" ": $description") done WHIP_QUESTION="Please select a Schedule Policy for :\n${aNAME[$index_current]}" OPTION=$(whiptail --title "Schedule Policy : ${aNAME[$index_current]}" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "${aSCHEDULE_POLICY[$index_current]}" 14 70 5 "${whiptail_menu_array[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then aSCHEDULE_POLICY[$index_current]=$OPTION #Apply Apply_Process_Tool fi ;; "Schedule Priority") #Match scheduler policy to array list local index_schedule=0 for ((i=0; i<$MAX_SCHEDULE_POLICIES; i++)) do if [ "${aSCHEDULE_POLICY[$index_current]}" = "${aSCHEDULE_AVAILABLE_POLICY[$i]}" ]; then index_schedule=$i break fi done #No priority options available if (( ( ${aSCHEDULE_AVAILABLE_PRIORITY_MIN[$index_schedule]} + ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} ) == 0 )); then whiptail --title "${aSCHEDULE_POLICY[$index_current]}" --msgbox "No priority options are available for ${aSCHEDULE_POLICY[$index_current]}." 8 60 #List available else local whiptail_menu_array=() # - 7 step description scale local scale_value_lowest=${aSCHEDULE_AVAILABLE_PRIORITY_MIN[$index_schedule]} local scale_value_lower=$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} / 6 )) local scale_value_low=$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} / 6 * 2 )) local scale_value_medium=$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} / 6 * 3 )) local scale_value_high=$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} / 6 * 4 )) local scale_value_higher=$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} / 6 * 5 )) local scale_value_highest=${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} for ((i=${aSCHEDULE_AVAILABLE_PRIORITY_MIN[$index_schedule]}; i<$(( ${aSCHEDULE_AVAILABLE_PRIORITY_MAX[$index_schedule]} + 1 )); i++)) do local description="" if (( $i == $scale_value_lowest )); then description="(Lowest priority)" elif (( $i == $scale_value_lower )); then description="(Lower priority)" elif (( $i == $scale_value_low )); then description="(Low priority)" elif (( $i == $scale_value_medium )); then description="(Medium priority)" elif (( $i == $scale_value_high )); then description="(High priority)" elif (( $i == $scale_value_higher )); then description="(Higher priority)" elif (( $i == $scale_value_highest )); then description="(Highest priority)" fi whiptail_menu_array+=("$i" ": $description") done WHIP_QUESTION="Please select a Schedule Priority level for :\n${aNAME[$index_current]}\n\n - Lower values are low priority\n - Higher values are high priority" OPTION=$(whiptail --title "Schedule Policy : ${aNAME[$index_current]}" --backtitle "$PROGRAM_NAME" --menu "$WHIP_QUESTION" --cancel-button "Back" --default-item "${aSCHEDULE_PRIORITY[$index_current]}" 18 60 5 "${whiptail_menu_array[@]}" 3>&1 1>&2 2>&3) CHOICE=$? unset whiptail_menu_array if (( $CHOICE == 0 )); then aSCHEDULE_PRIORITY[$index_current]=$OPTION #Apply Apply_Process_Tool fi fi ;; esac #Return to main menu else run_loop=0 fi done fi else Menu_Exit fi } #///////////////////////////////////////////////////////////////////////////////////// # MAIN #///////////////////////////////////////////////////////////////////////////////////// #----------------------------------------------------------------------------------- #Init Init #----------------------------------------------------------------------------------- #Run config menu if (( $INPUT == 0 )); then #Start DietPi Menu while (( $TARGETMENUID > -1 )); do clear if (( $TARGETMENUID == 0 )); then Menu_Main fi done #Save settings Write_Settings_File #Apply Process Tool elif (( $INPUT == 1 )); then Apply_Process_Tool G_DIETPI-NOTIFY -1 ${EXIT_CODE:=0} "$PROGRAM_NAME |" fi #----------------------------------------------------------------------------------- #Del tmp files rm "$FP_TEMP" &> /dev/null rm "$FP_PS_LIST" &> /dev/null #----------------------------------------------------------------------------------- #Delete[] Global arrays unset aNICE unset aAFFINITY unset aSCHEDULE_POLICY unset aSCHEDULE_PRIORITY unset aPID unset aNAME unset aPROCESS_NAME unset aAVAILABLE unset aSCHEDULE_AVAILABLE_POLICY unset aSCHEDULE_AVAILABLE_PRIORITY_MIN unset aSCHEDULE_AVAILABLE_PRIORITY_MAX #----------------------------------------------------------------------------------- exit #----------------------------------------------------------------------------------- }