mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Allow closing a monitor connection to force the server to quit
This commit is contained in:
parent
77dc7fc14c
commit
52da7778cd
@ -102,6 +102,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define MONITOR_PEERS (1<<2)
|
||||
#define MONITOR_DNAHELPER (1<<3)
|
||||
#define MONITOR_LINKS (1<<4)
|
||||
#define MONITOR_QUIT (1<<5)
|
||||
|
||||
#define MAX_SIGNATURES 16
|
||||
|
||||
|
17
monitor.c
17
monitor.c
@ -64,6 +64,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "monitor-client.h"
|
||||
#include "socket.h"
|
||||
#include "dataformats.h"
|
||||
#include "server.h"
|
||||
|
||||
#ifdef HAVE_UCRED_H
|
||||
#include <ucred.h>
|
||||
@ -166,6 +167,10 @@ void monitor_poll(struct sched_ent *alarm)
|
||||
static void monitor_close(struct monitor_context *c){
|
||||
INFOF("Tearing down monitor client fd=%d", c->alarm.poll.fd);
|
||||
|
||||
if (serverMode && c->flags & MONITOR_QUIT){
|
||||
INFOF("Quitting due to client disconnecting");
|
||||
serverMode=SERVER_CLOSING;
|
||||
}
|
||||
unwatch(&c->alarm);
|
||||
close(c->alarm.poll.fd);
|
||||
c->alarm.poll.fd=-1;
|
||||
@ -402,16 +407,18 @@ static int monitor_set(const struct cli_parsed *parsed, struct cli_context *cont
|
||||
if (codec>=0 && codec <=255)
|
||||
set_codec_flag(codec, c->supported_codecs);
|
||||
}
|
||||
}else if (strcase_startswith(parsed->args[1],"rhizome", NULL))
|
||||
}else if (strcase_startswith(parsed->args[1],"rhizome", NULL)){
|
||||
c->flags|=MONITOR_RHIZOME;
|
||||
else if (strcase_startswith(parsed->args[1],"peers", NULL)){
|
||||
}else if (strcase_startswith(parsed->args[1],"peers", NULL)){
|
||||
c->flags|=MONITOR_PEERS;
|
||||
enum_subscribers(NULL, monitor_announce_all_peers, NULL);
|
||||
}else if (strcase_startswith(parsed->args[1],"dnahelper", NULL))
|
||||
}else if (strcase_startswith(parsed->args[1],"dnahelper", NULL)){
|
||||
c->flags|=MONITOR_DNAHELPER;
|
||||
else if (strcase_startswith(parsed->args[1],"links", NULL)){
|
||||
}else if (strcase_startswith(parsed->args[1],"links", NULL)){
|
||||
c->flags|=MONITOR_LINKS;
|
||||
link_state_announce_links();
|
||||
}else if (strcase_startswith(parsed->args[1],"quit", NULL)){
|
||||
c->flags|=MONITOR_QUIT;
|
||||
}else
|
||||
return monitor_write_error(c,"Unknown monitor type");
|
||||
|
||||
@ -435,6 +442,8 @@ static int monitor_clear(const struct cli_parsed *parsed, struct cli_context *co
|
||||
c->flags&=~MONITOR_DNAHELPER;
|
||||
else if (strcase_startswith(parsed->args[1],"links", NULL))
|
||||
c->flags&=~MONITOR_LINKS;
|
||||
else if (strcase_startswith(parsed->args[1],"quit", NULL))
|
||||
c->flags&=~MONITOR_QUIT;
|
||||
else
|
||||
return monitor_write_error(c,"Unknown monitor type");
|
||||
|
||||
|
@ -485,6 +485,8 @@ static int monitor_announce(struct subscriber *subscriber, void *UNUSED(context)
|
||||
|
||||
int link_state_announce_links(){
|
||||
enum_subscribers(NULL, monitor_announce, NULL);
|
||||
// announce ourselves as unreachable, mainly so that monitor clients will always get one link back
|
||||
monitor_announce_link(0, NULL, my_subscriber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
14
server.c
14
server.c
@ -95,7 +95,7 @@ const char *_server_pidfile_path(struct __sourceloc __whence)
|
||||
int server()
|
||||
{
|
||||
IN();
|
||||
serverMode = 1;
|
||||
serverMode = SERVER_RUNNING;
|
||||
|
||||
// Warn, not merely Info, if there is no configured log file.
|
||||
logLevel_NoLogFileConfigured = LOG_LEVEL_WARN;
|
||||
@ -158,16 +158,18 @@ int server()
|
||||
|
||||
// log message used by tests to wait for the server to start
|
||||
INFO("Server initialised, entering main loop");
|
||||
while (serverMode == 1 && fd_poll())
|
||||
|
||||
/* Check for activitiy and respond to it */
|
||||
while((serverMode==SERVER_RUNNING) && fd_poll())
|
||||
;
|
||||
serverCleanUp();
|
||||
|
||||
|
||||
/* It is safe to unlink the pidfile here without checking whether it actually contains our own
|
||||
* PID, because server_shutdown_check() will have been executed very recently (in fd_poll()), so
|
||||
* if the code reaches here, the check has been done recently.
|
||||
*/
|
||||
server_unlink_pid();
|
||||
|
||||
serverMode = 0;
|
||||
RETURN(0);
|
||||
OUT();
|
||||
}
|
||||
@ -457,9 +459,9 @@ void signal_handler(int signal)
|
||||
/* Trigger the server to close gracefully after any current alarm has completed.
|
||||
If we get a second signal, exit now.
|
||||
*/
|
||||
if (serverMode==1){
|
||||
if (serverMode==SERVER_RUNNING){
|
||||
INFO("Attempting clean shutdown");
|
||||
serverMode=2;
|
||||
serverMode=SERVER_CLOSING;
|
||||
return;
|
||||
}
|
||||
default:
|
||||
|
3
server.h
3
server.h
@ -19,6 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#ifndef __SERVAL_DNA__SERVER_H
|
||||
#define __SERVAL_DNA__SERVER_H
|
||||
|
||||
#define SERVER_RUNNING 1
|
||||
#define SERVER_CLOSING 2
|
||||
|
||||
DECLARE_ALARM(server_shutdown_check);
|
||||
DECLARE_ALARM(server_watchdog);
|
||||
DECLARE_ALARM(server_config_reload);
|
||||
|
11
tests/server
11
tests/server
@ -150,6 +150,17 @@ test_RemovePid() {
|
||||
wait_until ! kill -0 $servald_pid 2>/dev/null
|
||||
}
|
||||
|
||||
doc_MonitorQuit="Server stops due to monitor client disconnection"
|
||||
setup_MonitorQuit() {
|
||||
setup
|
||||
start_servald_server
|
||||
}
|
||||
test_MonitorQuit() {
|
||||
executeOk_servald console < <(sleep 1 && echo "monitor quit" && sleep 1)
|
||||
tfw_cat --stdout --stderr
|
||||
wait_until ! kill -0 $servald_pid 2>/dev/null
|
||||
}
|
||||
|
||||
doc_NoZombie="Server process does not become a zombie"
|
||||
setup_NoZombie() {
|
||||
setup
|
||||
|
@ -71,6 +71,8 @@ static int console_hangup(const struct cli_parsed *parsed, struct cli_context *c
|
||||
static int console_audio(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_usage(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_quit(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_set(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static int console_clear(const struct cli_parsed *parsed, struct cli_context *context);
|
||||
static void monitor_read(struct sched_ent *alarm);
|
||||
|
||||
struct cli_schema console_commands[]={
|
||||
@ -80,6 +82,8 @@ struct cli_schema console_commands[]={
|
||||
{console_usage,{"help",NULL},0,"This usage message"},
|
||||
{console_audio,{"say","...",NULL},0,"Send a text string to the other party"},
|
||||
{console_quit,{"quit",NULL},0,"Exit process"},
|
||||
{console_set,{"monitor","<flag>",NULL},0,"Set an arbitrary monitor flag"},
|
||||
{console_clear,{"ignore","<flag>",NULL},0,"Clear an arbitrary monitor flag"},
|
||||
{NULL, {NULL, NULL, NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
@ -315,6 +319,26 @@ static int console_quit(const struct cli_parsed *UNUSED(parsed), struct cli_cont
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_set(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
|
||||
{
|
||||
const char *flag;
|
||||
if (cli_arg(parsed, "flag", &flag, NULL, NULL) != -1){
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "monitor %s\n",
|
||||
flag);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_clear(const struct cli_parsed *UNUSED(parsed), struct cli_context *UNUSED(context))
|
||||
{
|
||||
const char *flag;
|
||||
if (cli_arg(parsed, "flag", &flag, NULL, NULL) != -1){
|
||||
monitor_client_writeline(monitor_alarm.poll.fd, "ignore %s\n",
|
||||
flag);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_audio(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
|
||||
{
|
||||
if (!calls){
|
||||
|
Loading…
x
Reference in New Issue
Block a user