From 1d0291eec3cbb52f2908e39c9efd174486285760 Mon Sep 17 00:00:00 2001 From: lazio579 Date: Fri, 28 Sep 2018 10:42:29 +0800 Subject: [PATCH] Support single instance --- plugins/admin/admin-plugin.c | 51 ++++++++++++++++++++++++++++++++---- src/cetus-process-cycle.c | 30 ++++++++++++++++++--- src/chassis-mainloop.c | 3 +++ src/chassis-mainloop.h | 1 + src/mysql-proxy-cli.c | 10 +------ src/network-socket.c | 15 ++++++----- 6 files changed, 86 insertions(+), 24 deletions(-) diff --git a/plugins/admin/admin-plugin.c b/plugins/admin/admin-plugin.c index 76fe574..a57f297 100644 --- a/plugins/admin/admin-plugin.c +++ b/plugins/admin/admin-plugin.c @@ -717,6 +717,42 @@ network_mysqld_admin_plugin_get_options(chassis_plugin_config *config) return opts.options; } +static int +check_allowed_running(chassis *chas) +{ + char buffer[64]; + + memset(buffer, 0 ,64); + + sprintf(buffer, "/tmp/%s", chas->proxy_address); + chas->unix_socket_name = g_strdup(buffer); + + int fd; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + g_message("%s:create socket error", G_STRLOC); + return -1; + } + + + struct sockaddr_un un; + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + const char *name = chas->unix_socket_name; + strcpy(un.sun_path, name); + int len = offsetof(struct sockaddr_un, sun_path) + strlen(name); + + if (bind(fd, (struct sockaddr *)&un, len) < 0) { + g_message("%s:already running", G_STRLOC); + close(fd); + return -1; + } + + close(fd); + return 0; +} + + /** * init the plugin with the parsed config */ @@ -738,9 +774,15 @@ network_mysqld_admin_plugin_apply_config(chassis *chas, if (!config->address) { config->address = g_strdup(":4041"); - } else { - chas->proxy_address = config->address; - g_message("set admin address for chassis:%s", config->address); + } + + chas->proxy_address = config->address; + g_message("set admin address for chassis:%s", config->address); + + if (chas->enable_admin_listen) { + if (check_allowed_running(chas) == -1) { + return -1; + } } if (!config->admin_username) { @@ -793,8 +835,7 @@ network_mysqld_admin_plugin_apply_config(chassis *chas, return -1; } - /* FIXME: network_socket_bind() */ - if (0 != network_socket_bind(listen_sock, 0)) { + if (0 != network_socket_bind(listen_sock, 1)) { return -1; } diff --git a/src/cetus-process-cycle.c b/src/cetus-process-cycle.c index 22bb92a..098904f 100644 --- a/src/cetus-process-cycle.c +++ b/src/cetus-process-cycle.c @@ -17,7 +17,7 @@ #include "cetus-process-cycle.h" #include "network-socket.h" #include "chassis-event.h" -#include "chassis-plugin.h" +#include "chassis-frontend.h" #include "glib-ext.h" static void cetus_start_worker_processes(cetus_cycle_t *cycle, int n, int type); @@ -54,7 +54,7 @@ static u_char master_process[] = "master process"; static cetus_cycle_t cetus_exit_cycle; -static void +static int open_admin(cetus_cycle_t *cycle) { int i; @@ -67,9 +67,12 @@ open_admin(cetus_cycle_t *cycle) g_message("%s: call apply_config", G_STRLOC); if (0 != p->apply_config(cycle, p->config)) { g_critical("%s: applying config of plugin %s failed", G_STRLOC, p->name); + return -1; } } } + + return 0; } @@ -86,6 +89,7 @@ cetus_exec_new_binary(cetus_cycle_t *cycle, char **argv) ctx.envp = g_new0(char *, 2); char *new_env = g_new0(char, strlen(env) + 32); sprintf(new_env, "LD_LIBRARY_PATH=%s", env); + ctx.envp[0] = (char *) new_env; ctx.envp[1] = NULL; @@ -120,7 +124,19 @@ cetus_master_process_cycle(cetus_cycle_t *cycle) cetus_start_worker_processes(cycle, cycle->worker_processes, CETUS_PROCESS_RESPAWN); - open_admin(cycle); + if (open_admin(cycle) == -1) { + return; + } + + if (cycle->pid_file) { + GError *gerr = NULL; + if (0 != chassis_frontend_write_pidfile(cycle->pid_file, &gerr)) { + g_critical("%s", gerr->message); + g_clear_error(&gerr); + return; + } + } + live = 1; try_cnt = 0; @@ -161,6 +177,7 @@ cetus_master_process_cycle(cetus_cycle_t *cycle) if (cetus_quit) { cetus_signal_worker_processes(cycle, cetus_signal_value(CETUS_SHUTDOWN_SIGNAL)); + live = 0; continue; } @@ -176,6 +193,9 @@ cetus_master_process_cycle(cetus_cycle_t *cycle) if (cetus_change_binary) { g_message("%s: changing binary", G_STRLOC); + unlink(cycle->unix_socket_name); + g_free(cycle->unix_socket_name); + cycle->unix_socket_name = NULL; cetus_new_binary = cetus_exec_new_binary(cycle, cycle->argv); cetus_change_binary = 0; } @@ -478,6 +498,10 @@ cetus_reap_children(cetus_cycle_t *cycle) static void cetus_master_process_exit(cetus_cycle_t *cycle) { + if (cycle->unix_socket_name) { + unlink(cycle->unix_socket_name); + } + g_message("%s: exit", G_STRLOC); exit(0); diff --git a/src/chassis-mainloop.c b/src/chassis-mainloop.c index 41f3119..676acc4 100644 --- a/src/chassis-mainloop.c +++ b/src/chassis-mainloop.c @@ -194,6 +194,9 @@ chassis_free(chassis *chas) g_hash_table_destroy(chas->query_cache_table); if (chas->cache_index) g_queue_free_cache_index(chas->cache_index); + if (chas->unix_socket_name) { + g_free(chas->unix_socket_name); + } g_free(chas->event_hdr_version); diff --git a/src/chassis-mainloop.h b/src/chassis-mainloop.h index 8f4b7e3..1499a51 100644 --- a/src/chassis-mainloop.h +++ b/src/chassis-mainloop.h @@ -125,6 +125,7 @@ struct chassis { char *default_username; char *default_charset; char *default_hashed_pwd; + char *unix_socket_name; guint64 sess_key; unsigned int maintain_close_mode; diff --git a/src/mysql-proxy-cli.c b/src/mysql-proxy-cli.c index 1208f36..61784a7 100644 --- a/src/mysql-proxy-cli.c +++ b/src/mysql-proxy-cli.c @@ -836,6 +836,7 @@ init_slow_query_log(const char *main_log) return fp; } + /** * This is the "real" main which is called on UNIX platforms. */ @@ -1113,15 +1114,6 @@ main_cmdline(int argc, char **argv) chassis_unix_daemonize(); } - if (srv->pid_file) { - if (0 != chassis_frontend_write_pidfile(srv->pid_file, &gerr)) { - g_critical("%s", gerr->message); - g_clear_error(&gerr); - - GOTO_EXIT(EXIT_FAILURE); - } - } - if(frontend->group_replication_mode != 0 && frontend->group_replication_mode != 1) { g_critical("group-replication-mode is invalid, current value is %d", frontend->group_replication_mode); GOTO_EXIT(EXIT_FAILURE); diff --git a/src/network-socket.c b/src/network-socket.c index ad324d5..deadda2 100644 --- a/src/network-socket.c +++ b/src/network-socket.c @@ -466,17 +466,18 @@ network_socket_bind(network_socket *con, int advanced_mode) } #if defined(SO_REUSEPORT) - if (0 != setsockopt(con->fd, SOL_SOCKET, SO_REUSEPORT, SETSOCKOPT_OPTVAL_CAST & val, sizeof(val))) { - g_critical("%s: setsockopt(%s, SOL_SOCKET, SO_REUSEPORT) failed: %s (%d)", - G_STRLOC, con->dst->name->str, g_strerror(errno), errno); - return NETWORK_SOCKET_ERROR; - } + if (advanced_mode) { + g_message("%s:set SO_REUSEPORT", G_STRLOC); + if (0 != setsockopt(con->fd, SOL_SOCKET, SO_REUSEPORT, SETSOCKOPT_OPTVAL_CAST & val, sizeof(val))) { + g_critical("%s: setsockopt(%s, SOL_SOCKET, SO_REUSEPORT) failed: %s (%d)", + G_STRLOC, con->dst->name->str, g_strerror(errno), errno); + return NETWORK_SOCKET_ERROR; + } #ifdef BPF_ENABLED - if (advanced_mode) { attach_bpf(con->fd); - } #endif + } } #endif