Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Donald Haase
Cockatrice
Commits
a14a642b
Commit
a14a642b
authored
Jul 03, 2015
by
woogerboy21
Browse files
Merge pull request #1181 from ctrlaltca/servatrice_reload_config
Servatrice: refactor signal handling and permit config reloading
parents
9159958c
f5be6f83
Changes
12
Hide whitespace changes
Inline
Side-by-side
cockatrice/src/tab_admin.cpp
View file @
a14a642b
...
...
@@ -58,10 +58,13 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
connect
(
updateServerMessageButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
actUpdateServerMessage
()));
shutdownServerButton
=
new
QPushButton
;
connect
(
shutdownServerButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
actShutdownServer
()));
reloadConfigButton
=
new
QPushButton
;
connect
(
reloadConfigButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
actReloadConfig
()));
QVBoxLayout
*
vbox
=
new
QVBoxLayout
;
vbox
->
addWidget
(
updateServerMessageButton
);
vbox
->
addWidget
(
shutdownServerButton
);
vbox
->
addWidget
(
reloadConfigButton
);
vbox
->
addStretch
();
adminGroupBox
=
new
QGroupBox
;
...
...
@@ -87,6 +90,7 @@ void TabAdmin::retranslateUi()
{
updateServerMessageButton
->
setText
(
tr
(
"Update server &message"
));
shutdownServerButton
->
setText
(
tr
(
"&Shut down server"
));
reloadConfigButton
->
setText
(
tr
(
"&Reload configuration"
));
adminGroupBox
->
setTitle
(
tr
(
"Server administration functions"
));
unlockButton
->
setText
(
tr
(
"&Unlock functions"
));
...
...
@@ -110,6 +114,12 @@ void TabAdmin::actShutdownServer()
}
}
void
TabAdmin
::
actReloadConfig
()
{
Command_ReloadConfig
cmd
;
client
->
sendCommand
(
client
->
prepareAdminCommand
(
cmd
));
}
void
TabAdmin
::
actUnlock
()
{
if
(
QMessageBox
::
question
(
this
,
tr
(
"Unlock administration functions"
),
tr
(
"Do you really want to unlock the administration functions?"
),
QMessageBox
::
Yes
|
QMessageBox
::
No
)
==
QMessageBox
::
Yes
)
{
...
...
cockatrice/src/tab_admin.h
View file @
a14a642b
...
...
@@ -28,7 +28,7 @@ private:
bool
locked
;
AbstractClient
*
client
;
bool
fullAdmin
;
QPushButton
*
updateServerMessageButton
,
*
shutdownServerButton
;
QPushButton
*
updateServerMessageButton
,
*
shutdownServerButton
,
*
reloadConfigButton
;
QGroupBox
*
adminGroupBox
;
QPushButton
*
unlockButton
,
*
lockButton
;
signals:
...
...
@@ -36,6 +36,7 @@ signals:
private
slots
:
void
actUpdateServerMessage
();
void
actShutdownServer
();
void
actReloadConfig
();
void
actUnlock
();
void
actLock
();
...
...
common/pb/admin_commands.proto
View file @
a14a642b
...
...
@@ -2,6 +2,7 @@ message AdminCommand {
enum
AdminCommandType
{
UPDATE_SERVER_MESSAGE
=
1000
;
SHUTDOWN_SERVER
=
1001
;
RELOAD_CONFIG
=
1002
;
}
extensions
100
to
max
;
}
...
...
@@ -19,3 +20,9 @@ message Command_ShutdownServer {
optional
string
reason
=
1
;
optional
uint32
minutes
=
2
;
}
message
Command_ReloadConfig
{
extend
AdminCommand
{
optional
Command_ReloadConfig
ext
=
1002
;
}
}
servatrice/CMakeLists.txt
View file @
a14a642b
...
...
@@ -14,6 +14,7 @@ SET(servatrice_SOURCES
src/serversocketinterface.cpp
src/settingscache.cpp
src/isl_interface.cpp
src/signalhandler.cpp
${
VERSION_STRING_CPP
}
src/smtp/emailaddress.cpp
src/smtp/mimeattachment.cpp
...
...
servatrice/src/main.cpp
View file @
a14a642b
...
...
@@ -28,21 +28,16 @@
#include
"servatrice.h"
#include
"server_logger.h"
#include
"settingscache.h"
#include
"signalhandler.h"
#include
"rng_sfmt.h"
#include
"version_string.h"
#include
<google/protobuf/stubs/common.h>
#ifdef Q_OS_UNIX
#include
<signal.h>
#include
<execinfo.h>
#include
<unistd.h>
#endif
#define SIGSEGV_TRACE_LINES 40
RNG_Abstract
*
rng
;
ServerLogger
*
logger
;
QThread
*
loggerThread
;
SettingsCache
*
settingsCache
;
SignalHandler
*
signalhandler
;
/* Prototypes */
...
...
@@ -55,9 +50,6 @@ void myMessageOutput2(QtMsgType type, const char *msg);
void
myMessageOutput
(
QtMsgType
type
,
const
QMessageLogContext
&
,
const
QString
&
msg
);
void
myMessageOutput2
(
QtMsgType
type
,
const
QMessageLogContext
&
,
const
QString
&
msg
);
#endif
#ifdef Q_OS_UNIX
void
sigSegvHandler
(
int
sig
);
#endif
/* Implementations */
...
...
@@ -130,32 +122,6 @@ void myMessageOutput2(QtMsgType /*type*/, const QMessageLogContext &, const QStr
}
#endif
#ifdef Q_OS_UNIX
void
sigSegvHandler
(
int
sig
)
{
void
*
array
[
SIGSEGV_TRACE_LINES
];
size_t
size
;
// get void*'s for all entries on the stack
size
=
backtrace
(
array
,
SIGSEGV_TRACE_LINES
);
// print out all the frames to stderr
fprintf
(
stderr
,
"Error: signal %d:
\n
"
,
sig
);
backtrace_symbols_fd
(
array
,
size
,
STDERR_FILENO
);
if
(
sig
==
SIGSEGV
)
logger
->
logMessage
(
"CRASH: SIGSEGV"
);
else
if
(
sig
==
SIGABRT
)
logger
->
logMessage
(
"CRASH: SIGABRT"
);
logger
->
deleteLater
();
loggerThread
->
wait
();
delete
loggerThread
;
raise
(
sig
);
}
#endif
int
main
(
int
argc
,
char
*
argv
[])
{
QCoreApplication
app
(
argc
,
argv
);
...
...
@@ -202,23 +168,8 @@ int main(int argc, char *argv[])
qInstallMessageHandler
(
myMessageOutput2
);
#endif
#ifdef Q_OS_UNIX
struct
sigaction
hup
;
hup
.
sa_handler
=
ServerLogger
::
hupSignalHandler
;
sigemptyset
(
&
hup
.
sa_mask
);
hup
.
sa_flags
=
0
;
hup
.
sa_flags
|=
SA_RESTART
;
sigaction
(
SIGHUP
,
&
hup
,
0
);
struct
sigaction
segv
;
segv
.
sa_handler
=
sigSegvHandler
;
segv
.
sa_flags
=
SA_RESETHAND
;
sigemptyset
(
&
segv
.
sa_mask
);
sigaction
(
SIGSEGV
,
&
segv
,
0
);
sigaction
(
SIGABRT
,
&
segv
,
0
);
signal
(
SIGPIPE
,
SIG_IGN
);
#endif
signalhandler
=
new
SignalHandler
();
rng
=
new
RNG_SFMT
;
std
::
cerr
<<
"Servatrice "
<<
VERSION_STRING
<<
" starting."
<<
std
::
endl
;
...
...
@@ -250,6 +201,7 @@ int main(int argc, char *argv[])
}
delete
rng
;
delete
signalhandler
;
delete
settingsCache
;
logger
->
deleteLater
();
...
...
servatrice/src/main.h
View file @
a14a642b
...
...
@@ -2,6 +2,11 @@
#define MAIN_H
class
ServerLogger
;
class
QThread
;
class
SettingsCache
;
extern
ServerLogger
*
logger
;
extern
QThread
*
loggerThread
;
extern
SettingsCache
*
settingsCache
;
#endif
servatrice/src/server_logger.cpp
View file @
a14a642b
#include
"server_logger.h"
#include
"settingscache.h"
#include
<QSocketNotifier>
#include
<QFile>
#include
<QFileInfo>
#include
<QDir>
#include
<QTextStream>
#include
<QDateTime>
#include
<iostream>
#ifdef Q_OS_UNIX
# include <sys/types.h>
# include <sys/socket.h>
# include <unistd.h>
#endif
ServerLogger
::
ServerLogger
(
bool
_logToConsole
,
QObject
*
parent
)
:
QObject
(
parent
),
logToConsole
(
_logToConsole
),
flushRunning
(
false
)
...
...
@@ -44,13 +38,6 @@ void ServerLogger::startLog(const QString &logFileName)
logFile
=
0
;
return
;
}
#ifdef Q_OS_UNIX
::
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sigHupFD
);
snHup
=
new
QSocketNotifier
(
sigHupFD
[
1
],
QSocketNotifier
::
Read
,
this
);
connect
(
snHup
,
SIGNAL
(
activated
(
int
)),
this
,
SLOT
(
handleSigHup
()));
#endif
}
else
logFile
=
0
;
...
...
@@ -119,35 +106,15 @@ void ServerLogger::flushBuffer()
}
}
void
ServerLogger
::
hupSignalHandler
(
int
/*unused*/
)
void
ServerLogger
::
rotateLogs
(
)
{
#ifdef Q_OS_UNIX
if
(
!
logFile
)
return
;
char
a
=
1
;
ssize_t
writeValue
=
::
write
(
sigHupFD
[
0
],
&
a
,
sizeof
(
a
));
Q_UNUSED
(
writeValue
);
#endif
}
void
ServerLogger
::
handleSigHup
()
{
#ifdef Q_OS_UNIX
if
(
!
logFile
)
return
;
snHup
->
setEnabled
(
false
);
char
tmp
;
ssize_t
readValue
=
::
read
(
sigHupFD
[
1
],
&
tmp
,
sizeof
(
tmp
));
Q_UNUSED
(
readValue
);
flushBuffer
();
logFile
->
close
();
logFile
->
open
(
QIODevice
::
Append
);
snHup
->
setEnabled
(
true
);
#endif
}
QFile
*
ServerLogger
::
logFile
;
int
ServerLogger
::
sigHupFD
[
2
];
servatrice/src/server_logger.h
View file @
a14a642b
...
...
@@ -7,7 +7,6 @@
#include
<QWaitCondition>
#include
<QStringList>
class
QSocketNotifier
;
class
QFile
;
class
Server_ProtocolHandler
;
...
...
@@ -16,19 +15,16 @@ class ServerLogger : public QObject {
public:
ServerLogger
(
bool
_logToConsole
,
QObject
*
parent
=
0
);
~
ServerLogger
();
static
void
hupSignalHandler
(
int
unused
);
public
slots
:
void
startLog
(
const
QString
&
logFileName
);
void
logMessage
(
QString
message
,
void
*
caller
=
0
);
void
rotateLogs
();
private
slots
:
void
handleSigHup
();
void
flushBuffer
();
signals:
void
sigFlushBuffer
();
private:
bool
logToConsole
;
static
int
sigHupFD
[
2
];
QSocketNotifier
*
snHup
;
static
QFile
*
logFile
;
bool
flushRunning
;
QStringList
buffer
;
...
...
servatrice/src/serversocketinterface.cpp
View file @
a14a642b
...
...
@@ -289,6 +289,7 @@ Response::ResponseCode ServerSocketInterface::processExtendedAdminCommand(int cm
switch
((
AdminCommand
::
AdminCommandType
)
cmdType
)
{
case
AdminCommand
::
SHUTDOWN_SERVER
:
return
cmdShutdownServer
(
cmd
.
GetExtension
(
Command_ShutdownServer
::
ext
),
rc
);
case
AdminCommand
::
UPDATE_SERVER_MESSAGE
:
return
cmdUpdateServerMessage
(
cmd
.
GetExtension
(
Command_UpdateServerMessage
::
ext
),
rc
);
case
AdminCommand
::
RELOAD_CONFIG
:
return
cmdReloadConfig
(
cmd
.
GetExtension
(
Command_ReloadConfig
::
ext
),
rc
);
default:
return
Response
::
RespFunctionNotAllowed
;
}
}
...
...
@@ -956,3 +957,10 @@ Response::ResponseCode ServerSocketInterface::cmdShutdownServer(const Command_Sh
QMetaObject
::
invokeMethod
(
server
,
"scheduleShutdown"
,
Q_ARG
(
QString
,
QString
::
fromStdString
(
cmd
.
reason
())),
Q_ARG
(
int
,
cmd
.
minutes
()));
return
Response
::
RespOk
;
}
Response
::
ResponseCode
ServerSocketInterface
::
cmdReloadConfig
(
const
Command_ReloadConfig
&
/* cmd */
,
ResponseContainer
&
/*rc*/
)
{
logDebugMessage
(
"Received admin command: reloading configuration"
);
settingsCache
->
sync
();
return
Response
::
RespOk
;
}
servatrice/src/serversocketinterface.h
View file @
a14a642b
...
...
@@ -47,6 +47,7 @@ class Command_ReplayDeleteMatch;
class
Command_BanFromServer
;
class
Command_UpdateServerMessage
;
class
Command_ShutdownServer
;
class
Command_ReloadConfig
;
class
ServerSocketInterface
:
public
Server_ProtocolHandler
{
...
...
@@ -94,6 +95,7 @@ private:
Response
::
ResponseCode
cmdUpdateServerMessage
(
const
Command_UpdateServerMessage
&
cmd
,
ResponseContainer
&
rc
);
Response
::
ResponseCode
cmdRegisterAccount
(
const
Command_Register
&
cmd
,
ResponseContainer
&
rc
);
Response
::
ResponseCode
cmdActivateAccount
(
const
Command_Activate
&
cmd
,
ResponseContainer
&
/* rc */
);
Response
::
ResponseCode
cmdReloadConfig
(
const
Command_ReloadConfig
&
/* cmd */
,
ResponseContainer
&
/*rc*/
);
Response
::
ResponseCode
processExtendedSessionCommand
(
int
cmdType
,
const
SessionCommand
&
cmd
,
ResponseContainer
&
rc
);
Response
::
ResponseCode
processExtendedModeratorCommand
(
int
cmdType
,
const
ModeratorCommand
&
cmd
,
ResponseContainer
&
rc
);
...
...
servatrice/src/signalhandler.cpp
0 → 100644
View file @
a14a642b
#include
<QSocketNotifier>
#include
"signalhandler.h"
#include
"server_logger.h"
#include
"settingscache.h"
#include
"main.h"
#ifdef Q_OS_UNIX
#include
<sys/types.h>
#include
<sys/socket.h>
#include
<unistd.h>
#include
<signal.h>
#include
<execinfo.h>
#include
<iostream>
#include
<cstdio>
#endif
#define SIGSEGV_TRACE_LINES 40
int
SignalHandler
::
sigHupFD
[
2
];
SignalHandler
::
SignalHandler
(
QObject
*
parent
)
:
QObject
(
parent
)
{
#ifdef Q_OS_UNIX
::
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sigHupFD
);
snHup
=
new
QSocketNotifier
(
sigHupFD
[
1
],
QSocketNotifier
::
Read
,
this
);
connect
(
snHup
,
SIGNAL
(
activated
(
int
)),
this
,
SLOT
(
internalSigHupHandler
()));
struct
sigaction
hup
;
hup
.
sa_handler
=
SignalHandler
::
sigHupHandler
;
sigemptyset
(
&
hup
.
sa_mask
);
hup
.
sa_flags
=
0
;
hup
.
sa_flags
|=
SA_RESTART
;
sigaction
(
SIGHUP
,
&
hup
,
0
);
struct
sigaction
segv
;
segv
.
sa_handler
=
SignalHandler
::
sigSegvHandler
;
segv
.
sa_flags
=
SA_RESETHAND
;
sigemptyset
(
&
segv
.
sa_mask
);
sigaction
(
SIGSEGV
,
&
segv
,
0
);
sigaction
(
SIGABRT
,
&
segv
,
0
);
signal
(
SIGPIPE
,
SIG_IGN
);
#endif
}
void
SignalHandler
::
sigHupHandler
(
int
/* sig */
)
{
#ifdef Q_OS_UNIX
char
a
=
1
;
ssize_t
writeValue
=
::
write
(
sigHupFD
[
0
],
&
a
,
sizeof
(
a
));
Q_UNUSED
(
writeValue
);
#endif
}
void
SignalHandler
::
internalSigHupHandler
()
{
snHup
->
setEnabled
(
false
);
#ifdef Q_OS_UNIX
char
tmp
;
ssize_t
readValue
=
::
read
(
sigHupFD
[
1
],
&
tmp
,
sizeof
(
tmp
));
Q_UNUSED
(
readValue
);
std
::
cerr
<<
"Received SIGHUP"
<<
std
::
endl
;
#endif
logger
->
logMessage
(
"Received SIGHUP, rotating logs and reloading configuration"
,
this
);
logger
->
rotateLogs
();
settingsCache
->
sync
();
snHup
->
setEnabled
(
true
);
}
void
SignalHandler
::
sigSegvHandler
(
int
sig
)
{
#ifdef Q_OS_UNIX
void
*
array
[
SIGSEGV_TRACE_LINES
];
size_t
size
;
// get void*'s for all entries on the stack
size
=
backtrace
(
array
,
SIGSEGV_TRACE_LINES
);
// print out all the frames to stderr
fprintf
(
stderr
,
"Error: signal %d:
\n
"
,
sig
);
backtrace_symbols_fd
(
array
,
size
,
STDERR_FILENO
);
if
(
sig
==
SIGSEGV
)
logger
->
logMessage
(
"CRASH: SIGSEGV"
);
else
if
(
sig
==
SIGABRT
)
logger
->
logMessage
(
"CRASH: SIGABRT"
);
logger
->
deleteLater
();
loggerThread
->
wait
();
delete
loggerThread
;
raise
(
sig
);
#endif
}
servatrice/src/signalhandler.h
0 → 100644
View file @
a14a642b
#ifndef SIGNALHANDLER_H
#define SIGNALHANDLER_H
#include
<QObject>
class
QSocketNotifier
;
class
SignalHandler
:
public
QObject
{
Q_OBJECT
public:
SignalHandler
(
QObject
*
parent
=
0
);
~
SignalHandler
()
{
};
static
void
sigHupHandler
(
int
/* sig */
);
static
void
sigSegvHandler
(
int
sig
);
private:
static
int
sigHupFD
[
2
];
QSocketNotifier
*
snHup
;
private
slots
:
void
internalSigHupHandler
();
};
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment