New server option -F to force start even when state looks bad

Risks crashes and further corruption, but gives deities a chance to
fix up a bad game state with edit commands and such.
This commit is contained in:
Markus Armbruster 2011-07-10 17:53:31 +02:00
parent c27564c0a9
commit c6d3f68bbb
4 changed files with 26 additions and 12 deletions

View file

@ -415,7 +415,7 @@ extern int disloan(int, struct lonstr *);
/* distrea.c */ /* distrea.c */
extern int distrea(int, struct trtstr *); extern int distrea(int, struct trtstr *);
/* fileinit.c */ /* fileinit.c */
extern void ef_init_srv(void); extern void ef_init_srv(int);
extern void ef_fin_srv(void); extern void ef_fin_srv(void);
/* fortdef.c */ /* fortdef.c */
extern int sd(natid, natid, coord, coord, int, int, int); extern int sd(natid, natid, coord, coord, int, int, int);

View file

@ -7,7 +7,7 @@ emp_server \- Empire server
.SH SYNOPSIS .SH SYNOPSIS
.B emp_server .B emp_server
[ [
.B \-dhpsv .B \-dFhpsv
] ]
[ [
.BI \-e " configfile" .BI \-e " configfile"
@ -59,6 +59,13 @@ What to do on recoverable internal error ("oops"): \fBabort\fP,
.ie \nw \fBcrash-dump\fP is not implemented for Windows. .ie \nw \fBcrash-dump\fP is not implemented for Windows.
.el \fBcrash-dump\fP works by aborting a fork of the server process. .el \fBcrash-dump\fP works by aborting a fork of the server process.
.TP .TP
.B \-F
Force
.B emp_server
to start even when game state looks bad. Risks crashes and further
corruption; use this only for attempting to fix up problems. Better
make a backup first, and lock out players.
.TP
.B \-h .B \-h
Help. Print brief usage information and exit. Help. Print brief usage information and exit.
.if \nw \{\ .if \nw \{\

View file

@ -28,7 +28,7 @@
* *
* Known contributors to this file: * Known contributors to this file:
* Ron Koenderink, 2005 * Ron Koenderink, 2005
* Markus Armbruster, 2005-2008 * Markus Armbruster, 2005-2011
*/ */
#include <config.h> #include <config.h>
@ -60,7 +60,7 @@ static void ef_close_srv(void);
* Initialize empfile for full server operations. * Initialize empfile for full server operations.
*/ */
void void
ef_init_srv(void) ef_init_srv(int force_bad_state)
{ {
unsigned i; unsigned i;
@ -71,11 +71,14 @@ ef_init_srv(void)
} }
nsc_init(); nsc_init();
ef_open_srv();
if (ef_verify_config() < 0) if (ef_verify_config() < 0)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
if (ef_verify_state(1) < 0) ef_open_srv();
if (ef_verify_state(1) < 0 && !force_bad_state) {
fprintf(stderr, "You can try -F to force running anyway,"
" but that's risky; see the manual page\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
global_init(); global_init();
unit_cargo_init(); unit_cargo_init();
} }

View file

@ -31,7 +31,7 @@
* Steve McClure, 1996, 1998 * Steve McClure, 1996, 1998
* Doug Hay, 1998 * Doug Hay, 1998
* Ron Koenderink, 2004-2009 * Ron Koenderink, 2004-2009
* Markus Armbruster, 2005-2010 * Markus Armbruster, 2005-2011
*/ */
#include <config.h> #include <config.h>
@ -71,7 +71,7 @@
static void ignore(void); static void ignore(void);
static void crash_dump(void); static void crash_dump(void);
static void init_server(unsigned); static void init_server(unsigned, int);
static void create_pidfile(char *, pid_t); static void create_pidfile(char *, pid_t);
#if defined(_WIN32) #if defined(_WIN32)
@ -138,6 +138,7 @@ main(int argc, char **argv)
int remove_service_set = 0; int remove_service_set = 0;
#endif #endif
char *config_file = NULL; char *config_file = NULL;
int force_bad_state = 0;
int op, idx, sig; int op, idx, sig;
unsigned seed = time(NULL); unsigned seed = time(NULL);
@ -148,7 +149,7 @@ main(int argc, char **argv)
#else #else
# define XOPTS # define XOPTS
#endif #endif
while ((op = getopt(argc, argv, "de:E:hpsR:v" XOPTS)) != EOF) { while ((op = getopt(argc, argv, "de:E:FhpsR:v" XOPTS)) != EOF) {
switch (op) { switch (op) {
case 'p': case 'p':
flags |= EMPTH_PRINT; flags |= EMPTH_PRINT;
@ -168,6 +169,9 @@ main(int argc, char **argv)
} }
oops_handler = oops_hndlr[idx]; oops_handler = oops_hndlr[idx];
break; break;
case 'F':
force_bad_state = 1;
break;
#if defined(_WIN32) #if defined(_WIN32)
case 'I': case 'I':
service_name = optarg; service_name = optarg;
@ -247,7 +251,7 @@ main(int argc, char **argv)
return install_service(program_name, service_name, config_file); return install_service(program_name, service_name, config_file);
#endif /* _WIN32 */ #endif /* _WIN32 */
init_server(seed); init_server(seed, force_bad_state);
#if defined(_WIN32) #if defined(_WIN32)
if (daemonize != 0) { if (daemonize != 0) {
@ -342,14 +346,14 @@ crash_dump(void)
* Initialize for serving, acquire resources. * Initialize for serving, acquire resources.
*/ */
static void static void
init_server(unsigned seed) init_server(unsigned seed, int force_bad_state)
{ {
srandom(seed); srandom(seed);
#if defined(_WIN32) #if defined(_WIN32)
loc_NTInit(); loc_NTInit();
#endif #endif
player_init(); player_init();
ef_init_srv(); ef_init_srv(force_bad_state);
io_init(); io_init();
init_nreport(); init_nreport();