Issue Details (XML | Word | Printable)

Key: CORE-3622
Type: Improvement Improvement
Status: Reopened Reopened
Priority: Critical Critical
Assignee: Unassigned
Reporter: F.D.Castel
Votes: 2
Watchers: 4
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Classic: Stopping Windows Service leaves one or more instances of fb_inet_server.exe running

Created: 07/Oct/11 09:18 AM   Updated: 10/Oct/11 10:06 AM
Component/s: Engine
Affects Version/s: None
Fix Version/s: None

Environment: Windows Server 2003 / SP2 / x86


 Description  « Hide
Sometimes stopping Windows Service on Firebird Classic 2.5.0 can leave one or more instances of fb_inet_server.exe running.

This is highly undesirable, since it could lead one to think the database file isn't in use as the service status is "Stopped". A database file copy or file-level backup in this state can corrupt the database (actually this DID occur once with me, and that's why I flagged this issue as "critical").

The correct behavior should be:
- (preferred) The service STOPS, no more instances left running and all database files closed ; *OR*
- The service DON'T STOP, returning an error message.

Currently, running a

    taskkill /im fb_inet_server.exe /f

can surely kill every zombie process, but I don't know how harmful this can be.

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Vlad Khorsun added a comment - 07/Oct/11 09:43 AM
This is how CS works : you can directly control listener process but not workers.
To make sure db file is closed you must shutdown database. This is the only correct way.

Nothing to fix, as for me.

Dmitry Yemanov added a comment - 07/Oct/11 09:43 AM
Stopping the service does not (and never did) shutdown working processes, so the current behavior is expected. File-level copying while the engine is accessing the database can surely corrupt the copy, but it cannot corrupt the original database. If you need to perform a file-level copy, shutdown the database instead of shutting down the service, or use ALTER DATABASE BEGIN/END BACKUP for that purpose.

I tend to think this ticket should rather be an enhancement request, as it describes a more or less "as designed" behavior.

F.D.Castel added a comment - 07/Oct/11 11:27 AM
Vlad, Dmitry,

Please correct me if I'm wrong, but to my knowledge a shutdown database ALLOWS connections from a SYSDBA/DB owner. So it will not guarantee a closed database file (or I really didn't understand what you both tried to show me, sorry)

Philosophical questions about "how it was designed/should be/bug/enhancement/etc" apart, the fact is this behavior is both unnatural and unsafe. I'm failing to see one single reason to keep it this way (could you please, enlighten me?). I really can't remember any application or service which, once stopped, continues to access his data files (!?)

Dmitry, I agree that this could not corrupt the original database, but it doesn't diminishes the problem. Some unaware user could install a new, faster, drive in his server, stop the service, copy (or, worst, move) the db file to new drive, restart the service, and use it for several hours in a production environment before he notices something went south (probably on next backup).

(And if you are now asking yourself "who would do something as dumb as this?" -- Well... Hi! Nice to meet ya! :) )

So... If my sad story above indeed broke your hearts: Windows API CreateProcess [1] has a DEBUG_PROCESS flag [2] which, when passed into dwCreationFlags parameter, turns every child processes "chained" to this process. This way, killing the root process will also kill every other process created by it. Maybe this isn't the best way to accomplish this, but it is what I'm using with success it in some servers I've made.

What about to put this DEBUG_PROCESS flag into fb_inet_server creation?

Please, remember the users! ;)

[1] http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx

Sean Leyne added a comment - 07/Oct/11 02:31 PM - edited
The current functionality is how Classic has always worked.

Adriano dos Santos Fernandes added a comment - 07/Oct/11 02:39 PM
I do think F. D. Castel is correct. If service stopped successfully, it's expected that Firebird is then down.

Anything different than that smells like bug.

Dmitry Yemanov added a comment - 07/Oct/11 04:43 PM
Reopened for further discussion. I'm not really sure whether it should be treated as a bug or as a room for improvement, but I do agree that shutting down the listener should also shut down the workers. Hereby I suggest to accept this ticket.

Dmitry Yemanov added a comment - 07/Oct/11 04:44 PM
F. D. Castel, a database shutdown has three modes starting with Firebird 2.0. And the "full shutdown" mode doesn't allow any connections, even SYSDBA ones.

Paul Reeves added a comment - 07/Oct/11 05:34 PM
IMO this bug should be re-stated. There are two problems here.

1/ As reported shutting classic down on Windows just kills the listener process. Extant connections remain. This screws up maintenance (like software upgrade, integration with the cpl applet) and means that starting a new instance of the listener doesn't work correctly (or at least it didn't used to - maybe that was fixed. Can't remember.)

However, at least active connections have to be forcibly closed by an admin that knows how to use taskkill.

2/ With Super server we have the opposite - stopping the service will kill all connections. Without any warning.

Both these issues should be fixed. It should not be possible to 'accidentally' stop any engine flavour via the Windows services api if there are active connections. And it should be possible to forcibly bring take all instances down with a single extra switch such as -f[orce].


F.D.Castel added a comment - 09/Oct/11 04:28 AM
Dmitry: Thanks! I was unaware of that.

---

Paul: I understand your care with existing connections in this case. But IMHO a service stop command, per se, already is a "brute force" way.

I cannot imagine a single reason to keep it honoring existing connections. When the sysadmin requests a service to stop, he/she must have a good reason. If a "softer" solution is needed, he could use FB shutdown modes instead.

And, again using others databases/applications as benchmark, I don't remember any service which cares of current requests when asked to shuts itself off.

It is really annoying when you, after asking for a service stop, get an error message saying some futile reasons to NOT stop it -- and keeps itself running. That's why I suggested (on my first message) we don't follow this way. A locomotive emergency brake must stop the car at any cost, without asking "Are you sure? People on this train could be late for work..."

F.D.Castel added a comment - 09/Oct/11 04:38 AM
Removed affected versions. Changed issue type to "improvement"

F.D.Castel added a comment - 09/Oct/11 04:40 AM
BTW: Some comments about the DEBUG_PROCESS flag?

And what about the other ports? By Vlad/Dmitry/Sean comments I understand this is the current behavior on every port, since it is by design (at first I thought it was a bug in the Windows port)

In this case, a more portable (albeit not so clean) solution would be to dispatch a taskkill/pskill for every fb_inet_server on service stop.

F.D.Castel added a comment - 09/Oct/11 04:42 AM
Bad idea. Pskill "solution" would also kill every other instance of Firebird (in case of two or more services installed on same computer, but listening in different ports)

Vlad Khorsun added a comment - 09/Oct/11 08:58 AM
I agree that it will be good to have ability to *correctly* stop working processes by DBA request.
And this is already possible using database shutdown - since v2.5 it closed connections not waiting for client action.
Therefore i don't think this new feature should have big priority.
Also, I see no relation with listener process here.
Do you offer to stop all working Firebird processes when [x]inetd is stopped ?

> What about to put this DEBUG_PROCESS flag into fb_inet_server creation?
a) we will never kill processes as it will destroy database
b) this "solution" is not portable and prevents system from creating crash dumps

> Please, remember the users! ;)
Please, read the manuals. New shutdown modes and nbackup are present since v2.0 !

Alexander Peshkov added a comment - 10/Oct/11 07:21 AM
What about xinetd - this is absolutely other case. It's typical for unixes to leave daemons, started by xinetd, active after xinetd shutdown. Therefore people should not expect firebird processes to be closed in that case. What about windows and it's services - looks like other behavior is typical. Probably because there are not too much multiprocess windows services.

Alexander Peshkov added a comment - 10/Oct/11 07:24 AM
Certainly, use of DEBUG_PROCESS is not a solution and telling true it's nonsense for me. But probably sending some 'signal' and processing it like posix does (i.e. smart shutdown) will be very useful.

F.D.Castel added a comment - 10/Oct/11 10:06 AM
Vlad: From your answer I'm assuming Firebird Classic uses inetd in unix-like ports (which makes perfect sense, of course -- It's just me who never used FB Classic on unixes)

As Alexander said, inetd is another kind of beast (a "generic" service dispatcher). I agree that, *WHEN USING INETD*, this behavior is the expected one. If you setup a subversion server using inetd, stopping inetd won't kill svn processes. No one would to expect otherwise.

*HOWEVER*, if you do the same setup using SVNSERVE, that's a completely different thing: stopping svnserve would terminate all current requests ASAP and exit.

It all boils down to the "principle of least surprise", here :)