# This script is intended to be ran via CRON.
# It was written to catch opcache deadlocks where opcache cannot
# kill a process owned by another user within the same FPM master.
# Read more: https://github.com/php/php-src/issues/8072
# Count all locks with ZendSem in the name and only return ones that are over 20.
lslocks | awk '/ZendSem/ {print $9}' | sort | uniq -c | awk '$1 > 20' | while read -r bad_lock; do
bad_lock_count=$(echo "${bad_lock}" | awk '{print $1}');
bad_lock_name=$(echo "${bad_lock}" | awk '{print $2}');
lslocks | grep "${bad_lock_name}" | grep READ | awk '/^php-fpm/ {print $2}' | while read -r bad_lock_pid; do
# If the string isn't empty, proceed with the kill.
if [[ -n "${bad_lock_pid}" ]]; then
echo "opcache deadlock discovered: ${bad_lock_count} active locks for ${bad_lock_name} - sending kill: ${bad_lock_pid}" | systemd-cat -p info;
kill -9 "${bad_lock_pid}"