mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-06 19:19:16 +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_PEERS (1<<2)
|
||||||
#define MONITOR_DNAHELPER (1<<3)
|
#define MONITOR_DNAHELPER (1<<3)
|
||||||
#define MONITOR_LINKS (1<<4)
|
#define MONITOR_LINKS (1<<4)
|
||||||
|
#define MONITOR_QUIT (1<<5)
|
||||||
|
|
||||||
#define MAX_SIGNATURES 16
|
#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 "monitor-client.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "dataformats.h"
|
#include "dataformats.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
#ifdef HAVE_UCRED_H
|
#ifdef HAVE_UCRED_H
|
||||||
#include <ucred.h>
|
#include <ucred.h>
|
||||||
@ -166,6 +167,10 @@ void monitor_poll(struct sched_ent *alarm)
|
|||||||
static void monitor_close(struct monitor_context *c){
|
static void monitor_close(struct monitor_context *c){
|
||||||
INFOF("Tearing down monitor client fd=%d", c->alarm.poll.fd);
|
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);
|
unwatch(&c->alarm);
|
||||||
close(c->alarm.poll.fd);
|
close(c->alarm.poll.fd);
|
||||||
c->alarm.poll.fd=-1;
|
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)
|
if (codec>=0 && codec <=255)
|
||||||
set_codec_flag(codec, c->supported_codecs);
|
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;
|
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;
|
c->flags|=MONITOR_PEERS;
|
||||||
enum_subscribers(NULL, monitor_announce_all_peers, NULL);
|
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;
|
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;
|
c->flags|=MONITOR_LINKS;
|
||||||
link_state_announce_links();
|
link_state_announce_links();
|
||||||
|
}else if (strcase_startswith(parsed->args[1],"quit", NULL)){
|
||||||
|
c->flags|=MONITOR_QUIT;
|
||||||
}else
|
}else
|
||||||
return monitor_write_error(c,"Unknown monitor type");
|
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;
|
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;
|
c->flags&=~MONITOR_LINKS;
|
||||||
|
else if (strcase_startswith(parsed->args[1],"quit", NULL))
|
||||||
|
c->flags&=~MONITOR_QUIT;
|
||||||
else
|
else
|
||||||
return monitor_write_error(c,"Unknown monitor type");
|
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(){
|
int link_state_announce_links(){
|
||||||
enum_subscribers(NULL, monitor_announce, NULL);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
server.c
12
server.c
@ -95,7 +95,7 @@ const char *_server_pidfile_path(struct __sourceloc __whence)
|
|||||||
int server()
|
int server()
|
||||||
{
|
{
|
||||||
IN();
|
IN();
|
||||||
serverMode = 1;
|
serverMode = SERVER_RUNNING;
|
||||||
|
|
||||||
// Warn, not merely Info, if there is no configured log file.
|
// Warn, not merely Info, if there is no configured log file.
|
||||||
logLevel_NoLogFileConfigured = LOG_LEVEL_WARN;
|
logLevel_NoLogFileConfigured = LOG_LEVEL_WARN;
|
||||||
@ -158,7 +158,9 @@ int server()
|
|||||||
|
|
||||||
// log message used by tests to wait for the server to start
|
// log message used by tests to wait for the server to start
|
||||||
INFO("Server initialised, entering main loop");
|
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();
|
serverCleanUp();
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ int server()
|
|||||||
* if the code reaches here, the check has been done recently.
|
* if the code reaches here, the check has been done recently.
|
||||||
*/
|
*/
|
||||||
server_unlink_pid();
|
server_unlink_pid();
|
||||||
|
serverMode = 0;
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
OUT();
|
OUT();
|
||||||
}
|
}
|
||||||
@ -457,9 +459,9 @@ void signal_handler(int signal)
|
|||||||
/* Trigger the server to close gracefully after any current alarm has completed.
|
/* Trigger the server to close gracefully after any current alarm has completed.
|
||||||
If we get a second signal, exit now.
|
If we get a second signal, exit now.
|
||||||
*/
|
*/
|
||||||
if (serverMode==1){
|
if (serverMode==SERVER_RUNNING){
|
||||||
INFO("Attempting clean shutdown");
|
INFO("Attempting clean shutdown");
|
||||||
serverMode=2;
|
serverMode=SERVER_CLOSING;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
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
|
#ifndef __SERVAL_DNA__SERVER_H
|
||||||
#define __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_shutdown_check);
|
||||||
DECLARE_ALARM(server_watchdog);
|
DECLARE_ALARM(server_watchdog);
|
||||||
DECLARE_ALARM(server_config_reload);
|
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
|
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"
|
doc_NoZombie="Server process does not become a zombie"
|
||||||
setup_NoZombie() {
|
setup_NoZombie() {
|
||||||
setup
|
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_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_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_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);
|
static void monitor_read(struct sched_ent *alarm);
|
||||||
|
|
||||||
struct cli_schema console_commands[]={
|
struct cli_schema console_commands[]={
|
||||||
@ -80,6 +82,8 @@ struct cli_schema console_commands[]={
|
|||||||
{console_usage,{"help",NULL},0,"This usage message"},
|
{console_usage,{"help",NULL},0,"This usage message"},
|
||||||
{console_audio,{"say","...",NULL},0,"Send a text string to the other party"},
|
{console_audio,{"say","...",NULL},0,"Send a text string to the other party"},
|
||||||
{console_quit,{"quit",NULL},0,"Exit process"},
|
{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},
|
{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;
|
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))
|
static int console_audio(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
|
||||||
{
|
{
|
||||||
if (!calls){
|
if (!calls){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user