Apache: Kill Certain httpd/PHP Processes in DSO

Our development team are working on a new project which involved many scripts to be executed in long time using Apache. These scripts are used to migrate and convert old database to the new database fields and formats. Most of the scripts are still under development and required me to monitor the process and terminate the process when required.

One problem when you run Apache and PHP in DSO mode (which is enabled by default when installing using yum) is we can not monitor and see the PHP process that execute the script. PHP is running as dynamic shared object under Apache so the only process you can see from the server is httpd.

We will use following example to illustrate what was happen:

OS: CentOS 6.2 64bit
PHP script URL: http://develteam.org/migration/convert.php
PHP script directory: /home/devel/public_html/migration

If you are running PHP under CGI, suPHP or FastCGI in Apache, you can easily see which PID hold the process and we can kill the process immediately. Example as below:

$ ps aux | grep convert.php | grep -v grep
devel  21003    29.0    0.4    217472    36080   ?    S   13:56   0:00   /usr/bin/php /home/devel/public_html/migration/convert.php

The PID (column no 2) is 21003 and we can use kill command to terminate the process. But when you configure PHP to be run under DSO, the same command will produce nothing as below:

$ ps aux | grep php | grep -v grep

In this case, we need to get some help from another application called lsof (list of open file). This command will produced all open directory that used by certain PID. Since we know that the PHP script is located under /home/devel/public_html/migration directory, we can use this to filter the lsof output:

$ lsof | grep /home/devel/public_html/migration
httpd   32117    nobody   cwd    DIR      8,5    12288     40142612    /home/devel/public_html/migration

From the output we can see the PID (column no 2) of the httpd process that open this directory. This indicate the process that we need to terminate. I will then use kill command to terminate the httpd process:

$ kill -9 32117

To terminate all processes which return by lsof, we can use awk to filter only column no 2 (PID) and execute kill command accordingly:

$ kill -9 `lsof | grep /home/devel/public_html/migration | awk {'print $2'}`

Now our developer team can modify and start again the PHP process for their next test.