From f73cb9f4457c40edf787efcf30ea80822381a732 Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Mon, 6 Dec 2010 18:59:54 +0300 Subject: cli: implemented shutdown command to shutdown daemon --- .gitignore | 1 + accel-pptpd/cli/std_cmd.c | 43 ++++++++++++++++++++++++++++++++++++++++++ accel-pptpd/ctrl/l2tp/l2tp.c | 12 ++++++++++++ accel-pptpd/ctrl/pppoe/pppoe.c | 18 +++++++++++++++++- accel-pptpd/ctrl/pptp/pptp.c | 13 +++++++++++++ accel-pptpd/include/events.h | 1 + accel-pptpd/ppp/ppp.c | 16 ++++++++++++++++ accel-pptpd/ppp/ppp.h | 2 ++ 8 files changed, 105 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 89efb0f..bb95b2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build *.swp +scripts diff --git a/accel-pptpd/cli/std_cmd.c b/accel-pptpd/cli/std_cmd.c index 0d23493..673d277 100644 --- a/accel-pptpd/cli/std_cmd.c +++ b/accel-pptpd/cli/std_cmd.c @@ -1,8 +1,11 @@ #include #include #include +#include +#include #include "triton.h" +#include "events.h" #include "ppp.h" #include "cli.h" #include "utils.h" @@ -281,11 +284,51 @@ static void terminate_help(char * const *fields, int fields_cnt, void *client) cli_send(client, "terminate all [soft|hard]- terminate all session\r\n"); } +//============================= + +static void shutdown_help(char * const *fields, int fields_cnt, void *client) +{ + cli_send(client, "shutdown [soft|hard]- shutdown daemon\r\n"); + cli_send(client, "\t\tdefault action - send termination signals to all clients and wait everybody disconnects\r\n"); + cli_send(client, "\t\tsoft - wait until all clients disconnects, don't accept new connections\r\n"); + cli_send(client, "\t\thard - shutdown now, don't wait anything\r\n"); +} + +static int shutdown_exec(const char *cmd, char * const *f, int f_cnt, void *cli) +{ + int hard = 0; + struct ppp_t *ppp; + + if (f_cnt == 2) { + if (!strcmp(f[1], "soft")) { + triton_event_fire(EV_SHUTDOWN_SOFT, NULL); + return CLI_CMD_OK; + } else if (!strcmp(f[1], "hard")) + hard = 1; + else + return CLI_CMD_SYNTAX; + } + + triton_event_fire(EV_SHUTDOWN_SOFT, NULL); + + pthread_rwlock_rdlock(&ppp_lock); + list_for_each_entry(ppp, &ppp_list, entry) { + if (hard) + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_hard, ppp); + else + triton_context_call(ppp->ctrl->ctx, (triton_event_func)ppp_terminate_soft, ppp); + } + pthread_rwlock_unlock(&ppp_lock); + + return CLI_CMD_OK; +} + static void __init init(void) { cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat"); cli_register_simple_cmd2(show_ses_exec, show_ses_help, 2, "show", "sessions"); cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate"); + cli_register_simple_cmd2(shutdown_exec, shutdown_help, 1, "shutdown"); cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit"); } diff --git a/accel-pptpd/ctrl/l2tp/l2tp.c b/accel-pptpd/ctrl/l2tp/l2tp.c index cb891b6..2a48aa1 100644 --- a/accel-pptpd/ctrl/l2tp/l2tp.c +++ b/accel-pptpd/ctrl/l2tp/l2tp.c @@ -50,6 +50,8 @@ int conf_retransmit = 5; int conf_hello_interval = 60; const char *conf_host_name = "accel-pptp"; +static int shutdown_soft; + static uint32_t stat_active; static uint32_t stat_starting; @@ -638,6 +640,9 @@ static int l2tp_recv_SCCRQ(struct l2tp_serv_t *serv, struct l2tp_packet_t *pack) struct l2tp_attr_t *framing_cap = NULL; struct l2tp_attr_t *router_id = NULL; + if (shutdown_soft) + return 0; + list_for_each_entry(attr, &pack->attrs, entry) { switch (attr->attr->id) { case Protocol_Version: @@ -1107,6 +1112,11 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, return CLI_CMD_OK; } +static void ev_shutdown_soft(void) +{ + shutdown_soft = 1; +} + static void __init l2tp_init(void) { char *opt; @@ -1143,5 +1153,7 @@ static void __init l2tp_init(void) start_udp_server(); cli_register_simple_cmd2(&show_stat_exec, NULL, 2, "show", "stat"); + + triton_event_register_handler(EV_SHUTDOWN_SOFT, (triton_event_func)ev_shutdown_soft); } diff --git a/accel-pptpd/ctrl/pppoe/pppoe.c b/accel-pptpd/ctrl/pppoe/pppoe.c index b5a9189..57342ba 100644 --- a/accel-pptpd/ctrl/pppoe/pppoe.c +++ b/accel-pptpd/ctrl/pppoe/pppoe.c @@ -62,6 +62,8 @@ char *conf_ac_name; int conf_pado_delay; int conf_ifname_in_sid; +static int shutdown_soft; + static mempool_t conn_pool; static mempool_t pado_pool; @@ -628,7 +630,8 @@ static void pado_timer(struct triton_timer_t *t) { struct delayed_pado_t *pado = container_of(t, typeof(*pado), timer); - pppoe_send_PADO(pado->serv, pado->addr, pado->host_uniq, pado->relay_sid, pado->service_name); + if (!shutdown_soft) + pppoe_send_PADO(pado->serv, pado->addr, pado->host_uniq, pado->relay_sid, pado->service_name); free_delayed_pado(pado); } @@ -644,6 +647,9 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size) int n, service_match = 0; struct delayed_pado_t *pado; + if (shutdown_soft) + return; + if (hdr->sid) { log_warn("pppoe: discarding PADI packet (sid is not zero)\n"); return; @@ -737,6 +743,9 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size) int n, service_match = 0; struct pppoe_conn_t *conn; + if (shutdown_soft) + return; + if (!memcmp(ethhdr->h_dest, bc_addr, ETH_ALEN)) { if (conf_verbose) log_warn("pppoe: discard PADR (destination address is broadcast)\n"); @@ -1102,6 +1111,11 @@ static void _server_stop(struct pppoe_serv_t *serv) pthread_mutex_unlock(&serv->lock); } +static void ev_shutdown_soft(void) +{ + shutdown_soft = 1; +} + void pppoe_server_free(struct pppoe_serv_t *serv) { struct delayed_pado_t *pado; @@ -1206,5 +1220,7 @@ static void __init pppoe_init(void) if (!conf_ac_name) conf_ac_name = _strdup("accel-pptp"); + + triton_event_register_handler(EV_SHUTDOWN_SOFT, (triton_event_func)ev_shutdown_soft); } diff --git a/accel-pptpd/ctrl/pptp/pptp.c b/accel-pptpd/ctrl/pptp/pptp.c index f7ffee0..887db37 100644 --- a/accel-pptpd/ctrl/pptp/pptp.c +++ b/accel-pptpd/ctrl/pptp/pptp.c @@ -56,6 +56,7 @@ static int conf_timeout = 5; static int conf_echo_interval = 0; static int conf_echo_failure = 3; static int conf_verbose = 0; +static int shutdown_soft; static mempool_t conn_pool; @@ -617,6 +618,11 @@ static int pptp_connect(struct triton_md_handler_t *h) continue; } + if (shutdown_soft) { + close(sock); + continue; + } + log_info2("pptp: new connection from %s\n", inet_ntoa(addr.sin_addr)); if (iprange_client_check(addr.sin_addr.s_addr)) { @@ -694,6 +700,11 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, return CLI_CMD_OK; } +static void ev_shutdown_soft(void) +{ + shutdown_soft = 1; +} + static void __init pptp_init(void) { struct sockaddr_in addr; @@ -756,5 +767,7 @@ static void __init pptp_init(void) triton_context_wakeup(&serv.ctx); cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat"); + + triton_event_register_handler(EV_SHUTDOWN_SOFT, (triton_event_func)ev_shutdown_soft); } diff --git a/accel-pptpd/include/events.h b/accel-pptpd/include/events.h index 5958f27..3e4a23b 100644 --- a/accel-pptpd/include/events.h +++ b/accel-pptpd/include/events.h @@ -13,6 +13,7 @@ #define EV_CTRL_FINISHED 8 #define EV_PPP_PRE_UP 9 #define EV_PPP_ACCT_START 10 +#define EV_SHUTDOWN_SOFT 11 #define EV_IP_CHANGED 100 #define EV_SHAPER 101 #define EV_MPPE_KEYS 102 diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c index 95e1a86..f8faed8 100644 --- a/accel-pptpd/ppp/ppp.c +++ b/accel-pptpd/ppp/ppp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "linux_ppp.h" #include @@ -30,6 +31,8 @@ __export LIST_HEAD(ppp_list); static LIST_HEAD(layers); int __export sock_fd; +static int ppp_shutdown; + static unsigned long long seq; #if __WORDSIZE == 32 static spinlock_t seq_lock; @@ -226,6 +229,9 @@ static void destablish_ppp(struct ppp_t *ppp) _free(ppp->username); ppp->username = NULL; } + + if (ppp_shutdown && !ppp_stat.starting && !ppp_stat.active && !ppp_stat.finishing) + kill(getpid(), SIGTERM); } /*void print_buf(uint8_t *buf, int size) @@ -592,6 +598,14 @@ struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *ppp, struct ppp_layer return NULL; } +static void ev_shutdown_soft(void) +{ + ppp_shutdown = 1; + + if (!ppp_stat.starting && !ppp_stat.active && !ppp_stat.finishing) + kill(getpid(), SIGTERM); +} + static void save_seq(void) { FILE *f; @@ -633,6 +647,8 @@ static void __init init(void) //log_emerg("ppp: failed to open seq-file (%s): %s\n", opt, strerror(errno)); seq = (unsigned long long)random() * (unsigned long long)random(); + triton_event_register_handler(EV_SHUTDOWN_SOFT, (triton_event_func)ev_shutdown_soft); + atexit(save_seq); } diff --git a/accel-pptpd/ppp/ppp.h b/accel-pptpd/ppp/ppp.h index 1a97099..814a270 100644 --- a/accel-pptpd/ppp/ppp.h +++ b/accel-pptpd/ppp/ppp.h @@ -173,6 +173,8 @@ int ppp_register_layer(const char *name, struct ppp_layer_t *); void ppp_unregister_layer(struct ppp_layer_t *); struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *, struct ppp_layer_t *); +void ppp_shutdown_soft(void); + extern int conf_ppp_verbose; extern pthread_rwlock_t ppp_lock; -- cgit v1.2.3