1998-09-01
1998-09-01 14:00:07 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
a9d811af3b80dc44e44081703480fc5dfc5a9450
(211 lines)
(+107/-104)
[
Show
| Annotate
]
Branch: 5.2
Joined the shutdown and the restart code.
Also changed the shutdown signal from SIGQUIT to SIGTERM.
Rev: server/base_server/roxen.pike:1.231
1:
- constant cvs_version = "$Id: roxen.pike,v 1.230 1998/09/01 13:48:07 marcus Exp $";
+ constant cvs_version = "$Id: roxen.pike,v 1.231 1998/09/01 14:00:07 grubba Exp $";
// ABS and suicide systems contributed freely by Francesco Chemolli
93:
int privs_level;
int die_die_die;
- // Fork, and then do a 'slow-quit' in the forked copy. Exit the
- // original copy, after all listen ports are closed.
- // Then the forked copy can finish all current connections.
- private static void fork_or_quit()
+ void stop_all_modules()
{
- int i;
- object *f;
- int pid;
- perror("Exiting Roxen.\n");
+ foreach(configurations, object conf)
+ conf->stop();
+ }
-
+ private static void really_low_shutdown(int exit_code)
+ {
+ // Die nicely.
+
#ifdef SOCKET_DEBUG
- perror("SOCKETS: fork_or_quit()\n Bye!\n");
+ roxen_perror("SOCKETS: really_low_shutdown\n"
+ " Bye!\n");
#endif
#ifdef THREADS
stop_handler_threads();
#endif /* THREADS */
-
+ // Don't use fork() with threaded servers.
#if constant(fork) && !defined(THREADS)
-
+ // Fork, and then do a 'slow-quit' in the forked copy. Exit the
+ // original copy, after all listen ports are closed.
+ // Then the forked copy can finish all current connections.
if(fork()) {
-
+ // Kill the parent.
add_constant("roxen", 0); // Remove some extra refs...
- exit(-1); // Restart.
+
+ exit(exit_code); // Die...
}
// Now we're running in the forked copy.
131: Inside #if constant(fork) && !defined(THREADS)
f=indices(portno);
for(i=0; i<sizeof(f); i++)
catch(destruct(f[i]));
- #else /* !constant(fork) */
+ #else /* !constant(fork) || defined(THREADS) */
// FIXME:
// Should probably attempt something similar to the above,
// but this should be sufficient for the time being.
add_constant("roxen", 0); // Paranoia...
- exit(-1); // Restart
+
- #endif /* constant(fork) */
+ exit(exit_code); // Now we die...
+
+ #endif /* constant(fork) && !defined(THREADS) */
}
-
+ // Shutdown Roxen
+ // exit_code = 0 True shutdown
+ // exit_code = -1 Restart
+ private static void low_shutdown(int exit_code)
+ {
+ // Change to root user if possible ( to kill the start script... )
+ #if efun(seteuid)
+ seteuid(getuid());
+ setegid(getgid());
+ #endif
+ #if efun(setuid)
+ setuid(0);
+ #endif
+ stop_all_modules();
+
+ if(main_configuration_port && objectp(main_configuration_port))
+ {
+ // Only _really_ do something in the main process.
+ int pid;
+ if (exit_code) {
+ roxen_perror("Restarting Roxen.\n");
+ } else {
+ roxen_perror("Shutting down Roxen.\n");
+
+ // This has to be refined in some way. It is not all that nice to do
+ // it like this (write a file in /tmp, and then exit.) The major part
+ // of code to support this is in the 'start' script.
+ #ifndef __NT__
+ #ifdef USE_SHUTDOWN_FILE
+ // Fallback for systems without geteuid, Roxen will (probably)
+ // not be able to kill the start-script if this is the case.
+ rm("/tmp/Roxen_Shutdown_"+startpid);
+
+ object f;
+ f=open("/tmp/Roxen_Shutdown_"+startpid, "wc");
+
+ if(!f)
+ roxen_perror("cannot open shutdown file.\n");
+ else f->write(""+getpid());
+ #endif /* USE_SHUTDOWN_FILE */
+
+ // Try to kill the start-script.
+ if(startpid != getpid())
+ {
+ kill(startpid, signum("SIGINTR"));
+ kill(startpid, signum("SIGHUP"));
+ kill(getppid(), signum("SIGINTR"));
+ kill(getppid(), signum("SIGHUP"));
+ }
+ #endif /* !__NT__ */
+ }
+ }
+
+ call_out(really_low_shutdown, 5, exit_code);
+ }
+
+ // Perhaps somewhat misnamed, really... This function will close all
+ // listen ports, fork a new copy to handle the last connections, and
+ // then quit the original process. The 'start' script should then
+ // start a new copy of roxen automatically.
+ mapping restart()
+ {
+ low_shutdown(-1);
+ return ([ "data": replace(Stdio.read_bytes("etc/restart.html"),
+ ({"$docurl", "$PWD"}), ({roxen->docurl, getcwd()})),
+ "type":"text/html" ]);
+ }
+
+ mapping shutdown()
+ {
+ low_shutdown(0);
+ return ([ "data":replace(Stdio.read_bytes("etc/shutdown.html"),
+ ({"$docurl", "$PWD"}), ({roxen->docurl, getcwd()})),
+ "type":"text/html" ]);
+ }
+
// This is called for each incoming connection.
private static void accept_callback( object port )
{
189:
case 24:
report_fatal("Out of sockets. Restarting server gracefully.\n");
- fork_or_quit();
+ low_shutdown(-1);
return;
}
}
999:
int config_ports_changed = 0;
- void stop_all_modules()
- {
- foreach(configurations, object conf)
- conf->stop();
- }
-
-
- // Perhaps somewhat misnamed, really... This function will close all
- // listen ports, fork a new copy to handle the last connections, and
- // then quit the original process. The 'start' script should then
- // start a new copy of roxen automatically.
-
- mapping restart()
- {
- stop_all_modules();
- call_out(fork_or_quit, 5, -1);
- return ([ "data": replace(Stdio.read_bytes("etc/restart.html"),
- ({"$docurl", "$PWD"}), ({roxen->docurl, getcwd()})),
- "type":"text/html" ]);
- }
-
+
static string MKPORTKEY(array(string) p)
{
if (sizeof(p[3])) {
1043:
return(values(configuration_ports));
}
- // This has to be refined in some way. It is not all that nice to do
- // it like this (write a file in /tmp, and then exit.) The major part
- // of code to support this is in the 'start' script.
- void kill_me()
- {
- // Change to root user if possible ( to kill the start script... )
- #if efun(seteuid)
- seteuid(getuid());
- setegid(getgid());
- #endif
- #if efun(setuid)
- setuid(0);
- #endif
- stop_all_modules();
-
- #ifdef THREADS
- stop_handler_threads();
- #endif /* THREADS */
-
- if(main_configuration_port && objectp(main_configuration_port))
- {
- // Only _really_ do something in the main process.
- int pid;
- perror("Shutting down Roxen.\n");
-
- #ifndef __NT__
- #ifdef USE_SHUTDOWN_FILE
-
- // Fallback for systems without geteuid, Roxen will (probably)
- // not be able to kill the start-script if this is the case.
- rm("/tmp/Roxen_Shutdown_"+startpid);
-
- object f;
- f=open("/tmp/Roxen_Shutdown_"+startpid, "wc");
-
- if(!f)
- perror("cannot open shutdown file.\n");
- else f->write(""+getpid());
-
- if(startpid != getpid())
- {
- kill(startpid, signum("SIGINTR"));
- kill(startpid, signum("SIGHUP"));
- kill(getppid(), signum("SIGINTR"));
- kill(getppid(), signum("SIGHUP"));
- }
-
- #endif /* USE_SHUTDOWN_FILE */
- #endif
- }
- // Die nicely (we're shutting down).
- call_out(exit, 2, 0);
- }
-
- mapping shutdown()
- {
- call_out(kill_me, 5, 0);
- return ([ "data":replace(Stdio.read_bytes("etc/shutdown.html"),
- ({"$docurl", "$PWD"}), ({roxen->docurl, getcwd()})),
- "type":"text/html" ]);
- }
-
+
string docurl;
// I will remove this in a future version of roxen.
2492:
static private int _recurse;
+ // FIXME: Ought to use the shutdown code.
void exit_when_done()
{
object o;
2537:
werror("Exiting roxen (timeout).\n");
stop_all_modules();
add_constant("roxen", 0); // Paranoia...
- exit(0); // Restart.
+ exit(-1); // Restart.
}, 600, 0); // Slow buggers..
}
2642:
}
catch { signal(signum("SIGHUP"), reload_all_configurations); };
// Signals which cause a shutdown (exitcode == 0)
- foreach( ({ "SIGQUIT" }), string sig) {
- catch { signal(signum(sig), kill_me); };
+ foreach( ({ "SIGTERM" }), string sig) {
+ catch { signal(signum(sig), shutdown); };
}
report_notice("Roxen started in "+(time()-start_time)+" seconds.\n");