Bug 55743

Summary: Shutdown script broken on linux when only using PID-File
Product: Tomcat 7 Reporter: Felix Becker <f.becker>
Component: PackagingAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: enhancement    
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Felix Becker 2013-11-05 11:04:11 UTC
I disabled the tomcat shutdown port on my production systems for sanity and security reasons. I'm only using the CATALINA_PID mechanism.

When shutting down the the tomcat server with ./shutdown.sh, nothing happens. I always have to use ./shutdown.sh -force which triggers an kill -9 internally.

When using "kill <tomcatpid>", the tomcat is shutting down cleanly.

In the catalina.sh i can only find kill -0 and kill -9, but no normal kill (SIGTERM).

I would expect, that the ./shutdown.sh / catalina.sh script at first sends a normal kill (15, SIGTERM), and, if the -force parameter is set, sends an kill -9 after a small timeout - but that never happens.

This problem exists with all tomcat 7 versions on 32 / 64 bit linux.
Comment 1 Christopher Schultz 2013-11-05 14:40:04 UTC
Though I don't disagree that use of CATALINA_PID should allow a normal shutdown of Tomcat when the shutdown port has been disabled (which I assume it has been in your case, even though you don't exactly say how you did it), I don't see anything in the documentation that suggests that CATALINA_PID is used to stop Tomcat under these conditions.

I'm therefore marking this as an enhancement.
Comment 2 Felix Becker 2013-11-05 14:54:37 UTC
Hi,

http://tomcat.apache.org/tomcat-7.0-doc/config/server.html 


=== Quote
Note: Disabling the shutdown port works well when Tomcat is started using Apache Commons Daemon (running as a service on Windows or with jsvc on un*xes). It cannot be used when running Tomcat with the standard shell scripts though, as it will prevent shutdown.bat|.sh and catalina.bat|.sh from stopping it gracefully.
=== End quote

Okay, the "It cannot be used when running Tomcat with the standard shell scripts though, as it will prevent shutdown.bat|.sh and catalina.bat|.sh from stopping it gracefully." describes my situation correctly.

But I'm wondering why that is implemented in this way because a normal SIGTERM causes a graceful shutdown - is there any reason why the catalina.sh doesn't send this SIGTERM?

Is there a chance that this improvement will be added to the stable line of TC7? If not i'll try to patch my catalina.sh by myself.
Comment 3 Christopher Schultz 2013-11-05 18:25:03 UTC
I wasn't objecting to you having filed this BZ issue: I was just changing the classification from BUG to ENHANCEMENT. I don't see why it couldn't be added.

Did you want to propose a patch? They are of course always welcome.

There is no good way that I know of for the Tomcat script(s) to check for a disabled shutdown in server.xml, so perhaps having another environment variable to control that behavior is appropriate. For instance, using CATALINA_PID can be reasonably used without asking catalina.sh to send a 'kill' signal to terminate the process. So, maybe a new CATALINA_KILL_TO_SHUTDOWN env var would be appropriate.
Comment 4 Mark Thomas 2013-11-08 16:33:12 UTC
It should be possible to check a return value from the call to stop(). If that is non-zero and we have a pid, try that next?
Comment 5 Konstantin Kolinko 2013-11-09 05:01:47 UTC
(In reply to Felix Becker from comment #2)
> 
> But I'm wondering why that is implemented in this way because a normal
> SIGTERM causes a graceful shutdown - is there any reason why the catalina.sh
> doesn't send this SIGTERM?
> 

1. Apache Commons Daemon stops Tomcat from the "inside". It has direct access to JVM that runs Tomcat.  Thus no need for an external connection and that is the reason why the port may be disabled.


2. Using SIGTERM is not guaranteed to be as clear as proper shutdown command. 

There may be several shutdown hooks in the JVM. They all will be started at the same time and may suffer from a race condition.

E.g. if Log4J had such a hook (very likely, but I do not know whether it has one) then it might be shut down before a web application that uses it.

(In reply to Mark Thomas from comment #4)
> It should be possible to check a return value from the call to stop(). If
> that is non-zero and we have a pid, try that next?

+1.

Catalina.stopServer() already has the necessary code and exits with return code of "1".

I was thinking whether there should be a separate return code for this use case. IMO, we do not need one. If "stopServer()" failed then Tomcat does not know that we tried to stop it and it is logical to try SIGTERM next.

One good thing is that with this we can stop Tomcats that are in the process of starting up and have not opened the shutdown port yet.
Comment 6 Mark Thomas 2014-01-13 15:28:49 UTC
This has been fixed in 8.0.x for 8.0.0 onwards and in 7.0.x for 7.0.51 onwards.