You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
4.5 KiB

1 year ago
  1. #!/bin/sh
  2. # vim:sw=2:ts=2:sts=2:et
  3. set -eu
  4. LC_ALL=C
  5. ME=$( basename "$0" )
  6. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  7. [ "${NGINX_ENTRYPOINT_WORKER_PROCESSES_AUTOTUNE:-}" ] || exit 0
  8. touch /etc/nginx/nginx.conf 2>/dev/null || { echo >&2 "$ME: error: can not modify /etc/nginx/nginx.conf (read-only file system?)"; exit 0; }
  9. ceildiv() {
  10. num=$1
  11. div=$2
  12. echo $(( (num + div - 1) / div ))
  13. }
  14. get_cpuset() {
  15. cpusetroot=$1
  16. cpusetfile=$2
  17. ncpu=0
  18. [ -f "$cpusetroot/$cpusetfile" ] || return 1
  19. for token in $( tr ',' ' ' < "$cpusetroot/$cpusetfile" ); do
  20. case "$token" in
  21. *-*)
  22. count=$( seq $(echo "$token" | tr '-' ' ') | wc -l )
  23. ncpu=$(( ncpu+count ))
  24. ;;
  25. *)
  26. ncpu=$(( ncpu+1 ))
  27. ;;
  28. esac
  29. done
  30. echo "$ncpu"
  31. }
  32. get_quota() {
  33. cpuroot=$1
  34. ncpu=0
  35. [ -f "$cpuroot/cpu.cfs_quota_us" ] || return 1
  36. [ -f "$cpuroot/cpu.cfs_period_us" ] || return 1
  37. cfs_quota=$( cat "$cpuroot/cpu.cfs_quota_us" )
  38. cfs_period=$( cat "$cpuroot/cpu.cfs_period_us" )
  39. [ "$cfs_quota" = "-1" ] && return 1
  40. [ "$cfs_period" = "0" ] && return 1
  41. ncpu=$( ceildiv "$cfs_quota" "$cfs_period" )
  42. [ "$ncpu" -gt 0 ] || return 1
  43. echo "$ncpu"
  44. }
  45. get_quota_v2() {
  46. cpuroot=$1
  47. ncpu=0
  48. [ -f "$cpuroot/cpu.max" ] || return 1
  49. cfs_quota=$( cut -d' ' -f 1 < "$cpuroot/cpu.max" )
  50. cfs_period=$( cut -d' ' -f 2 < "$cpuroot/cpu.max" )
  51. [ "$cfs_quota" = "max" ] && return 1
  52. [ "$cfs_period" = "0" ] && return 1
  53. ncpu=$( ceildiv "$cfs_quota" "$cfs_period" )
  54. [ "$ncpu" -gt 0 ] || return 1
  55. echo "$ncpu"
  56. }
  57. get_cgroup_v1_path() {
  58. needle=$1
  59. found=
  60. foundroot=
  61. mountpoint=
  62. [ -r "/proc/self/mountinfo" ] || return 1
  63. [ -r "/proc/self/cgroup" ] || return 1
  64. while IFS= read -r line; do
  65. case "$needle" in
  66. "cpuset")
  67. case "$line" in
  68. *cpuset*)
  69. found=$( echo "$line" | cut -d ' ' -f 4,5 )
  70. break
  71. ;;
  72. esac
  73. ;;
  74. "cpu")
  75. case "$line" in
  76. *cpuset*)
  77. ;;
  78. *cpu,cpuacct*|*cpuacct,cpu|*cpuacct*|*cpu*)
  79. found=$( echo "$line" | cut -d ' ' -f 4,5 )
  80. break
  81. ;;
  82. esac
  83. esac
  84. done << __EOF__
  85. $( grep -F -- '- cgroup ' /proc/self/mountinfo )
  86. __EOF__
  87. while IFS= read -r line; do
  88. controller=$( echo "$line" | cut -d: -f 2 )
  89. case "$needle" in
  90. "cpuset")
  91. case "$controller" in
  92. cpuset)
  93. mountpoint=$( echo "$line" | cut -d: -f 3 )
  94. break
  95. ;;
  96. esac
  97. ;;
  98. "cpu")
  99. case "$controller" in
  100. cpu,cpuacct|cpuacct,cpu|cpuacct|cpu)
  101. mountpoint=$( echo "$line" | cut -d: -f 3 )
  102. break
  103. ;;
  104. esac
  105. ;;
  106. esac
  107. done << __EOF__
  108. $( grep -F -- 'cpu' /proc/self/cgroup )
  109. __EOF__
  110. case "${found%% *}" in
  111. "/")
  112. foundroot="${found##* }$mountpoint"
  113. ;;
  114. "$mountpoint")
  115. foundroot="${found##* }"
  116. ;;
  117. esac
  118. echo "$foundroot"
  119. }
  120. get_cgroup_v2_path() {
  121. found=
  122. foundroot=
  123. mountpoint=
  124. [ -r "/proc/self/mountinfo" ] || return 1
  125. [ -r "/proc/self/cgroup" ] || return 1
  126. while IFS= read -r line; do
  127. found=$( echo "$line" | cut -d ' ' -f 4,5 )
  128. done << __EOF__
  129. $( grep -F -- '- cgroup2 ' /proc/self/mountinfo )
  130. __EOF__
  131. while IFS= read -r line; do
  132. mountpoint=$( echo "$line" | cut -d: -f 3 )
  133. done << __EOF__
  134. $( grep -F -- '0::' /proc/self/cgroup )
  135. __EOF__
  136. case "${found%% *}" in
  137. "")
  138. return 1
  139. ;;
  140. "/")
  141. foundroot="${found##* }$mountpoint"
  142. ;;
  143. "$mountpoint")
  144. foundroot="${found##* }"
  145. ;;
  146. esac
  147. echo "$foundroot"
  148. }
  149. ncpu_online=$( getconf _NPROCESSORS_ONLN )
  150. ncpu_cpuset=
  151. ncpu_quota=
  152. ncpu_cpuset_v2=
  153. ncpu_quota_v2=
  154. cpuset=$( get_cgroup_v1_path "cpuset" ) && ncpu_cpuset=$( get_cpuset "$cpuset" "cpuset.effective_cpus" ) || ncpu_cpuset=$ncpu_online
  155. cpu=$( get_cgroup_v1_path "cpu" ) && ncpu_quota=$( get_quota "$cpu" ) || ncpu_quota=$ncpu_online
  156. cgroup_v2=$( get_cgroup_v2_path ) && ncpu_cpuset_v2=$( get_cpuset "$cgroup_v2" "cpuset.cpus.effective" ) || ncpu_cpuset_v2=$ncpu_online
  157. cgroup_v2=$( get_cgroup_v2_path ) && ncpu_quota_v2=$( get_quota_v2 "$cgroup_v2" ) || ncpu_quota_v2=$ncpu_online
  158. ncpu=$( printf "%s\n%s\n%s\n%s\n%s\n" \
  159. "$ncpu_online" \
  160. "$ncpu_cpuset" \
  161. "$ncpu_quota" \
  162. "$ncpu_cpuset_v2" \
  163. "$ncpu_quota_v2" \
  164. | sort -n \
  165. | head -n 1 )
  166. sed -i.bak -r 's/^(worker_processes)(.*)$/# Commented out by '"$ME"' on '"$(date)"'\n#\1\2\n\1 '"$ncpu"';/' /etc/nginx/nginx.conf