File util_service.c¶
File List > cubrid > src > executables > util_service.c
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* util_service.c - a front end of service utilities
*/
#ident "$Id$"
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#if !defined(WINDOWS)
#include <sys/wait.h>
#endif
#if defined(WINDOWS)
#include <io.h>
#endif
#include "porting.h"
#include "utility.h"
#include "error_code.h"
#include "error_manager.h"
#include "system_parameter.h"
#include "client_support.h"
#include "util_func.h"
#include "util_support.h"
#if defined(WINDOWS)
#include "wintcp.h"
#endif
#include "environment_variable.h"
#include "release_string.h"
#include "dynamic_array.h"
#include "heartbeat.h"
#include "process_util.h"
#include "pl_file.h"
#include <string>
#if defined(WINDOWS)
typedef int pid_t;
#endif
typedef enum
{
SERVICE = 0,
SERVER = 1,
BROKER = 2,
MANAGER = 3,
HEARTBEAT = 4,
UTIL_HELP = 6,
UTIL_VERSION = 7,
ADMIN = 8,
PL_UTIL = 20, // JAVASP_UTIL
GATEWAY = 21,
} UTIL_SERVICE_INDEX_E;
typedef enum
{
START,
STOP,
RESTART,
STATUS,
DEREGISTER,
LIST,
RELOAD,
ON,
OFF,
ACCESS_CONTROL,
RESET,
INFO,
SC_COPYLOGDB,
SC_APPLYLOGDB,
GET_SHARID,
TEST,
REPLICATION
} UTIL_SERVICE_COMMAND_E;
typedef enum
{
SERVICE_START_SERVER,
SERVICE_START_BROKER,
SERVICE_START_MANAGER,
SERVER_START_LIST,
SERVICE_START_HEARTBEAT,
SERVICE_START_GATEWAY
} UTIL_SERVICE_PROPERTY_E;
typedef enum
{
ALL_SERVICES_RUNNING,
ALL_SERVICES_STOPPED
} UTIL_ALL_SERVICES_STATUS;
typedef enum
{
MANAGER_SERVER_RUNNING = 0,
MANAGER_SERVER_STOPPED,
MANAGER_SERVER_STATUS_ERROR
} UTIL_MANAGER_SERVER_STATUS_E;
typedef enum
{
PL_SERVER_RUNNING = 0,
PL_SERVER_STOPPED,
PL_SERVER_STATUS_ERROR,
PL_SERVER_STARTING
} UTIL_PL_SERVER_STATUS_E;
typedef struct
{
int option_type;
const char *option_name;
int option_mask;
} UTIL_SERVICE_OPTION_MAP_T;
typedef struct
{
int property_index;
const char *property_value;
} UTIL_SERVICE_PROPERTY_T;
#define UTIL_TYPE_SERVICE "service"
#define UTIL_TYPE_SERVER "server"
#define UTIL_TYPE_BROKER "broker"
#define UTIL_TYPE_MANAGER "manager"
#define UTIL_TYPE_HEARTBEAT "heartbeat"
#define UTIL_TYPE_HB_SHORT "hb"
#define UTIL_TYPE_PL "pl"
#define UTIL_TYPE_GATEWAY "gateway"
static UTIL_SERVICE_OPTION_MAP_T us_Service_map[] = {
{SERVICE, UTIL_TYPE_SERVICE, MASK_SERVICE},
{SERVER, UTIL_TYPE_SERVER, MASK_SERVER},
{BROKER, UTIL_TYPE_BROKER, MASK_BROKER},
{MANAGER, UTIL_TYPE_MANAGER, MASK_MANAGER},
{HEARTBEAT, UTIL_TYPE_HEARTBEAT, MASK_HEARTBEAT},
{HEARTBEAT, UTIL_TYPE_HB_SHORT, MASK_HEARTBEAT},
{PL_UTIL, UTIL_TYPE_PL, MASK_PL},
{GATEWAY, UTIL_TYPE_GATEWAY, MASK_GATEWAY},
{UTIL_HELP, "--help", MASK_ALL},
{UTIL_VERSION, "--version", MASK_ALL},
{ADMIN, UTIL_OPTION_CREATEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_RENAMEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_COPYDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_DELETEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_BACKUPDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_RESTOREDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_ADDVOLDB, MASK_ADMIN},
#if 0
{ADMIN, UTIL_OPTION_DELVOLDB, MASK_ADMIN},
#endif /* ` */
{ADMIN, UTIL_OPTION_SPACEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_LOCKDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_KILLTRAN, MASK_ADMIN},
{ADMIN, UTIL_OPTION_OPTIMIZEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_INSTALLDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_DIAGDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_CLEANFILEDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_PATCHDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_CHECKDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_ALTERDBHOST, MASK_ADMIN},
{ADMIN, UTIL_OPTION_PLANDUMP, MASK_ADMIN},
{ADMIN, UTIL_OPTION_ESTIMATE_DATA, MASK_ADMIN},
{ADMIN, UTIL_OPTION_ESTIMATE_INDEX, MASK_ADMIN},
{ADMIN, UTIL_OPTION_LOADDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_UNLOADDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_COMPACTDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_PARAMDUMP, MASK_ADMIN},
{ADMIN, UTIL_OPTION_STATDUMP, MASK_ADMIN},
{ADMIN, UTIL_OPTION_CHANGEMODE, MASK_ADMIN},
{ADMIN, UTIL_OPTION_APPLYINFO, MASK_ADMIN},
{ADMIN, UTIL_OPTION_GENERATE_LOCALE, MASK_ADMIN},
{ADMIN, UTIL_OPTION_DUMP_LOCALE, MASK_ADMIN},
{ADMIN, UTIL_OPTION_TRANLIST, MASK_ADMIN},
{ADMIN, UTIL_OPTION_GEN_TZ, MASK_ADMIN},
{ADMIN, UTIL_OPTION_DUMP_TZ, MASK_ADMIN},
{ADMIN, UTIL_OPTION_SYNCCOLLDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_RESTORESLAVE, MASK_ADMIN},
{ADMIN, UTIL_OPTION_VACUUMDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_CHECKSUMDB, MASK_ADMIN},
{ADMIN, UTIL_OPTION_TDE, MASK_ADMIN},
{ADMIN, UTIL_OPTION_FLASHBACK, MASK_ADMIN},
{ADMIN, UTIL_OPTION_MEMMON, MASK_ADMIN},
{-1, "", MASK_ADMIN}
};
#define COMMAND_TYPE_START "start"
#define COMMAND_TYPE_STOP "stop"
#define COMMAND_TYPE_RESTART "restart"
#define COMMAND_TYPE_STATUS "status"
#define COMMAND_TYPE_DEREG "deregister"
#define COMMAND_TYPE_LIST "list"
#define COMMAND_TYPE_RELOAD "reload"
#define COMMAND_TYPE_ON "on"
#define COMMAND_TYPE_OFF "off"
#define COMMAND_TYPE_ACL "acl"
#define COMMAND_TYPE_RESET "reset"
#define COMMAND_TYPE_INFO "info"
#define COMMAND_TYPE_COPYLOGDB "copylogdb"
#define COMMAND_TYPE_APPLYLOGDB "applylogdb"
#define COMMAND_TYPE_GETID "getid"
#define COMMAND_TYPE_TEST "test"
#define COMMAND_TYPE_REPLICATION "replication"
#define COMMAND_TYPE_REPLICATION_SHORT "repl"
static UTIL_SERVICE_OPTION_MAP_T us_Command_map[] = {
{START, COMMAND_TYPE_START, MASK_ALL & ~MASK_PL},
{STOP, COMMAND_TYPE_STOP, MASK_ALL & ~MASK_PL},
{RESTART, COMMAND_TYPE_RESTART, MASK_SERVICE | MASK_SERVER | MASK_BROKER | MASK_GATEWAY | MASK_PL},
{STATUS, COMMAND_TYPE_STATUS, MASK_ALL},
{DEREGISTER, COMMAND_TYPE_DEREG, MASK_HEARTBEAT},
{LIST, COMMAND_TYPE_LIST, MASK_HEARTBEAT},
{RELOAD, COMMAND_TYPE_RELOAD, MASK_HEARTBEAT},
{ON, COMMAND_TYPE_ON, MASK_BROKER | MASK_GATEWAY},
{OFF, COMMAND_TYPE_OFF, MASK_BROKER | MASK_GATEWAY},
{ACCESS_CONTROL, COMMAND_TYPE_ACL, MASK_SERVER | MASK_BROKER | MASK_GATEWAY},
{RESET, COMMAND_TYPE_RESET, MASK_BROKER | MASK_GATEWAY},
{INFO, COMMAND_TYPE_INFO, MASK_BROKER | MASK_GATEWAY},
{SC_COPYLOGDB, COMMAND_TYPE_COPYLOGDB, MASK_HEARTBEAT},
{SC_APPLYLOGDB, COMMAND_TYPE_APPLYLOGDB, MASK_HEARTBEAT},
{GET_SHARID, COMMAND_TYPE_GETID, MASK_BROKER},
{TEST, COMMAND_TYPE_TEST, MASK_BROKER},
{REPLICATION, COMMAND_TYPE_REPLICATION, MASK_HEARTBEAT},
{REPLICATION, COMMAND_TYPE_REPLICATION_SHORT, MASK_HEARTBEAT},
{-1, "", MASK_ALL}
};
static UTIL_SERVICE_PROPERTY_T us_Property_map[] = {
{SERVICE_START_SERVER, NULL},
{SERVICE_START_BROKER, NULL},
{SERVICE_START_MANAGER, NULL},
{SERVER_START_LIST, NULL},
{SERVICE_START_HEARTBEAT, NULL},
{SERVICE_START_GATEWAY, NULL},
{-1, NULL}
};
static const char **Argv;
static int ha_mode_in_common;
static int util_get_service_option_mask (int util_type);
static int util_get_command_option_mask (int command_type);
static void util_service_usage (int util_type);
static void util_service_version (const char *argv0);
static int load_properties (void);
static void finalize_properties (void);
static const char *get_property (int property_type);
static int parse_arg (UTIL_SERVICE_OPTION_MAP_T * option, const char *arg);
static int process_service (int command_type, bool process_window_service);
static int process_server (int command_type, int argc, char **argv, bool show_usage, bool check_ha_mode,
bool process_window_service);
static int process_broker (int command_type, int argc, const char **argv, bool process_window_service);
static int process_gateway (int command_type, int argc, const char **argv, bool process_window_service);
static int process_manager (int command_type, bool process_window_service);
static int process_pl (int command_type, int argc, const char **argv, bool show_usage, bool suppress_message,
bool process_window_service, bool ha_mode);
static int process_pl_restart (const char *db_name, bool suppress_message, bool process_window_service);
static int process_pl_status (const char *db_name, bool suppress_message);
static int process_heartbeat (int command_type, int argc, const char **argv);
static int process_heartbeat_start (HA_CONF * ha_conf, int argc, const char **argv);
static int process_heartbeat_stop (HA_CONF * ha_conf, int argc, const char **argv);
static int process_heartbeat_deregister (int argc, const char **argv);
static int process_heartbeat_status (int argc, const char **argv);
static int process_heartbeat_reload (int argc, const char **argv);
static int process_heartbeat_util (HA_CONF * ha_conf, int command_type, int argc, const char **argv);
static int process_heartbeat_replication (HA_CONF * ha_conf, int argc, const char **argv);
static int proc_execute_internal (const char *file, const char *args[], bool wait_child, bool close_output,
bool close_err, bool hide_cmd_args, int *pid);
static int proc_execute (const char *file, const char *args[], bool wait_child, bool close_output, bool close_err,
int *pid);
static int proc_execute_hide_cmd_args (const char *file, const char *args[], bool wait_child, bool close_output,
bool close_err, int *pid);
static void hide_cmd_line_args (char **args);
static int process_master (int command_type);
static void print_message (FILE * output, int message_id, ...);
static void print_result (const char *util_name, int status, int command_type);
static char *make_exec_abspath (char *buf, int buf_len, char *cmd);
static const char *command_string (int command_type);
static bool is_server_running (const char *type, const char *server_name, int pid);
static int shutdown_reviving_server (const char *server_name);
static int is_broker_running (void);
static int is_gateway_running (void);
static UTIL_MANAGER_SERVER_STATUS_E is_manager_running (unsigned int sleep_time);
static UTIL_PL_SERVER_STATUS_E is_pl_running (const char *server_name);
static void get_server_names (const char *type, char **name_buffer);
#if defined(WINDOWS)
static bool is_windows_service_running (unsigned int sleep_time);
#endif
static bool are_all_services_running (unsigned int sleep_time, bool check_win_service);
static bool are_all_services_stopped (unsigned int sleep_time, bool check_win_service);
static bool check_all_services_status (unsigned int sleep_time, UTIL_ALL_SERVICES_STATUS expected_status,
bool check_win_service);
static bool ha_make_mem_size (char *mem_size, int size, int value);
static bool ha_is_registered (const char *args, const char *hostname);
#if !defined(WINDOWS)
static int us_hb_copylogdb_start (dynamic_array * out_ap, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host);
static int us_hb_copylogdb_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host);
static int us_hb_applylogdb_start (dynamic_array * out_ap, HA_CONF * ha_conf, const char *db_name,
const char *node_name, const char *remote_host);
static int us_hb_applylogdb_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host);
#if defined (ENABLE_UNUSED_FUNCTION)
static int us_hb_utils_start (dynamic_array * pids, HA_CONF * ha_conf, const char *db_name, const char *node_name);
static int us_hb_utils_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name);
#endif /* ENABLE_UNUSED_FUNCTION */
static int us_hb_server_start (HA_CONF * ha_conf, const char *db_name);
static int us_hb_server_stop (HA_CONF * ha_conf, const char *db_name);
static int us_hb_process_start (HA_CONF * ha_conf, const char *db_name, bool check_result);
static int us_hb_process_stop (HA_CONF * ha_conf, const char *db_name);
static int us_hb_process_copylogdb (int command_type, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host);
static int us_hb_process_applylogdb (int command_type, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host);
#if defined (ENABLE_UNUSED_FUNCTION)
static int us_hb_process_server (int command_type, HA_CONF * ha_conf, const char *db_name);
#endif /* ENABLE_UNUSED_FUNCTION */
static int us_hb_stop_get_options (char *db_name, int db_name_size, char *host_name, int host_name_size,
bool * immediate_stop, int argc, const char **argv);
static int us_hb_status_get_options (bool * verbose, char *remote_host_name, int remote_host_name_size, int argc,
const char **argv);
static int us_hb_util_get_options (char *db_name, int db_name_size, char *node_name, int node_name_size,
char *remote_host_name, int remote_host_name_size, int argc, const char **argv);
#define US_HB_DEREG_WAIT_TIME_IN_SEC 100
#endif /* !WINDOWS */
static char *
make_exec_abspath (char *buf, int buf_len, char *cmd)
{
buf[0] = '\0';
(void) envvar_bindir_file (buf, buf_len, cmd);
return buf;
}
static const char *
command_string (int command_type)
{
const char *command;
switch (command_type)
{
case START:
command = PRINT_CMD_START;
break;
case RESTART:
command = PRINT_CMD_RESTART;
break;
case STATUS:
command = PRINT_CMD_STATUS;
break;
case DEREGISTER:
command = PRINT_CMD_DEREG;
break;
case LIST:
command = PRINT_CMD_LIST;
break;
case RELOAD:
command = PRINT_CMD_RELOAD;
break;
case ACCESS_CONTROL:
command = PRINT_CMD_ACL;
break;
case SC_COPYLOGDB:
command = PRINT_CMD_COPYLOGDB;
break;
case SC_APPLYLOGDB:
command = PRINT_CMD_APPLYLOGDB;
break;
case TEST:
command = PRINT_CMD_TEST;
break;
case REPLICATION:
command = PRINT_CMD_REPLICATION;
break;
case STOP:
default:
command = PRINT_CMD_STOP;
break;
}
return command;
}
static void
print_result (const char *util_name, int status, int command_type)
{
const char *result;
if (status != NO_ERROR)
{
result = PRINT_RESULT_FAIL;
}
else
{
result = PRINT_RESULT_SUCCESS;
}
print_message (stdout, MSGCAT_UTIL_GENERIC_RESULT, util_name, command_string (command_type), result);
}
/*
* print_message() -
*
* return:
*
*/
static void
print_message (FILE * output, int message_id, ...)
{
va_list arg_list;
const char *format;
format = utility_get_generic_message (message_id);
va_start (arg_list, message_id);
vfprintf (output, format, arg_list);
va_end (arg_list);
fflush (output);
}
/*
* process_admin() - process admin utility
*
* return:
*
*/
static int
process_admin (int argc, char **argv)
{
char **copy_argv;
int status;
/* execv expects NULL terminated arguments vector */
copy_argv = (char **) malloc (sizeof (char *) * (argc + 1));
if (copy_argv == NULL)
{
return ER_GENERIC_ERROR;
}
memcpy (copy_argv, argv, sizeof (char *) * argc);
copy_argv[argc] = NULL;
status = proc_execute_hide_cmd_args (UTIL_ADMIN_NAME, (const char **) copy_argv, true, false, false, NULL);
free (copy_argv);
return status;
}
/*
* util_get_service_option_mask () -
*
*/
static int
util_get_service_option_mask (int util_type)
{
int i;
assert (util_type != ADMIN);
for (i = 0; us_Service_map[i].option_type != -1; i++)
{
if (us_Service_map[i].option_type == util_type)
{
return us_Service_map[i].option_mask;
}
}
return 0; /* NULL mask */
}
/*
* util_get_command_option_mask () -
*
*/
static int
util_get_command_option_mask (int command_type)
{
int i;
for (i = 0; us_Command_map[i].option_type != -1; i++)
{
if (us_Command_map[i].option_type == command_type)
{
return us_Command_map[i].option_mask;
}
}
return 0; /* NULL mask */
}
/*
* main() - a service utility's entry point
*
* return:
*
* NOTE:
*/
int
main (int argc, char *argv[])
{
int util_type, command_type;
int status;
bool process_window_service = false;
pid_t pid = getpid ();
char env_buf[16];
int util_name_pos = 0;
sprintf (env_buf, "%d", pid);
envvar_set (UTIL_PID_ENVVAR_NAME, env_buf);
ER_SAFE_INIT (NULL, ER_NEVER_EXIT);
Argv = (const char **) argv;
if (argc == 2)
{
if (parse_arg (us_Service_map, (char *) argv[1]) == UTIL_VERSION)
{
util_service_version (argv[0]);
return EXIT_SUCCESS;
}
}
/* validate the number of arguments to avoid Klockwork's error message */
if (argc < 2 || argc > 1024)
{
util_type = -1;
goto usage;
}
util_type = parse_arg (us_Service_map, (char *) argv[1]);
if (util_type == ER_GENERIC_ERROR)
{
util_type = parse_arg (us_Service_map, (char *) argv[2]);
if (util_type == ER_GENERIC_ERROR)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_INVALID_NAME, argv[1]);
goto error;
}
if (util_type == ADMIN)
{
util_name_pos = 2;
}
}
else if (util_type == ADMIN)
{
util_name_pos = 1;
}
if (load_properties () != NO_ERROR)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
util_log_write_command (argc, argv, util_name_pos);
util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
return EXIT_FAILURE;
}
ha_mode_in_common = prm_get_integer_value (PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY);
if (util_type == ADMIN)
{
util_log_write_command (argc, argv, util_name_pos);
status = process_admin (argc, argv);
util_log_write_result (status);
return status;
}
if (util_type == UTIL_HELP)
{
util_type = -1;
goto usage;
}
if (argc < 3)
{
goto usage;
}
command_type = parse_arg (us_Command_map, (char *) argv[2]);
if (command_type == ER_GENERIC_ERROR)
{
command_type = parse_arg (us_Command_map, (char *) argv[1]);
if (command_type == ER_GENERIC_ERROR)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_INVALID_CMD, argv[2]);
goto error;
}
}
else
{
int util_mask = util_get_service_option_mask (util_type);
int command_mask = util_get_command_option_mask (command_type);
if ((util_mask & command_mask) == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_INVALID_CMD, argv[2]);
goto error;
}
}
util_log_write_command (argc, argv, util_name_pos);
#if defined(WINDOWS)
if (css_windows_startup () < 0)
{
util_log_write_errstr ("Unable to initialize Winsock.\n");
goto error;
}
process_window_service = true;
if ((util_type == SERVICE || util_type == BROKER || util_type == GATEWAY || util_type == MANAGER) && (argc > 3)
&& strcmp ((char *) argv[3], "--for-windows-service") == 0)
{
process_window_service = false;
}
else if ((util_type == SERVER || util_type == BROKER || util_type == GATEWAY || util_type == PL_UTIL)
&& (argc > 4) && strcmp ((char *) argv[4], "--for-windows-service") == 0)
{
process_window_service = false;
}
#else
assert (process_window_service == false);
#endif
switch (util_type)
{
case SERVICE:
{
status = process_service (command_type, process_window_service);
}
break;
case SERVER:
status = process_server (command_type, argc - 3, &argv[3], true, true, process_window_service);
break;
case BROKER:
status = process_broker (command_type, argc - 3, (const char **) &argv[3], process_window_service);
break;
case MANAGER:
status = process_manager (command_type, process_window_service);
break;
case HEARTBEAT:
#if defined(WINDOWS)
/* TODO : define message catalog for heartbeat */
return EXIT_FAILURE;
#else
status = process_heartbeat (command_type, argc - 3, (const char **) &argv[3]);
#endif /* !WINDOWs */
break;
case PL_UTIL: // PL_UTIL
status =
process_pl (command_type, argc - 3, (const char **) &argv[3], true, false, process_window_service, false);
break;
case GATEWAY:
status = process_gateway (command_type, argc - 3, (const char **) &argv[3], process_window_service);
break;
default:
goto usage;
}
util_log_write_result (status);
return ((status == NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE);
usage:
util_service_usage (util_type);
error:
finalize_properties ();
#if defined(WINDOWS)
css_windows_shutdown ();
#endif /* WINDOWS */
return EXIT_FAILURE;
}
/*
* util_service_usage - display an usage of this utility
*
* return:
*
* NOTE:
*/
static void
util_service_usage (int util_type)
{
char *exec_name;
if (util_type < 0)
{
util_type = 0;
}
else
{
util_type++;
}
exec_name = basename ((char *) Argv[0]);
print_message (stdout, MSGCAT_UTIL_GENERIC_CUBRID_USAGE + util_type, PRODUCT_STRING, exec_name, exec_name, exec_name);
}
/*
* util_service_version - display a version of this utility
*
* return:
*
* NOTE:
*/
static void
util_service_version (const char *argv0)
{
const char *exec_name;
char buf[REL_MAX_VERSION_LENGTH];
exec_name = basename ((char *) argv0);
rel_copy_version_string (buf, REL_MAX_VERSION_LENGTH);
print_message (stdout, MSGCAT_UTIL_GENERIC_VERSION, exec_name, buf);
}
/*
* proc_execute - to fork/exec internal service exes
*/
static int
proc_execute (const char *file, const char *args[], bool wait_child, bool close_output, bool close_err, int *out_pid)
{
return proc_execute_internal (file, args, wait_child, close_output, close_err, false, out_pid);
}
/*
* proc_execute_hide_cmd_args - to fork/exec cub_admin for command line
*
* It will hide commandline arguments.
*/
static int
proc_execute_hide_cmd_args (const char *file, const char *args[], bool wait_child, bool close_output, bool close_err,
int *out_pid)
{
return proc_execute_internal (file, args, wait_child, close_output, close_err, true, out_pid);
}
#if defined(WINDOWS)
static int
proc_execute_internal (const char *file, const char *args[], bool wait_child, bool close_output, bool close_err,
bool hide_cmd_args, int *out_pid)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
int i, j, k, cmd_arg_len;
char cmd_arg[1024];
char executable_path[PATH_MAX];
int ret_code = NO_ERROR;
bool inherited_handle = TRUE;
char fixed_arg[1024]; /* replace " with "" */
if (out_pid)
{
*out_pid = 0;
}
(void) envvar_bindir_file (executable_path, PATH_MAX, file);
for (i = 0, cmd_arg_len = 0; args[i]; i++)
{
if (strchr (args[i], '"') == NULL)
{
cmd_arg_len += sprintf (cmd_arg + cmd_arg_len, "\"%s\" ", args[i]);
}
else
{
k = 0;
for (j = 0; args[i][j] != '\0'; j++)
{
if (args[i][j] == '"')
{
fixed_arg[k++] = '"';
}
fixed_arg[k++] = args[i][j];
}
fixed_arg[k] = '\0';
cmd_arg_len += sprintf (cmd_arg + cmd_arg_len, "\"%s\" ", fixed_arg);
}
}
GetStartupInfo (&si);
si.dwFlags = si.dwFlags | STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
inherited_handle = TRUE;
if (close_output)
{
si.hStdOutput = NULL;
}
if (close_err)
{
si.hStdError = NULL;
}
if (!CreateProcess (executable_path, cmd_arg, NULL, NULL, inherited_handle, 0, NULL, NULL, &si, &pi))
{
return ER_FAILED;
}
if (wait_child)
{
DWORD status = 0;
WaitForSingleObject (pi.hProcess, INFINITE);
GetExitCodeProcess (pi.hProcess, &status);
ret_code = status;
}
else
{
if (out_pid)
{
*out_pid = pi.dwProcessId;
}
}
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
return ret_code;
}
#else
static int
proc_execute_internal (const char *file, const char *args[], bool wait_child, bool close_output, bool close_err,
bool hide_cmd_args, int *out_pid)
{
pid_t pid, tmp;
char executable_path[PATH_MAX];
if (out_pid)
{
*out_pid = 0;
}
(void) envvar_bindir_file (executable_path, PATH_MAX, file);
/* do not process SIGCHLD, a child process will be defunct */
if (wait_child)
{
signal (SIGCHLD, SIG_DFL);
}
else
{
signal (SIGCHLD, SIG_IGN);
}
pid = fork ();
if (pid == -1)
{
perror ("fork");
return ER_GENERIC_ERROR;
}
else if (pid == 0)
{
/* a child process handle SIGCHLD to SIG_DFL */
signal (SIGCHLD, SIG_DFL);
if (close_output)
{
close (STDOUT_FILENO);
}
if (close_err)
{
close (STDERR_FILENO);
}
if (execv (executable_path, (char *const *) args) == -1)
{
perror ("execv");
return ER_GENERIC_ERROR;
}
}
else
{
int status = 0;
if (hide_cmd_args == true)
{
/* for hide password */
hide_cmd_line_args ((char **) args);
}
/* sleep (0); */
if (wait_child)
{
do
{
tmp = waitpid (-1, &status, 0);
if (tmp == -1)
{
perror ("waitpid");
return ER_GENERIC_ERROR;
}
}
while (tmp != pid);
}
else
{
/* sleep (3); */
if (out_pid)
{
*out_pid = pid;
}
return NO_ERROR;
}
if (WIFEXITED (status))
{
return WEXITSTATUS (status);
}
}
return ER_GENERIC_ERROR;
}
#endif
/*
* hide_cmd_line_args -
*
* return:
*
*/
static void
hide_cmd_line_args (char **args)
{
#if defined (LINUX)
int i;
assert (args[0] != NULL && args[1] != NULL);
for (i = 2; args[i] != NULL; i++)
{
memset (args[i], '\0', strlen (args[i]));
}
#endif /* LINUX */
}
/*
* process_master -
*
* return:
*
* command_type(in):
*/
static int
process_master (int command_type)
{
int status = NO_ERROR;
int pid = 0;
int waited_seconds = 0;
int master_port = prm_get_master_port_id ();
switch (command_type)
{
case START:
{
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_MASTER_NAME, PRINT_CMD_START);
if (!__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = { UTIL_MASTER_NAME, NULL };
status = ER_GENERIC_ERROR;
while (status != NO_ERROR && waited_seconds < 180)
{
if (pid == 0 || (pid != 0 && is_terminated_process (pid)))
{
if (pid != 0)
{
util_log_write_errstr ("Master does not exist. Try to start it again.\n");
}
#if !defined(WINDOWS)
envvar_set ("NO_DAEMON", "true");
#endif
status = proc_execute (UTIL_MASTER_NAME, args, false, false, false, &pid);
if (status != NO_ERROR)
{
util_log_write_errstr ("Could not start master process.\n");
break;
}
}
/* The master process needs a few seconds to bind port */
sleep (1);
waited_seconds++;
status = __gv_cvar.css_does_master_exist (master_port) ? NO_ERROR : ER_GENERIC_ERROR;
}
if (status != NO_ERROR)
{
/* The master process failed to start or could not connected within 3 minutes */
util_log_write_errid (MSGCAT_UTIL_GENERIC_RESULT, PRINT_MASTER_NAME, command_string (command_type),
PRINT_RESULT_FAIL);
}
print_result (PRINT_MASTER_NAME, status, command_type);
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MASTER_NAME);
}
}
break;
case STOP:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_MASTER_NAME, PRINT_CMD_STOP);
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = { UTIL_COMMDB_NAME, COMMDB_ALL_STOP, NULL };
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
status = __gv_cvar.css_does_master_exist (master_port) ? ER_GENERIC_ERROR : NO_ERROR;
print_result (PRINT_MASTER_NAME, status, command_type);
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
break;
}
return status;
}
#if defined(WINDOWS)
/*
* is_windwos_service_running -
*
* return:
*
* sleep_time(in):
*
* NOTE:
*/
static bool
is_windows_service_running (unsigned int sleep_time)
{
FILE *input;
char buf[32], cmd[PATH_MAX];
sleep (sleep_time);
make_exec_abspath (cmd, PATH_MAX, (char *) UTIL_WIN_SERVICE_CONTROLLER_NAME " " "-status");
input = popen (cmd, "r");
if (input == NULL)
{
return false;
}
memset (buf, '\0', sizeof (buf));
if ((fgets (buf, 32, input) == NULL) || strncmp (buf, "SERVICE_RUNNING", 15) != 0)
{
pclose (input);
return false;
}
pclose (input);
return true;
}
#endif
/*
* are_all_services_running - are all of services running
*
* return:
*
* sleep_time(in):
*
* NOTE:
*/
static bool
are_all_services_running (unsigned int sleep_time, bool check_win_service)
{
return check_all_services_status (sleep_time, ALL_SERVICES_RUNNING, check_win_service);
}
/*
* are_all_services_stopped - are all of services stopped
*
* return:
*
* sleep_time(in):
*
* NOTE:
*/
static bool
are_all_services_stopped (unsigned int sleep_time, bool check_win_service)
{
return check_all_services_status (sleep_time, ALL_SERVICES_STOPPED, check_win_service);
}
/*
* check_all_services_status - check all service status and compare with
expected_status, if not meet return false.
*
* return:
*
* sleep_time(in):
* expected_status(in);
* NOTE:
*/
static bool
check_all_services_status (unsigned int sleep_time, UTIL_ALL_SERVICES_STATUS expected_status, bool check_win_service)
{
bool ret;
int master_port;
if (check_win_service)
{
#if defined (WINDOWS)
/* check whether CUBRIDService is running */
ret = is_windows_service_running (sleep_time);
if ((expected_status == ALL_SERVICES_RUNNING && !ret) || (expected_status == ALL_SERVICES_STOPPED && ret))
{
return false;
}
#else
assert (0);
return false;
#endif
}
master_port = prm_get_master_port_id ();
/* check whether cub_master is running */
ret = __gv_cvar.css_does_master_exist (master_port);
if ((expected_status == ALL_SERVICES_RUNNING && !ret) || (expected_status == ALL_SERVICES_STOPPED && ret))
{
return false;
}
if (strcmp (get_property (SERVICE_START_SERVER), PROPERTY_ON) == 0
&& us_Property_map[SERVER_START_LIST].property_value != NULL)
{
char buf[4096];
char *list, *token, *save;
const char *delim = " ,:";
memset (buf, '\0', sizeof (buf));
strncpy (buf, us_Property_map[SERVER_START_LIST].property_value, sizeof (buf) - 1);
for (list = buf;; list = NULL)
{
token = strtok_r (list, delim, &save);
if (token == NULL)
{
break;
}
/* check whether cub_server is running */
ret = is_server_running (CHECK_SERVER, token, 0);
if ((expected_status == ALL_SERVICES_RUNNING && !ret) || (expected_status == ALL_SERVICES_STOPPED && ret))
{
return false;
}
}
}
/* check whether cub_broker is running */
if (strcmp (get_property (SERVICE_START_BROKER), PROPERTY_ON) == 0)
{
int broker_status;
/* broker_status may be 0, 1, 2. */
broker_status = is_broker_running ();
if ((expected_status == ALL_SERVICES_RUNNING && broker_status != 0)
|| (expected_status == ALL_SERVICES_STOPPED && broker_status != 1))
{
return false;
}
}
/* check whether cub_gateway is running */
if (strcmp (get_property (SERVICE_START_GATEWAY), PROPERTY_ON) == 0)
{
int gateway_status;
/* gateway_status may be 0, 1, 2. */
gateway_status = is_gateway_running ();
if ((expected_status == ALL_SERVICES_RUNNING && gateway_status != 0)
|| (expected_status == ALL_SERVICES_STOPPED && gateway_status != 1))
{
return false;
}
}
/* check whether cub_manager is running */
if (strcmp (get_property (SERVICE_START_MANAGER), PROPERTY_ON) == 0)
{
UTIL_MANAGER_SERVER_STATUS_E manager_status;
manager_status = is_manager_running (0);
if ((expected_status == ALL_SERVICES_RUNNING && manager_status != MANAGER_SERVER_RUNNING)
|| (expected_status == ALL_SERVICES_STOPPED && manager_status != MANAGER_SERVER_STOPPED))
{
return false;
}
}
/* do not check heartbeat in windows */
return true;
}
/*
* process_service -
*
* return:
*
* command_type(in):
* process_window_service(in):
*
* NOTE:
*/
static int
process_service (int command_type, bool process_window_service)
{
int status = NO_ERROR;
switch (command_type)
{
case START:
if (process_window_service)
{
#if defined(WINDOWS)
if (!are_all_services_running (0, process_window_service))
{
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_SERVICE,
PRINT_CMD_START, NULL
};
proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = are_all_services_running (0, process_window_service) ? NO_ERROR : ER_GENERIC_ERROR;
print_result (PRINT_SERVICE_NAME, status, command_type);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_SERVICE_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_SERVICE_NAME);
status = ER_GENERIC_ERROR;
}
#endif
}
else
{
if (!are_all_services_running (0, process_window_service))
{
(void) process_master (command_type);
if (strcmp (get_property (SERVICE_START_SERVER), PROPERTY_ON) == 0
&& us_Property_map[SERVER_START_LIST].property_value != NULL
&& us_Property_map[SERVER_START_LIST].property_value[0] != '\0')
{
(void) process_server (command_type, 0, NULL, false, true, false);
}
if (strcmp (get_property (SERVICE_START_BROKER), PROPERTY_ON) == 0)
{
(void) process_broker (command_type, 0, NULL, false);
}
if (strcmp (get_property (SERVICE_START_GATEWAY), PROPERTY_ON) == 0)
{
(void) process_gateway (command_type, 0, NULL, false);
}
if (strcmp (get_property (SERVICE_START_MANAGER), PROPERTY_ON) == 0)
{
(void) process_manager (command_type, false);
}
if (strcmp (get_property (SERVICE_START_HEARTBEAT), PROPERTY_ON) == 0)
{
(void) process_heartbeat (command_type, 0, NULL);
}
status = are_all_services_running (0, process_window_service) ? NO_ERROR : ER_GENERIC_ERROR;
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_SERVICE_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_SERVICE_NAME);
status = ER_GENERIC_ERROR;
}
}
break;
case STOP:
if (process_window_service)
{
#if defined(WINDOWS)
if (is_windows_service_running (0))
{
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_SERVICE,
PRINT_CMD_STOP, NULL
};
proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = are_all_services_stopped (0, process_window_service) ? NO_ERROR : ER_GENERIC_ERROR;
print_result (PRINT_SERVICE_NAME, status, command_type);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_SERVICE_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_SERVICE_NAME);
status = ER_GENERIC_ERROR;
}
#endif
}
else
{
if (!are_all_services_stopped (0, process_window_service))
{
if (strcmp (get_property (SERVICE_START_SERVER), PROPERTY_ON) == 0
&& us_Property_map[SERVER_START_LIST].property_value != NULL
&& us_Property_map[SERVER_START_LIST].property_value[0] != '\0')
{
(void) process_server (command_type, 0, NULL, false, true, false);
}
if (strcmp (get_property (SERVICE_START_BROKER), PROPERTY_ON) == 0)
{
(void) process_broker (command_type, 0, NULL, false);
}
if (strcmp (get_property (SERVICE_START_GATEWAY), PROPERTY_ON) == 0)
{
(void) process_gateway (command_type, 0, NULL, false);
}
if (strcmp (get_property (SERVICE_START_MANAGER), PROPERTY_ON) == 0)
{
(void) process_manager (command_type, false);
}
if (strcmp (get_property (SERVICE_START_HEARTBEAT), PROPERTY_ON) == 0)
{
(void) process_heartbeat (command_type, 0, NULL);
}
(void) process_master (command_type);
status = are_all_services_stopped (0, process_window_service) ? NO_ERROR : ER_GENERIC_ERROR;
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_SERVICE_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_SERVICE_NAME);
status = ER_GENERIC_ERROR;
}
}
break;
case RESTART:
status = process_service (STOP, process_window_service);
status = process_service (START, process_window_service);
break;
case STATUS:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_MASTER_NAME, PRINT_CMD_STATUS);
if (__gv_cvar.css_does_master_exist (prm_get_master_port_id ()))
{
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MASTER_NAME);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
{
const char *args[] = { "-b" };
(void) process_server (command_type, 0, NULL, false, true, false);
(void) process_pl (command_type, 0, NULL, true, false, false, false);
(void) process_broker (command_type, 1, args, false);
(void) process_gateway (command_type, 1, args, false);
(void) process_manager (command_type, false);
if (strcmp (get_property (SERVICE_START_HEARTBEAT), PROPERTY_ON) == 0)
{
(void) process_heartbeat (command_type, 0, NULL);
}
}
break;
default:
status = ER_GENERIC_ERROR;
}
return status;
}
/*
* get_server_names -
*
* return:
*
* out_buffer (out):
*/
static void
get_server_names (const char *type, char **name_buffer)
{
FILE *input;
char buf[4096];
char cmd[PATH_MAX];
assert (strcmp (type, CHECK_SERVER) == 0 || strcmp (type, CHECK_HA_SERVER) == 0);
assert (name_buffer != NULL);
*name_buffer = NULL;
make_exec_abspath (cmd, PATH_MAX, (char *) UTIL_COMMDB_NAME " " COMMDB_ALL_STATUS);
input = popen (cmd, "r");
if (input == NULL)
{
return;
}
int offset = 0;
/* *INDENT-OFF* */
std::string delimiter = " ";
std::string result;
/* *INDENT-ON* */
while (fgets (buf, 4096, input) != NULL)
{
/* *INDENT-OFF* */
std::string s (buf);
/*
* ignore HA-applylogdb and HA-copylogdb
* check Server and HA-Server
*/
std::string::size_type server_pos = s.find (type);
if (server_pos == std::string::npos)
{
continue;
}
/* find Server */
std::string::size_type start = s.find (delimiter, 1) + 1;
std::string::size_type end = s.find (delimiter, start);
std::string server_name = s.substr (start, end - start);
result.append (server_name);
result.append (",");
/* *INDENT-ON* */
}
/* allocate buffer, it should be freed */
if (!result.empty ())
{
int name_length = result.size ();
*name_buffer = (char *) malloc (name_length + 1);
if (*name_buffer)
{
strncpy (*name_buffer, result.c_str (), name_length);
(*name_buffer)[name_length] = '\0';
}
}
pclose (input);
}
/*
* check_server -
*
* return:
*
* type(in):
* server_name(in):
*/
static bool
check_server (const char *type, const char *server_name)
{
FILE *input;
char buf[4096], *token, *save_ptr, *delim = (char *) " ";
char cmd[PATH_MAX];
make_exec_abspath (cmd, PATH_MAX, (char *) UTIL_COMMDB_NAME " " COMMDB_ALL_STATUS);
input = popen (cmd, "r");
if (input == NULL)
{
return false;
}
while (fgets (buf, 4096, input) != NULL)
{
token = strtok_r (buf, delim, &save_ptr);
if (token == NULL)
{
continue;
}
if (strcmp (type, CHECK_SERVER) == 0)
{
if (strcmp (token, CHECK_SERVER) != 0 && strcmp (token, CHECK_HA_SERVER) != 0)
{
continue;
}
}
else
{
if (strcmp (token, type) != 0)
{
continue;
}
}
token = strtok_r (NULL, delim, &save_ptr);
if (token != NULL && strcmp (token, server_name) == 0)
{
pclose (input);
return true;
}
}
pclose (input);
return false;
}
/*
* is_server_running -
*
* return:
*
* type(in):
* server_name(in):
* pid(in):
*/
static bool
is_server_running (const char *type, const char *server_name, int pid)
{
if (!__gv_cvar.css_does_master_exist (prm_get_master_port_id ()))
{
return false;
}
if (pid <= 0)
{
return check_server (type, server_name);
}
while (true)
{
if (!is_terminated_process (pid))
{
if (check_server (type, server_name))
{
return true;
}
sleep (1);
/* A child process is defunct because the SIGCHLD signal ignores. */
/*
* if (waitpid (pid, &status, WNOHANG) == -1) { perror ("waitpid"); } */
}
else
{
return false;
}
}
}
/*
* shutdown_reviving_server -
*
* return:
*
* type(in):
* server_name(in):
* pid(in):
*/
static int
shutdown_reviving_server (const char *server_name)
{
const char *args[] = { UTIL_COMMDB_NAME, COMMDB_SHUTDOWN_REVIVING_SERVER, server_name, NULL };
return proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
}
/*
* process_server -
*
* return:
*
* command_type(in):
* argc(in):
* argv(in) :
* show_usage(in):
*
* NOTE:
*/
static int
process_server (int command_type, int argc, char **argv, bool show_usage, bool check_ha_mode,
bool process_window_service)
{
char buf[4096];
char *list, *token, *save;
const char *delim = " ,:";
int status = NO_ERROR;
int master_port = prm_get_master_port_id ();
memset (buf, '\0', sizeof (buf));
/* A string is copyed because strtok_r() modify an original string. */
if (argc == 0)
{
if (us_Property_map[SERVER_START_LIST].property_value != NULL)
{
strncpy (buf, us_Property_map[SERVER_START_LIST].property_value, sizeof (buf) - 1);
}
}
else
{
strncpy (buf, argv[0], sizeof (buf) - 1);
}
if (command_type != STATUS && strlen (buf) == 0)
{
if (show_usage)
{
util_service_usage (SERVER);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
}
return ER_GENERIC_ERROR;
}
switch (command_type)
{
case START:
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_SERVER,
COMMAND_TYPE_START, NULL, NULL
};
for (list = buf;; list = NULL)
{
token = strtok_r (list, delim, &save);
if (token == NULL)
{
break;
}
args[3] = token;
/* load parameters for [@database] section */
if (check_ha_mode == true)
{
status = sysprm_load_and_init (token, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
print_result (PRINT_SERVER_NAME, status, command_type);
break;
}
if (util_get_ha_mode_for_sa_utils () != HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE);
print_result (PRINT_SERVER_NAME, status, command_type);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE);
continue;
}
}
if (is_server_running (CHECK_SERVER, token, 0))
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, token);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, token);
continue;
}
else
{
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
if (status == NO_ERROR && !is_server_running (CHECK_SERVER, token, 0))
{
status = ER_GENERIC_ERROR;
}
print_result (PRINT_SERVER_NAME, status, command_type);
}
}
#endif
}
else
{
if (!__gv_cvar.css_does_master_exist (master_port))
{
status = process_master (command_type);
if (status != NO_ERROR)
{
break; /* escape switch */
}
}
for (list = buf;; list = NULL)
{
token = strtok_r (list, delim, &save);
if (token == NULL)
{
break;
}
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_3S, PRINT_SERVER_NAME, PRINT_CMD_START, token);
#if !defined(WINDOWS)
if (check_ha_mode == true)
{
status = sysprm_load_and_init (token, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
print_result (PRINT_SERVER_NAME, status, command_type);
break;
}
if (util_get_ha_mode_for_sa_utils () != HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE);
print_result (PRINT_SERVER_NAME, status, command_type);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE);
continue;
}
}
#endif /* !WINDOWS */
if (is_server_running (CHECK_SERVER, token, 0))
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, token);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, token);
continue;
}
else
{
int pid;
const char *args[] = { UTIL_CUBRID_NAME, token, NULL };
status = proc_execute (UTIL_CUBRID_NAME, args, false, false, false, &pid);
if (status == NO_ERROR && !is_server_running (CHECK_SERVER, token, pid))
{
status = ER_GENERIC_ERROR;
}
print_result (PRINT_SERVER_NAME, status, command_type);
}
}
}
break;
case STOP:
for (list = buf;; list = NULL)
{
token = strtok_r (list, delim, &save);
if (token == NULL)
{
break;
}
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_3S, PRINT_SERVER_NAME, PRINT_CMD_STOP, token);
if (is_server_running (CHECK_SERVER, token, 0))
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_SERVER,
COMMAND_TYPE_STOP, NULL, NULL
};
args[3] = token;
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_COMMDB_NAME, COMMDB_SERVER_STOP, token, NULL };
#if !defined(WINDOWS)
if (check_ha_mode)
{
status = sysprm_load_and_init (token, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
print_result (PRINT_SERVER_NAME, status, command_type);
break;
}
if (util_get_ha_mode_for_sa_utils () != HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE);
print_result (PRINT_SERVER_NAME, status, command_type);
continue;
}
}
#endif /* !WINDOWS */
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
}
print_result (PRINT_SERVER_NAME, status, command_type);
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, token);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, token);
shutdown_reviving_server (token);
}
}
break;
case RESTART:
status = process_server (STOP, argc, argv, show_usage, check_ha_mode, process_window_service);
status = process_server (START, argc, argv, show_usage, check_ha_mode, process_window_service);
break;
case STATUS:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_SERVER_NAME, PRINT_CMD_STATUS);
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = { UTIL_COMMDB_NAME, COMMDB_SERVER_STATUS, NULL };
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
break;
case ACCESS_CONTROL:
{
if (argc != 2)
{
status = ER_GENERIC_ERROR;
if (show_usage)
{
util_service_usage (SERVER);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
}
break;
}
if (strcasecmp (argv[0], "reload") == 0)
{
const char *args[] = { UTIL_ADMIN_NAME, UTIL_OPTION_ACLDB, ACLDB_RELOAD, argv[1],
NULL
};
status = proc_execute (UTIL_ADMIN_NAME, args, true, false, false, NULL);
print_result (PRINT_SERVER_NAME, status, command_type);
}
else if (strcasecmp (argv[0], "status") == 0)
{
const char *args[] = { UTIL_ADMIN_NAME, UTIL_OPTION_ACLDB, argv[1], NULL };
status = proc_execute (UTIL_ADMIN_NAME, args, true, false, false, NULL);
}
else
{
status = ER_GENERIC_ERROR;
if (show_usage)
{
util_service_usage (SERVER);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
}
break;
}
}
break;
default:
status = ER_GENERIC_ERROR;
break;
}
return status;
}
/*
* is_broker_running -
*
* return:
*
*/
static int
is_broker_running (void)
{
const char *args[] = { UTIL_MONITOR_NAME, 0 };
int status = proc_execute (UTIL_MONITOR_NAME, args, true, true, false, NULL);
return status;
}
/*
* process_broker -
*
* return:
*
* command_type(in):
* name(in):
*
*/
static int
process_broker (int command_type, int argc, const char **argv, bool process_window_service)
{
int status = NO_ERROR;
switch (command_type)
{
case START:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_BROKER_NAME, PRINT_CMD_START);
switch (is_broker_running ())
{
case 0: /* no error */
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_BROKER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_BROKER_NAME);
break;
case 1: /* shm_open error */
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_BROKER,
COMMAND_TYPE_START, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = (is_broker_running () == 0) ? NO_ERROR : ER_GENERIC_ERROR;
#endif
}
else
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_START, NULL };
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
status = (is_broker_running () == 0) ? NO_ERROR : ER_GENERIC_ERROR;
}
print_result (PRINT_BROKER_NAME, status, command_type);
break;
case 2: /* no conf file or parameter error */
default:
status = ER_GENERIC_ERROR;
print_result (PRINT_BROKER_NAME, ER_GENERIC_ERROR, command_type);
break;
}
break;
case STOP:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_BROKER_NAME, PRINT_CMD_STOP);
switch (is_broker_running ())
{
case 0: /* no error */
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_BROKER,
COMMAND_TYPE_STOP, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = (is_broker_running () == 0) ? ER_GENERIC_ERROR : NO_ERROR;
#endif
}
else
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_STOP, NULL };
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
status = (is_broker_running () == 0) ? ER_GENERIC_ERROR : NO_ERROR;
}
print_result (PRINT_BROKER_NAME, status, command_type);
break;
case 1: /* shm_open error */
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
break;
case 2: /* no conf file or parameter error */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_BROKER_NAME, ER_GENERIC_ERROR, command_type);
break;
}
break;
case RESTART:
status = process_broker (STOP, 0, NULL, process_window_service);
#if defined (WINDOWS)
Sleep (500);
#endif
status = process_broker (START, 0, NULL, process_window_service);
break;
case STATUS:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_BROKER_NAME, PRINT_CMD_STATUS);
switch (is_broker_running ())
{
case 0: /* no error */
args = (const char **) malloc (sizeof (char *) * (argc + 2));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = PRINT_BROKER_NAME " " PRINT_CMD_STATUS;
for (i = 0; i < argc; i++)
{
args[i + 1] = argv[i];
}
args[argc + 1] = NULL;
status = proc_execute (UTIL_MONITOR_NAME, args, true, false, false, NULL);
free (args);
break;
case 1: /* shm_open error */
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
break;
case 2: /* no conf file */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_BROKER_NAME, ER_GENERIC_ERROR, command_type);
break;
}
}
break;
case ON:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_BROKER,
COMMAND_TYPE_ON, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_ON, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
}
}
break;
case OFF:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_BROKER,
COMMAND_TYPE_OFF, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_OFF, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
}
}
break;
case ACCESS_CONTROL:
{
const char *args[5];
args[0] = UTIL_BROKER_NAME;
args[1] = COMMAND_TYPE_ACL;
args[2] = argv[0];
if (argc == 1)
{
args[3] = NULL;
}
else if (argc == 2)
{
args[3] = argv[1];
args[4] = NULL;
}
else
{
status = ER_GENERIC_ERROR;
util_service_usage (BROKER);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
break;
}
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
print_result (PRINT_BROKER_NAME, status, command_type);
break;
}
case RESET:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_BROKER,
COMMAND_TYPE_RESET, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_RESET, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
}
}
break;
case INFO:
{
const char *args[] = { UTIL_BROKER_NAME, COMMAND_TYPE_INFO, NULL };
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
}
break;
case GET_SHARID:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_BROKER_NAME, PRINT_CMD_GETID);
if (is_broker_running ())
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
status = ER_GENERIC_ERROR;
break;
}
args = (const char **) malloc (sizeof (char *) * (argc + 3));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = UTIL_BROKER_NAME;
args[1] = PRINT_CMD_GETID;
for (i = 0; i < argc; i++)
{
args[i + 2] = argv[i];
}
args[argc + 2] = NULL;
status = proc_execute (UTIL_BROKER_NAME, args, true, false, false, NULL);
free (args);
}
break;
case TEST:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_BROKER_NAME, PRINT_CMD_TEST);
switch (is_broker_running ())
{
case 0: /* no error */
args = (const char **) malloc (sizeof (char *) * (argc + 2));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = PRINT_BROKER_NAME " " PRINT_CMD_TEST;
for (i = 0; i < argc; i++)
{
args[i + 1] = argv[i];
}
args[argc + 1] = NULL;
status = proc_execute (UTIL_TESTER_NAME, args, true, false, false, NULL);
free (args);
break;
case 1: /* shm_open error */
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_BROKER_NAME);
break;
case 2: /* no conf file */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_BROKER_NAME, ER_GENERIC_ERROR, command_type);
break;
}
}
break;
default:
status = ER_GENERIC_ERROR;
break;
}
return status;
}
/*
* is_gateway_running -
*
* return:
*
*/
static int
is_gateway_running (void)
{
const char *args[] = { UTIL_GATEWAY_MONITOR_NAME, 0 };
int status = proc_execute (UTIL_GATEWAY_MONITOR_NAME, args, true, true, false, NULL);
return status;
}
/*
* process_gateway -
*
* return:
*
* command_type(in):
* name(in):
*
*/
static int
process_gateway (int command_type, int argc, const char **argv, bool process_window_service)
{
int status = NO_ERROR;
switch (command_type)
{
case START:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_GATEWAY_NAME, PRINT_CMD_START);
switch (is_gateway_running ())
{
case 0: /* no error */
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_GATEWAY_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_GATEWAY_NAME);
break;
case 1: /* shm_open error */
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_GATEWAY,
COMMAND_TYPE_START, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = (is_gateway_running () == 0) ? NO_ERROR : ER_GENERIC_ERROR;
#endif
}
else
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_START, NULL };
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
status = (is_gateway_running () == 0) ? NO_ERROR : ER_GENERIC_ERROR;
}
print_result (PRINT_GATEWAY_NAME, status, command_type);
break;
case 2: /* no conf file or parameter error */
default:
status = ER_GENERIC_ERROR;
print_result (PRINT_GATEWAY_NAME, ER_GENERIC_ERROR, command_type);
break;
}
break;
case STOP:
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_GATEWAY_NAME, PRINT_CMD_STOP);
switch (is_gateway_running ())
{
case 0: /* no error */
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_GATEWAY,
COMMAND_TYPE_STOP, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
status = (is_gateway_running () == 0) ? ER_GENERIC_ERROR : NO_ERROR;
#endif
}
else
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_STOP, NULL };
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
status = (is_gateway_running () == 0) ? ER_GENERIC_ERROR : NO_ERROR;
}
print_result (PRINT_GATEWAY_NAME, status, command_type);
break;
case 1: /* shm_open error */
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
break;
case 2: /* no conf file or parameter error */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_GATEWAY_NAME, ER_GENERIC_ERROR, command_type);
break;
}
break;
case RESTART:
status = process_gateway (STOP, 0, NULL, process_window_service);
#if defined (WINDOWS)
Sleep (500);
#endif
status = process_gateway (START, 0, NULL, process_window_service);
break;
case STATUS:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_GATEWAY_NAME, PRINT_CMD_STATUS);
switch (is_gateway_running ())
{
case 0: /* no error */
args = (const char **) malloc (sizeof (char *) * (argc + 2));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = PRINT_GATEWAY_NAME " " PRINT_CMD_STATUS;
for (i = 0; i < argc; i++)
{
args[i + 1] = argv[i];
}
args[argc + 1] = NULL;
status = proc_execute (UTIL_GATEWAY_MONITOR_NAME, args, true, false, false, NULL);
free (args);
break;
case 1: /* shm_open error */
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
break;
case 2: /* no conf file */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_GATEWAY_NAME, ER_GENERIC_ERROR, command_type);
break;
}
}
break;
case ON:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_GATEWAY,
COMMAND_TYPE_ON, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_ON, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
}
}
break;
case OFF:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_GATEWAY,
COMMAND_TYPE_OFF, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_OFF, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
}
}
break;
case ACCESS_CONTROL:
{
const char *args[5];
args[0] = UTIL_GATEWAY_NAME;
args[1] = COMMAND_TYPE_ACL;
args[2] = argv[0];
if (argc == 1)
{
args[3] = NULL;
}
else if (argc == 2)
{
args[3] = argv[1];
args[4] = NULL;
}
else
{
status = ER_GENERIC_ERROR;
util_service_usage (GATEWAY);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
break;
}
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
print_result (PRINT_GATEWAY_NAME, status, command_type);
break;
}
case RESET:
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_GATEWAY,
COMMAND_TYPE_RESET, argv[0], NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_RESET, argv[0], NULL };
if (argc <= 0)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
break;
}
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
}
}
break;
case INFO:
{
const char *args[] = { UTIL_GATEWAY_NAME, COMMAND_TYPE_INFO, NULL };
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
}
break;
case GET_SHARID:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_GATEWAY_NAME, PRINT_CMD_GETID);
if (is_gateway_running ())
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
status = ER_GENERIC_ERROR;
break;
}
args = (const char **) malloc (sizeof (char *) * (argc + 3));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = UTIL_GATEWAY_NAME;
args[1] = PRINT_CMD_GETID;
for (i = 0; i < argc; i++)
{
args[i + 2] = argv[i];
}
args[argc + 2] = NULL;
status = proc_execute (UTIL_GATEWAY_NAME, args, true, false, false, NULL);
free (args);
}
break;
case TEST:
{
int i;
const char **args;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_GATEWAY_NAME, PRINT_CMD_TEST);
switch (is_gateway_running ())
{
case 0: /* no error */
args = (const char **) malloc (sizeof (char *) * (argc + 2));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
break;
}
args[0] = PRINT_GATEWAY_NAME " " PRINT_CMD_TEST;
for (i = 0; i < argc; i++)
{
args[i + 1] = argv[i];
}
args[argc + 1] = NULL;
status = proc_execute (UTIL_TESTER_NAME, args, true, false, false, NULL);
free (args);
break;
case 1: /* shm_open error */
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_GATEWAY_NAME);
break;
case 2: /* no conf file */
default: /* other error */
status = ER_GENERIC_ERROR;
print_result (PRINT_GATEWAY_NAME, ER_GENERIC_ERROR, command_type);
break;
}
}
break;
default:
status = ER_GENERIC_ERROR;
break;
}
return status;
}
static UTIL_MANAGER_SERVER_STATUS_E
is_manager_running (unsigned int sleep_time)
{
FILE *input;
char buf[16], cmd[PATH_MAX];
struct stat stbuf;
sleep (sleep_time);
/* check cub_manager */
(void) envvar_bindir_file (cmd, PATH_MAX, UTIL_CUB_MANAGER_NAME);
if (stat (cmd, &stbuf) == -1)
{
/* Not install manager server */
return MANAGER_SERVER_STATUS_ERROR;
}
strcat (cmd, " getpid");
input = popen (cmd, "r");
if (input == NULL)
{
/* Failed to run cub_manager process */
return MANAGER_SERVER_STATUS_ERROR;
}
memset (buf, '\0', sizeof (buf));
if (fgets (buf, 16, input) == NULL)
{
pclose (input);
return MANAGER_SERVER_STOPPED;
}
if (atoi (buf) > 0)
{
pclose (input);
return MANAGER_SERVER_RUNNING;
}
else
{
pclose (input);
return MANAGER_SERVER_STATUS_ERROR;
}
}
/*
* process_manager -
*
* return:
*
* command_type(in):
* cms_port(in):
*
*/
static int
process_manager (int command_type, bool process_window_service)
{
int cub_manager, status = NO_ERROR;
char cub_manager_path[PATH_MAX];
UTIL_MANAGER_SERVER_STATUS_E manager_status;
struct stat stbuf;
cub_manager_path[0] = '\0';
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_MANAGER_NAME, command_string (command_type));
(void) envvar_bindir_file (cub_manager_path, PATH_MAX, UTIL_CUB_MANAGER_NAME);
if (stat (cub_manager_path, &stbuf) == -1)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_MANAGER_NOT_INSTALLED);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MANAGER_NOT_INSTALLED);
return ER_GENERIC_ERROR;
}
manager_status = is_manager_running (0);
if (manager_status == MANAGER_SERVER_STATUS_ERROR)
{
status = ER_GENERIC_ERROR;
print_result (PRINT_MANAGER_NAME, status, command_type);
return status;
}
switch (command_type)
{
case START:
if (manager_status == MANAGER_SERVER_STOPPED)
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_MANAGER,
COMMAND_TYPE_START, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_CUB_MANAGER_NAME, COMMAND_TYPE_START, NULL };
cub_manager = proc_execute (UTIL_CUB_MANAGER_NAME, args, false, false, false, NULL);
}
status = (is_manager_running (1) == MANAGER_SERVER_RUNNING) ? NO_ERROR : ER_GENERIC_ERROR;
print_result (PRINT_MANAGER_NAME, status, command_type);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MANAGER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MANAGER_NAME);
status = ER_GENERIC_ERROR;
}
break;
case STOP:
if (manager_status == MANAGER_SERVER_RUNNING)
{
if (process_window_service)
{
#if defined(WINDOWS)
const char *args[] = { UTIL_WIN_SERVICE_CONTROLLER_NAME, PRINT_CMD_MANAGER,
COMMAND_TYPE_STOP, NULL
};
status = proc_execute (UTIL_WIN_SERVICE_CONTROLLER_NAME, args, true, false, false, NULL);
#endif
}
else
{
const char *args[] = { UTIL_CUB_MANAGER_NAME, COMMAND_TYPE_STOP, NULL };
status = proc_execute (UTIL_CUB_MANAGER_NAME, args, true, false, false, NULL);
}
status = (is_manager_running (1) == MANAGER_SERVER_STOPPED) ? NO_ERROR : ER_GENERIC_ERROR;
print_result (PRINT_MANAGER_NAME, status, command_type);
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MANAGER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MANAGER_NAME);
status = ER_GENERIC_ERROR;
}
break;
case STATUS:
{
switch (manager_status)
{
case MANAGER_SERVER_RUNNING:
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_1S, PRINT_MANAGER_NAME);
break;
case MANAGER_SERVER_STOPPED:
default:
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MANAGER_NAME);
break;
}
}
break;
default:
status = ER_GENERIC_ERROR;
break;
}
return status;
}
/*
* is_pl_running -
*
* return:
*
*/
static UTIL_PL_SERVER_STATUS_E
is_pl_running (const char *server_name)
{
static const char PING_CMD[] = " ping ";
static const int PING_CMD_LEN = sizeof (PING_CMD);
FILE *input = NULL;
char buf[PATH_MAX] = { 0 };
char cmd[PATH_MAX] = { 0 };
(void) envvar_bindir_file (cmd, PATH_MAX, UTIL_PL_NAME);
strcat (cmd, PING_CMD);
strcat (cmd, server_name);
input = popen (cmd, "r");
if (input == NULL)
{
return PL_SERVER_STATUS_ERROR;
}
memset (buf, '\0', sizeof (buf));
if (fgets (buf, PATH_MAX, input) == NULL)
{
pclose (input);
return PL_SERVER_STATUS_ERROR;
}
if (strcmp (buf, server_name) == 0)
{
pclose (input);
return PL_SERVER_RUNNING;
}
else if (strcmp (buf, "NO_PROCESS") == 0)
{
pclose (input);
return PL_SERVER_STOPPED;
}
else if (strcmp (buf, "NO_CONNECTION") == 0)
{
pclose (input);
return PL_SERVER_STARTING;
}
else
{
pclose (input);
return PL_SERVER_STATUS_ERROR;
}
}
#define WAIT_TIMEOUT_CUB_PL (10)
static int
process_pl_restart (const char *db_name, bool suppress_message)
{
int status = NO_ERROR;
int waited_secs = 0;
if (!suppress_message)
{
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_3S, PRINT_PL_NAME, PRINT_CMD_RESTART, db_name);
}
if (!is_server_running (CHECK_SERVER, db_name, 0))
{
status = ER_GENERIC_ERROR;
if (!suppress_message)
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, db_name);
}
}
status = sysprm_reload_and_init (db_name, NULL);
const bool is_sp_on = prm_get_bool_value (PRM_ID_STORED_PROCEDURE);
if (is_sp_on == false)
{
status = ER_GENERIC_ERROR;
}
if (status == NO_ERROR)
{
PL_SERVER_INFO pl_old = PL_SERVER_INFO_INITIALIZER;
PL_SERVER_INFO pl_new = PL_SERVER_INFO_INITIALIZER;
pl_read_info (db_name, pl_old);
pl_new.pid = pl_old.pid;
const char *args[] = { UTIL_PL_NAME, COMMAND_TYPE_STOP, db_name, NULL };
status = proc_execute (UTIL_PL_NAME, args, true, false, false, NULL);
/* We don't start cub_pl directly here.
* We just request a shutdown, and it will be restarted by cub_server.
*/
UTIL_PL_SERVER_STATUS_E pl_status;
do
{
// The pl server needs a few seconds to accept ping request
sleep (1);
if (pl_old.pid == pl_new.pid)
{
pl_read_info (db_name, pl_new);
}
else
{
pl_status = is_pl_running (db_name);
status = (pl_status == PL_SERVER_RUNNING) ? NO_ERROR : ER_GENERIC_ERROR;
if (!is_server_running (CHECK_SERVER, db_name, 0))
{
status = ER_GENERIC_ERROR;
if (!suppress_message)
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, db_name);
}
break;
}
}
waited_secs++;
}
while (status != NO_ERROR && waited_secs < WAIT_TIMEOUT_CUB_PL);
}
if (!suppress_message)
{
print_result (PRINT_PL_NAME, status, RESTART);
}
return status;
}
static int
process_pl_status (const char *db_name)
{
int status = NO_ERROR;
int waited_secs = 0;
UTIL_PL_SERVER_STATUS_E pl_status;
status = sysprm_reload_and_init (db_name, NULL);
const bool is_sp_on = prm_get_bool_value (PRM_ID_STORED_PROCEDURE);
do
{
if (!is_server_running (CHECK_SERVER, db_name, 0))
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, db_name);
return status;
}
if (is_sp_on == false)
{
status = ER_GENERIC_ERROR;
break;
}
pl_status = is_pl_running (db_name);
if (pl_status == PL_SERVER_RUNNING)
{
const char *args[] = { UTIL_PL_NAME, COMMAND_TYPE_STATUS, db_name, NULL };
status = proc_execute (UTIL_PL_NAME, args, true, false, false, NULL);
if (status == NO_ERROR)
{
break;
}
}
else
{
status = ER_GENERIC_ERROR;
}
// retry
sleep (1);
waited_secs++;
}
while (status != NO_ERROR && waited_secs < WAIT_TIMEOUT_CUB_PL);
if (status != NO_ERROR)
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_PL_NAME, db_name);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_PL_NAME, db_name);
}
return status;
}
static int
process_pl (int command_type, int argc, const char **argv, bool show_usage, bool suppress_message,
bool process_window_service, bool ha_mode)
{
const int buf_size = 4096;
char *buf = NULL;
char *list = NULL, *save = NULL;
const char *delim = " ,:";
int status = NO_ERROR;
char *db_name = NULL;
int master_port = prm_get_master_port_id ();
if (argc == 0) /* cubrid service command */
{
/* get all server names from master request */
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *server_type = (ha_mode) ? CHECK_HA_SERVER : CHECK_SERVER;
get_server_names (server_type, &buf);
}
}
else /* cubrid pl command */
{
buf = (char *) calloc (sizeof (char), buf_size);
strncpy (buf, argv[0], buf_size);
}
if (command_type != STATUS && buf == NULL)
{
if (show_usage)
{
util_service_usage (PL_UTIL);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_CMD);
}
status = ER_GENERIC_ERROR;
goto exit;
}
if (command_type == STATUS && !suppress_message)
{
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_PL_NAME, PRINT_CMD_STATUS);
}
list = buf;
while (buf)
{
db_name = strtok_r (list, delim, &save);
if (db_name == NULL)
{
break;
}
switch (command_type)
{
case START:
if (!suppress_message)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_INVALID_CMD, PRINT_CMD_START);
}
break;
case STOP:
if (!suppress_message)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_INVALID_CMD, PRINT_CMD_STOP);
}
break;
case RESTART:
status = process_pl_restart (db_name, suppress_message);
break;
case STATUS:
status = process_pl_status (db_name);
break;
default:
status = ER_GENERIC_ERROR;
break;
}
list = NULL;
}
exit:
if (buf)
{
free (buf);
}
return status;
}
static bool
ha_make_log_path (char *path, int size, char *base, char *db, char *node)
{
return snprintf (path, size, "%s/%s_%s", base, db, node) >= 0;
}
static bool
ha_concat_db_and_host (char *db_host, int size, const char *db, const char *host)
{
return snprintf (db_host, size, "%s@%s", db, host) >= 0;
}
#if defined(WINDOWS)
static bool
ha_mkdir (const char *path, int dummy)
{
return false;
}
#else
static bool
ha_mkdir (const char *path, mode_t mode)
{
char dir[PATH_MAX];
struct stat statbuf;
if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
{
return true;
}
cub_dirname_r (path, dir, PATH_MAX);
if (stat (dir, &statbuf) == -1)
{
if (errno == ENOENT && ha_mkdir (dir, mode))
{
return mkdir (path, mode) == 0;
}
else
{
return false;
}
}
else if (S_ISDIR (statbuf.st_mode))
{
return mkdir (path, mode) == 0;
}
return false;
}
#endif /* WINDOWS */
static bool
ha_make_mem_size (char *mem_size, int size, int value)
{
return snprintf (mem_size, size, "--max-mem-size=%d", value) >= 0;
}
static bool
ha_is_registered (const char *args, const char *hostname)
{
int status;
const char *commdb_argv[] = {
UTIL_COMMDB_NAME, /* argv[0] */
COMMDB_IS_REG, /* argv[1] */
args, /* argv[2] : process args */
NULL, NULL, /* argv[3~4] : -h hostname */
NULL /* argv[5] */
};
if (args == NULL)
{
return false;
}
if (hostname)
{
commdb_argv[3] = COMMDB_HOST; /* -h */
commdb_argv[4] = hostname; /* hostname */
commdb_argv[5] = NULL;
}
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, NULL);
if (status == NO_ERROR)
{
return true;
}
return false;
}
static int
ha_argv_to_args (char *args, int size, const char **argv, HB_PROC_TYPE type)
{
int status = NO_ERROR;
int ret = 0;
if (type == HB_PTYPE_COPYLOGDB)
{
ret = snprintf (args, size, "%s %s %s %s %s %s %s ", /* copylogdb */
argv[0], /* UTIL_ADMIN_NAME : cub_admin */
argv[1], /* UTIL_COPYLOGDB : copylogdb */
argv[2], /* -L, --log-path=PATH */
argv[3], /* PATH */
argv[4], /* -m, --mode=MODE */
argv[5], /* MODE */
argv[6]); /* database-name */
}
else if (type == HB_PTYPE_APPLYLOGDB)
{
ret = snprintf (args, size, "%s %s %s %s %s %s ", /* applylogdb */
argv[0], /* UTIL_ADMIN_NAME : cub_admin */
argv[1], /* UTIL_APPLYLOGDB : applylogdb */
argv[2], /* -L, --log-path=PATH */
argv[3], /* PATH */
argv[4], /* --max-mem-size=SIZE */
argv[5]); /* database-name */
}
else
{
assert (false);
status = ER_GENERIC_ERROR;
}
if (ret < 0)
{
assert (false);
status = ER_GENERIC_ERROR;
}
return status;
}
#if !defined(WINDOWS)
static int
us_hb_copylogdb_start (dynamic_array * out_ap, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host)
{
int status = NO_ERROR;
int pid;
int i, j, num_nodes;
int num_db_found = 0, num_node_found = 0;
HA_NODE_CONF *nc;
char db_host[PATH_MAX], log_path[PATH_MAX];
char **dbs;
num_nodes = ha_conf->num_node_conf;
dbs = ha_conf->db_names;
nc = ha_conf->node_conf;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, UTIL_COPYLOGDB, PRINT_CMD_START);
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (dbs[i], db_name) != 0)
{
continue;
}
num_db_found++;
prm_set_integer_value (PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY, HA_MODE_FAIL_BACK);
status = sysprm_load_and_init (dbs[i], NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
goto ret;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
continue;
}
for (j = 0; j < num_nodes; j++)
{
if (node_name != NULL && strcmp (nc[j].node_name, node_name) != 0)
{
continue;
}
if (remote_host == NULL)
{
if (util_is_localhost (nc[j].node_name))
{
continue;
}
}
else
{
if (node_name != NULL && strcmp (node_name, remote_host) == 0)
{
continue;
}
}
num_node_found++;
db_host[0] = log_path[0] = '\0';
(void) ha_concat_db_and_host (db_host, PATH_MAX, dbs[i], nc[j].node_name);
(void) ha_make_log_path (log_path, PATH_MAX, nc[j].copy_log_base, dbs[i], nc[j].node_name);
if (db_host[0] != '\0' && log_path[0] != '\0')
{
char lw_args[HB_MAX_SZ_PROC_ARGS];
const char *lw_argv[] = { UTIL_ADMIN_NAME, UTIL_COPYLOGDB,
"-L", log_path,
"-m", nc[j].copy_sync_mode,
db_host,
NULL
};
status = ha_argv_to_args (lw_args, sizeof (lw_args), lw_argv, HB_PTYPE_COPYLOGDB);
if (status != NO_ERROR)
{
goto ret;
}
if (remote_host == NULL)
{
if (ha_is_registered (lw_args, NULL))
{
continue;
}
if (ha_mkdir (log_path, 0755))
{
status = proc_execute (UTIL_ADMIN_NAME, lw_argv, false, false, false, &pid);
if (status != NO_ERROR)
{
goto ret;
}
if (out_ap && da_add (out_ap, &pid) != NO_ERROR)
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
else
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
else
{
const char *commdb_argv[] = {
UTIL_COMMDB_NAME,
COMMDB_HA_START_UTIL_PROCESS, lw_args,
COMMDB_HOST, remote_host,
NULL,
};
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, &pid);
if (status != NO_ERROR)
{
goto ret;
}
if (out_ap && (da_add (out_ap, lw_args) != NO_ERROR))
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
}
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
goto ret;
}
if (node_name != NULL && num_node_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
status = ER_GENERIC_ERROR;
}
ret:
print_result (UTIL_COPYLOGDB, status, START);
return status;
}
static int
us_hb_copylogdb_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name, const char *remote_host)
{
int status = NO_ERROR;
int i, j, num_nodes;
int num_db_found = 0, num_node_found = 0;
HA_NODE_CONF *nc;
char db_host[PATH_MAX], log_path[PATH_MAX];
char **dbs;
int wait_time = 0;
num_nodes = ha_conf->num_node_conf;
dbs = ha_conf->db_names;
nc = ha_conf->node_conf;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, UTIL_COPYLOGDB, PRINT_CMD_STOP);
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (dbs[i], db_name) != 0)
{
continue;
}
num_db_found++;
for (j = 0; j < num_nodes; j++)
{
if (node_name != NULL && strcmp (nc[j].node_name, node_name) != 0)
{
continue;
}
if (remote_host == NULL)
{
if (util_is_localhost (nc[j].node_name))
{
continue;
}
}
else
{
if (node_name != NULL && strcmp (node_name, remote_host) == 0)
{
continue;
}
}
num_node_found++;
db_host[0] = log_path[0] = '\0';
(void) ha_concat_db_and_host (db_host, PATH_MAX, dbs[i], nc[j].node_name);
(void) ha_make_log_path (log_path, PATH_MAX, nc[j].copy_log_base, dbs[i], nc[j].node_name);
if (db_host[0] != '\0' && log_path[0] != '\0')
{
char lw_args[HB_MAX_SZ_PROC_ARGS];
const char *lw_argv[] = {
UTIL_ADMIN_NAME, UTIL_COPYLOGDB,
"-L", log_path,
"-m", nc[j].copy_sync_mode, db_host, NULL
};
status = ha_argv_to_args (lw_args, sizeof (lw_args), lw_argv, HB_PTYPE_COPYLOGDB);
if (status != NO_ERROR)
{
goto ret;
}
if (remote_host != NULL || ha_is_registered (lw_args, remote_host))
{
const char *commdb_argv[HB_MAX_SZ_PROC_ARGS] = {
UTIL_COMMDB_NAME, COMMDB_HA_DEREG_BY_ARGS, lw_args,
NULL, NULL, /* -h hostname */
NULL
};
if (remote_host != NULL)
{
commdb_argv[3] = COMMDB_HOST; /* -h */
commdb_argv[4] = remote_host; /* hostname */
commdb_argv[5] = NULL;
}
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, NULL);
if (remote_host != NULL && status != NO_ERROR)
{
goto ret;
}
wait_time = 0;
do
{
if (ha_is_registered (lw_args, remote_host) == false)
{
status = NO_ERROR;
break;
}
sleep (3);
wait_time += 3;
}
while (wait_time < US_HB_DEREG_WAIT_TIME_IN_SEC);
}
}
else
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
goto ret;
}
if (node_name != NULL && num_node_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
status = ER_GENERIC_ERROR;
}
ret:
print_result (UTIL_COPYLOGDB, status, STOP);
return status;
}
static int
us_hb_applylogdb_start (dynamic_array * out_ap, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host)
{
int status = NO_ERROR;
int pid;
int i, j, num_nodes;
int num_db_found = 0, num_node_found = 0;
HA_NODE_CONF *nc;
char log_path[PATH_MAX], db_host[PATH_MAX], mem_size[PATH_MAX];
char **dbs;
num_nodes = ha_conf->num_node_conf;
dbs = ha_conf->db_names;
nc = ha_conf->node_conf;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, UTIL_APPLYLOGDB, PRINT_CMD_START);
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (dbs[i], db_name) != 0)
{
continue;
}
num_db_found++;
prm_set_integer_value (PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY, HA_MODE_FAIL_BACK);
status = sysprm_load_and_init (dbs[i], NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
goto ret;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
continue;
}
for (j = 0; j < num_nodes; j++)
{
if (node_name != NULL && strcmp (nc[j].node_name, node_name) != 0)
{
continue;
}
if (remote_host == NULL)
{
if (util_is_localhost (nc[j].node_name))
{
continue;
}
}
else
{
if (node_name != NULL && strcmp (node_name, remote_host) == 0)
{
continue;
}
}
num_node_found++;
log_path[0] = db_host[0] = mem_size[0] = '\0';
(void) ha_concat_db_and_host (db_host, PATH_MAX, dbs[i], "localhost");
(void) ha_make_log_path (log_path, PATH_MAX, nc[j].copy_log_base, dbs[i], nc[j].node_name);
(void) ha_make_mem_size (mem_size, PATH_MAX, nc[j].apply_max_mem_size);
if (log_path[0] != '\0' && db_host[0] != '\0' && mem_size[0] != '\0')
{
char la_args[HB_MAX_SZ_PROC_ARGS];
const char *la_argv[] = {
UTIL_ADMIN_NAME, UTIL_APPLYLOGDB,
"-L", log_path, mem_size, db_host, NULL
};
status = ha_argv_to_args (la_args, sizeof (la_args), la_argv, HB_PTYPE_APPLYLOGDB);
if (status != NO_ERROR)
{
goto ret;
}
if (remote_host == NULL)
{
if (ha_is_registered (la_args, NULL))
{
continue;
}
status = proc_execute (UTIL_ADMIN_NAME, la_argv, false, false, false, &pid);
if (status != NO_ERROR)
{
goto ret;
}
if (out_ap && da_add (out_ap, &pid) != NO_ERROR)
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
else
{
const char *commdb_argv[] = {
UTIL_COMMDB_NAME,
COMMDB_HA_START_UTIL_PROCESS, la_args,
COMMDB_HOST, remote_host,
NULL,
};
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, &pid);
if (status != NO_ERROR)
{
goto ret;
}
if (out_ap && (da_add (out_ap, la_args) != NO_ERROR))
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
}
else
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
goto ret;
}
if (node_name != NULL && num_node_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
status = ER_GENERIC_ERROR;
}
ret:
print_result (UTIL_APPLYLOGDB, status, START);
return status;
}
static int
us_hb_applylogdb_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name, const char *remote_host)
{
int status = NO_ERROR;
int i, j, num_nodes;
int num_db_found = 0, num_node_found = 0;
HA_NODE_CONF *nc;
char log_path[PATH_MAX], db_host[PATH_MAX], mem_size[PATH_MAX];
char **dbs;
int wait_time = 0;
num_nodes = ha_conf->num_node_conf;
dbs = ha_conf->db_names;
nc = ha_conf->node_conf;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, UTIL_APPLYLOGDB, PRINT_CMD_STOP);
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (dbs[i], db_name) != 0)
{
continue;
}
num_db_found++;
for (j = 0; j < num_nodes; j++)
{
if (node_name != NULL && strcmp (nc[j].node_name, node_name) != 0)
{
continue;
}
if (remote_host == NULL)
{
if (util_is_localhost (nc[j].node_name))
{
continue;
}
}
else
{
if (node_name != NULL && strcmp (node_name, remote_host) == 0)
{
continue;
}
}
num_node_found++;
log_path[0] = db_host[0] = mem_size[0] = '\0';
(void) ha_concat_db_and_host (db_host, PATH_MAX, dbs[i], "localhost");
(void) ha_make_log_path (log_path, PATH_MAX, nc[j].copy_log_base, dbs[i], nc[j].node_name);
(void) ha_make_mem_size (mem_size, PATH_MAX, nc[j].apply_max_mem_size);
if (log_path[0] != '\0' && db_host[0] != '\0' && mem_size[0] != '\0')
{
char la_args[HB_MAX_SZ_PROC_ARGS];
const char *la_argv[] = {
UTIL_ADMIN_NAME, UTIL_APPLYLOGDB,
"-L", log_path, mem_size, db_host, NULL
};
status = ha_argv_to_args (la_args, sizeof (la_args), la_argv, HB_PTYPE_APPLYLOGDB);
if (status != NO_ERROR)
{
goto ret;
}
if (remote_host != NULL || ha_is_registered (la_args, remote_host))
{
const char *commdb_argv[HB_MAX_SZ_PROC_ARGS] = {
UTIL_COMMDB_NAME, COMMDB_HA_DEREG_BY_ARGS, la_args,
NULL, NULL, /* -h hostname */
NULL
};
if (remote_host != NULL)
{
commdb_argv[3] = COMMDB_HOST; /* -h */
commdb_argv[4] = remote_host; /* hostname */
commdb_argv[5] = NULL;
}
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, NULL);
if (remote_host != NULL && status != NO_ERROR)
{
goto ret;
}
wait_time = 0;
do
{
if (ha_is_registered (la_args, remote_host) == false)
{
status = NO_ERROR;
break;
}
sleep (3);
wait_time += 3;
}
while (wait_time < US_HB_DEREG_WAIT_TIME_IN_SEC);
}
}
else
{
status = ER_GENERIC_ERROR;
goto ret;
}
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
goto ret;
}
if (node_name != NULL && num_node_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_NODE);
status = ER_GENERIC_ERROR;
}
ret:
print_result (UTIL_APPLYLOGDB, status, STOP);
return status;
}
#if defined (ENABLE_UNUSED_FUNCTION)
static int
us_hb_utils_start (dynamic_array * pids, HA_CONF * ha_conf, const char *db_name, const char *node_name)
{
int status = NO_ERROR;
status = us_hb_copylogdb_start (pids, ha_conf, db_name, node_name, NULL);
if (status != NO_ERROR)
{
return status;
}
status = us_hb_applylogdb_start (pids, ha_conf, db_name, node_name, NULL);
return status;
}
static int
us_hb_utils_stop (HA_CONF * ha_conf, const char *db_name, const char *node_name)
{
int status = NO_ERROR;
status = us_hb_copylogdb_stop (ha_conf, db_name, node_name, NULL);
if (status != NO_ERROR)
{
return status;
}
status = us_hb_applylogdb_stop (ha_conf, db_name, node_name, NULL);
return status;
}
#endif /* ENABLE_UNUSED_FUNCTION */
static int
us_hb_server_start (HA_CONF * ha_conf, const char *db_name)
{
int status = NO_ERROR;
int i, num_db_found = 0;
char **dbs;
dbs = ha_conf->db_names;
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (db_name, dbs[i]))
{
continue;
}
num_db_found++;
if (!is_server_running (CHECK_SERVER, dbs[i], 0))
{
prm_set_integer_value (PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY, HA_MODE_FAIL_BACK);
status = sysprm_load_and_init (dbs[i], NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
print_result (PRINT_SERVER_NAME, status, START);
break;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
print_result (PRINT_SERVER_NAME, status, START);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
continue;
}
status = process_server (START, 1, &(dbs[i]), true, false, false);
if (status != NO_ERROR)
{
return status;
}
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, dbs[i]);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ALREADY_RUNNING_2S, PRINT_SERVER_NAME, dbs[i]);
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
}
return status;
}
static int
us_hb_server_stop (HA_CONF * ha_conf, const char *db_name)
{
int status = NO_ERROR;
int i, num_db_found = 0;
char **dbs;
dbs = ha_conf->db_names;
for (i = 0; dbs[i] != NULL; i++)
{
if (db_name != NULL && strcmp (db_name, dbs[i]))
{
continue;
}
num_db_found++;
if (is_server_running (CHECK_SERVER, dbs[i], 0))
{
status = process_server (STOP, 1, &(dbs[i]), true, false, false);
if (status != NO_ERROR)
{
return status;
}
}
else
{
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, dbs[i]);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_2S, PRINT_SERVER_NAME, dbs[i]);
}
}
if (db_name != NULL && num_db_found == 0)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
util_log_write_errid (MSGCAT_UTIL_GENERIC_HA_MODE_NOT_LISTED_HA_DB);
status = ER_GENERIC_ERROR;
}
return status;
}
static int
us_hb_process_start (HA_CONF * ha_conf, const char *db_name, bool check_result)
{
int status = NO_ERROR;
int i;
int pid;
dynamic_array *pids = NULL;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HA_PROCS_NAME, PRINT_CMD_START);
pids = da_create (100, sizeof (int));
if (pids == NULL)
{
status = ER_GENERIC_ERROR;
goto ret;
}
status = us_hb_server_start (ha_conf, db_name);
if (status != NO_ERROR)
{
goto ret;
}
status = us_hb_copylogdb_start (pids, ha_conf, db_name, NULL, NULL);
if (status != NO_ERROR)
{
goto ret;
}
status = us_hb_applylogdb_start (pids, ha_conf, db_name, NULL, NULL);
if (status != NO_ERROR)
{
goto ret;
}
sleep (HB_START_WAITING_TIME_IN_SECS);
if (check_result == true)
{
for (i = 0; i < da_size (pids); i++)
{
da_get (pids, i, &pid);
if (is_terminated_process (pid))
{
status = ER_GENERIC_ERROR;
break;
}
}
}
ret:
if (pids)
{
da_destroy (pids);
}
print_result (PRINT_HA_PROCS_NAME, status, START);
return status;
}
/*
* us_hb_deactivate - deactivate CUBRID heartbeat
* return:
*
* hostname(in): target hostname
* immediate_stop(in): whether to stop immediately or not
*/
static int
us_hb_deactivate (const char *hostname, bool immediate_stop)
{
int status = NO_ERROR;
int opt_idx = 1;
const char *args[] = {
UTIL_COMMDB_NAME, NULL, NULL, NULL, NULL, NULL
};
if (hostname != NULL && hostname[0] != '\0')
{
args[opt_idx++] = COMMDB_HOST;
args[opt_idx++] = hostname;
}
if (immediate_stop == true)
{
args[opt_idx++] = COMMDB_HB_DEACT_IMMEDIATELY;
}
/* stop all HA processes including cub_server */
args[opt_idx] = COMMDB_HA_DEACT_STOP_ALL;
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
if (status != NO_ERROR)
{
return status;
}
/* wait until all processes are shutdown */
args[opt_idx] = COMMDB_HA_DEACT_CONFIRM_STOP_ALL;
while ((status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL)) != NO_ERROR)
{
if (status == EXIT_FAILURE)
{
return status;
}
sleep (1);
}
/* start deactivation */
args[opt_idx] = COMMDB_HA_DEACTIVATE;
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
if (status != NO_ERROR)
{
return status;
}
/* wait until no cub_server processes are running */
args[opt_idx] = COMMDB_HA_DEACT_CONFIRM_NO_SERVER;
while ((status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL)) != NO_ERROR)
{
if (status == EXIT_FAILURE)
{
return status;
}
sleep (1);
}
return NO_ERROR;
}
static int
us_hb_process_stop (HA_CONF * ha_conf, const char *db_name)
{
int status = NO_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HA_PROCS_NAME, PRINT_CMD_STOP);
status = us_hb_copylogdb_stop (ha_conf, db_name, NULL, NULL);
if (status != NO_ERROR)
{
goto ret;
}
status = us_hb_applylogdb_stop (ha_conf, db_name, NULL, NULL);
if (status != NO_ERROR)
{
goto ret;
}
status = us_hb_server_stop (ha_conf, db_name);
ret:
print_result (PRINT_HA_PROCS_NAME, status, STOP);
return status;
}
static int
us_hb_process_copylogdb (int command_type, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host)
{
int status = NO_ERROR;
int i;
int pid;
dynamic_array *pids = NULL;
dynamic_array *args = NULL;
char arg[PATH_MAX];
switch (command_type)
{
case START:
if (remote_host == NULL)
{
pids = da_create (100, sizeof (int));
if (pids == NULL)
{
status = ER_GENERIC_ERROR;
goto ret;
}
status = us_hb_copylogdb_start (pids, ha_conf, db_name, node_name, remote_host);
sleep (HB_START_WAITING_TIME_IN_SECS);
for (i = 0; i < da_size (pids); i++)
{
da_get (pids, i, &pid);
if (is_terminated_process (pid))
{
(void) us_hb_copylogdb_stop (ha_conf, db_name, node_name, remote_host);
status = ER_GENERIC_ERROR;
break;
}
}
}
else
{
args = da_create (100, sizeof (arg));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
goto ret;
}
status = us_hb_copylogdb_start (args, ha_conf, db_name, node_name, remote_host);
sleep (HB_START_WAITING_TIME_IN_SECS);
for (i = 0; i < da_size (args); i++)
{
da_get (args, i, arg);
if (ha_is_registered (arg, remote_host) == false)
{
(void) us_hb_copylogdb_stop (ha_conf, db_name, node_name, remote_host);
status = ER_GENERIC_ERROR;
break;
}
}
}
break;
case STOP:
status = us_hb_copylogdb_stop (ha_conf, db_name, node_name, remote_host);
break;
default:
status = ER_GENERIC_ERROR;
break;
}
ret:
if (pids)
{
da_destroy (pids);
}
if (args)
{
da_destroy (args);
}
return status;
}
static int
us_hb_process_applylogdb (int command_type, HA_CONF * ha_conf, const char *db_name, const char *node_name,
const char *remote_host)
{
int status = NO_ERROR;
int i, pid;
dynamic_array *pids = NULL;
dynamic_array *args = NULL;
char arg[PATH_MAX];
switch (command_type)
{
case START:
if (remote_host == NULL)
{
pids = da_create (100, sizeof (int));
if (pids == NULL)
{
status = ER_GENERIC_ERROR;
goto ret;
}
status = us_hb_applylogdb_start (pids, ha_conf, db_name, node_name, remote_host);
sleep (HB_START_WAITING_TIME_IN_SECS);
for (i = 0; i < da_size (pids); i++)
{
da_get (pids, i, &pid);
if (is_terminated_process (pid))
{
(void) us_hb_applylogdb_stop (ha_conf, db_name, node_name, remote_host);
status = ER_GENERIC_ERROR;
break;
}
}
}
else
{
args = da_create (100, sizeof (arg));
if (args == NULL)
{
status = ER_GENERIC_ERROR;
goto ret;
}
status = us_hb_applylogdb_start (args, ha_conf, db_name, node_name, remote_host);
sleep (HB_START_WAITING_TIME_IN_SECS);
for (i = 0; i < da_size (args); i++)
{
da_get (args, i, arg);
if (ha_is_registered (arg, remote_host) == false)
{
(void) us_hb_applylogdb_stop (ha_conf, db_name, node_name, remote_host);
status = ER_GENERIC_ERROR;
break;
}
}
}
break;
case STOP:
status = us_hb_applylogdb_stop (ha_conf, db_name, node_name, remote_host);
break;
default:
status = ER_GENERIC_ERROR;
break;
}
ret:
if (pids)
{
da_destroy (pids);
}
if (args)
{
da_destroy (args);
}
return status;
}
#if defined (ENABLE_UNUSED_FUNCTION)
static int
us_hb_process_server (int command_type, HA_CONF * ha_conf, const char *db_name)
{
int status = NO_ERROR;
switch (command_type)
{
case START:
status = us_hb_server_start (ha_conf, db_name);
break;
case STOP:
status = us_hb_server_stop (ha_conf, db_name);
break;
default:
status = ER_GENERIC_ERROR;
break;
}
return status;
}
#endif /* !ENABLE_UNUSED_FUNCTION */
#endif /* !WINDOWS */
/*
* us_hb_stop_get_options -
* return: NO_ERROR or error code
*
* db_name(out):
* db_name_size(in):
* remote_host_name(out):
* remote_host_name_size(in):
* immediate_stop(out):
* argc(in):
* argv(in):
*
*/
static int
us_hb_stop_get_options (char *db_name, int db_name_size, char *remote_host_name, int remote_host_name_size,
bool * immediate_stop, int argc, const char **argv)
{
int status = NO_ERROR;
int opt, opt_idx;
char opt_str[64];
int tmp_argc;
const char **tmp_argv = NULL;
size_t copy_len;
const struct option hb_stop_opts[] = {
{COMMDB_HB_DEACT_IMMEDIATELY_L, 0, 0, COMMDB_HB_DEACT_IMMEDIATELY_S},
{COMMDB_HOST_L, 1, 0, COMMDB_HOST_S},
{0, 0, 0, 0}
};
*db_name = *remote_host_name = '\0';
*immediate_stop = false;
/* dummy program name + user given argv */
tmp_argc = argc + 1;
/* +1 for null termination */
tmp_argv = (const char **) malloc ((tmp_argc + 1) * sizeof (char *));
if (tmp_argv == NULL)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NO_MEM);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
goto ret;
}
memset (tmp_argv, 0, (tmp_argc + 1) * sizeof (char *));
tmp_argv[0] = PRINT_HEARTBEAT_NAME " " PRINT_CMD_STOP;
memcpy (&tmp_argv[1], argv, argc * sizeof (char *));
utility_make_getopt_optstring (hb_stop_opts, opt_str);
while (1)
{
opt = getopt_long (tmp_argc, (char *const *) tmp_argv, opt_str, hb_stop_opts, &opt_idx);
if (opt == -1)
{
break;
}
switch (opt)
{
case COMMDB_HOST_S:
copy_len = strnlen (optarg, remote_host_name_size - 1);
memcpy (remote_host_name, optarg, copy_len);
remote_host_name[copy_len] = '\0';
break;
case COMMDB_HB_DEACT_IMMEDIATELY_S:
*immediate_stop = true;
break;
default:
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
break;
}
}
/* process non optional arguments */
if (status == NO_ERROR && tmp_argc > optind)
{
if ((tmp_argc - optind) > 1)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[optind + 1]);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[optind + 1]);
goto ret;
}
if ((tmp_argc - optind) == 1)
{
copy_len = strnlen (tmp_argv[optind], db_name_size);
memcpy (db_name, tmp_argv[optind], copy_len);
db_name[copy_len] = '\0';
}
}
ret:
if (tmp_argv)
{
free_and_init (tmp_argv);
}
return status;
}
/*
* us_hb_status_get_options -
* return: NO_ERROR or error code
*
* verbose(out):
* remote_host_name(out):
* remote_host_name_size(in):
* argc(in):
* argv(in):
*
*/
static int
us_hb_status_get_options (bool * verbose, char *remote_host_name, int remote_host_name_size, int argc,
const char **argv)
{
int status = NO_ERROR;
int opt, opt_idx;
char opt_str[64];
int tmp_argc;
const char **tmp_argv = NULL;
int copy_len;
const struct option hb_status_opts[] = {
{"verbose", 0, 0, 'v'},
{COMMDB_HOST_L, 1, 0, COMMDB_HOST_S},
{0, 0, 0, 0}
};
*verbose = false;
*remote_host_name = '\0';
/* dummy program name + user given argv */
tmp_argc = argc + 1;
/* +1 for null termination */
tmp_argv = (const char **) malloc ((tmp_argc + 1) * sizeof (char *));
if (tmp_argv == NULL)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NO_MEM);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
goto ret;
}
memset (tmp_argv, 0, (tmp_argc + 1) * sizeof (char *));
tmp_argv[0] = PRINT_HEARTBEAT_NAME " " PRINT_CMD_STATUS;
memcpy (&tmp_argv[1], argv, argc * sizeof (char *));
utility_make_getopt_optstring (hb_status_opts, opt_str);
while (1)
{
opt = getopt_long (tmp_argc, (char *const *) tmp_argv, opt_str, hb_status_opts, &opt_idx);
if (opt == -1)
{
break;
}
switch (opt)
{
case 'v':
*verbose = true;
break;
case COMMDB_HOST_S:
copy_len = (int) strnlen (optarg, (size_t) (remote_host_name_size - 1));
memcpy (remote_host_name, optarg, copy_len);
remote_host_name[copy_len] = '\0';
break;
default:
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
break;
}
}
/* process non optional arguments */
if (status == NO_ERROR && tmp_argc > optind)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[optind]);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[optind]);
goto ret;
}
ret:
if (tmp_argv)
{
free_and_init (tmp_argv);
}
return status;
}
/*
* us_hb_util_get_options -
* return: NO_ERROR or error code
*
* db_name(out):
* db_name_size(in):
* node_name(out):
* node_name_size(in):
* remote_host_name(out):
* remote_host_name_size(in):
* argc(in):
* argv(in):
*
*/
static int
us_hb_util_get_options (char *db_name, int db_name_size, char *node_name, int node_name_size, char *remote_host_name,
int remote_host_name_size, int argc, const char **argv)
{
int status = NO_ERROR;
int opt, opt_idx;
char opt_str[64];
int tmp_argc;
const char **tmp_argv = NULL;
size_t copy_len;
const struct option hb_util_opts[] = {
{COMMDB_HOST_L, 1, 0, COMMDB_HOST_S},
{0, 0, 0, 0}
};
if (argc < 0)
{
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
return ER_GENERIC_ERROR;
}
*db_name = *node_name = *remote_host_name = '\0';
/* dummy program name + user given argv */
tmp_argc = argc + 1;
/* +1 for null termination */
tmp_argv = (const char **) malloc ((tmp_argc + 1) * sizeof (char *));
if (tmp_argv == NULL)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NO_MEM);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
goto ret;
}
memset (tmp_argv, 0, (tmp_argc + 1) * sizeof (char *));
tmp_argv[0] = PRINT_HEARTBEAT_NAME " " "copylogdb/applylogdb/prefetchlogdb";
memcpy (&tmp_argv[1], argv, argc * sizeof (char *));
utility_make_getopt_optstring (hb_util_opts, opt_str);
while (1)
{
opt = getopt_long (tmp_argc, (char *const *) tmp_argv, opt_str, hb_util_opts, &opt_idx);
if (opt == -1)
{
break;
}
switch (opt)
{
case COMMDB_HOST_S:
copy_len = strnlen (optarg, remote_host_name_size);
memcpy (remote_host_name, optarg, copy_len);
remote_host_name[copy_len] = '\0';
break;
default:
status = ER_GENERIC_ERROR;
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
break;
}
}
/* process non optional arguments */
if (status == NO_ERROR)
{
if ((tmp_argc - optind) > 2)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[tmp_argc - 1]);
util_log_write_errid (MSGCAT_UTIL_GENERIC_ARGS_OVER, tmp_argv[tmp_argc - 1]);
goto ret;
}
else if ((tmp_argc - optind) < 2)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
goto ret;
}
copy_len = strnlen (tmp_argv[optind], db_name_size - 1);
memcpy (db_name, tmp_argv[optind], copy_len);
db_name[copy_len] = '\0';
copy_len = strnlen (tmp_argv[optind + 1], node_name_size - 1);
memcpy (node_name, tmp_argv[optind + 1], copy_len);
node_name[copy_len] = '\0';
}
ret:
if (tmp_argv)
{
free_and_init (tmp_argv);
}
return status;
}
#if !defined(WINDOWS)
/*
* process_heartbeat_start -
*
* return:
*
* ha_conf(in):
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_start (HA_CONF * ha_conf, int argc, const char **argv)
{
int status = NO_ERROR;
int master_port;
const char *db_name = NULL;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, PRINT_CMD_START);
master_port = prm_get_master_port_id ();
if (!__gv_cvar.css_does_master_exist (master_port))
{
status = process_master (START);
if (status != NO_ERROR)
{
goto ret;
}
}
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = {
UTIL_COMMDB_NAME, COMMDB_HA_ACTIVATE, NULL
};
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
}
if (status != NO_ERROR)
{
goto ret;
}
db_name = (argc >= 1) ? argv[0] : NULL;
if (db_name != NULL)
{
status = sysprm_load_and_init (db_name, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
goto ret;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
goto ret;
}
}
status = us_hb_process_start (ha_conf, db_name, true);
if (status != NO_ERROR)
{
if (db_name == NULL)
{
(void) us_hb_deactivate (NULL, false);
}
else
{
(void) us_hb_process_stop (ha_conf, db_name);
}
}
ret:
print_result (PRINT_HEARTBEAT_NAME, status, START);
return status;
}
/*
* process_heartbeat_stop -
*
* return:
*
* ha_conf(in):
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_stop (HA_CONF * ha_conf, int argc, const char **argv)
{
int status = NO_ERROR;
int master_port;
char db_name[64] = ""; /* DBNAME_LEN */
char remote_host_name[CUB_MAXHOSTNAMELEN] = "";
bool immediate_stop = false;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, PRINT_CMD_STOP);
status =
us_hb_stop_get_options (db_name, sizeof (db_name), remote_host_name, sizeof (remote_host_name), &immediate_stop,
argc, argv);
if (status != NO_ERROR)
{
goto ret;
}
/* validate options */
if ((db_name[0] != '\0') && (remote_host_name[0] != '\0' || immediate_stop == true))
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
goto ret;
}
master_port = prm_get_master_port_id ();
if (remote_host_name[0] != '\0' || __gv_cvar.css_does_master_exist (master_port) == true)
{
if (db_name[0] != '\0')
{
status = sysprm_load_and_init (db_name, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
goto ret;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
goto ret;
}
status = us_hb_process_stop (ha_conf, db_name);
}
else
{
status = us_hb_deactivate (remote_host_name, immediate_stop);
}
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
if (status == NO_ERROR)
{
/* wait for cub_master to clean up its internal resources */
sleep (HB_STOP_WAITING_TIME_IN_SECS);
}
ret:
print_result (PRINT_HEARTBEAT_NAME, status, STOP);
return status;
}
#endif
/*
* process_heartbeat_deregister -
*
* return:
*
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_deregister (int argc, const char **argv)
{
int status = NO_ERROR;
int master_port;
const char *pid = NULL;
if (argc < 1)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
goto ret;
}
pid = (char *) argv[0];
if (pid == NULL)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
goto ret;
}
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_3S, PRINT_HEARTBEAT_NAME, PRINT_CMD_DEREG, pid);
master_port = prm_get_master_port_id ();
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *commdb_argv[] = {
UTIL_COMMDB_NAME, COMMDB_HA_DEREG_BY_PID, pid, NULL
};
status = proc_execute (UTIL_COMMDB_NAME, commdb_argv, true, false, false, NULL);
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
ret:
print_result (PRINT_HEARTBEAT_NAME, status, DEREGISTER);
return status;
}
/*
* process_heartbeat_status -
*
* return:
*
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_status (int argc, const char **argv)
{
int status = NO_ERROR;
int master_port;
bool verbose;
char remote_host_name[CUB_MAXHOSTNAMELEN];
int ext_opt_offset;
const char *node_list_argv[] = {
UTIL_COMMDB_NAME, COMMDB_HA_NODE_LIST,
NULL, NULL, NULL, /* -v and/or -h hostname */
NULL
};
const char *proc_list_argv[] = {
UTIL_COMMDB_NAME, COMMDB_HA_PROC_LIST,
NULL, NULL, NULL, /* -v and/or -h hostname */
NULL
};
const char *ping_host_list_argv[] = {
UTIL_COMMDB_NAME, COMMDB_HA_PING_HOST_LIST,
NULL, NULL, NULL, /* -v and/or -h hostname */
NULL
};
const char *admin_info_argv[] = {
UTIL_COMMDB_NAME, COMMDB_HA_ADMIN_INFO,
NULL, NULL, NULL, /* -v and/or -h hostname */
NULL
};
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, PRINT_CMD_STATUS);
verbose = false;
memset (remote_host_name, 0, sizeof (remote_host_name));
status = us_hb_status_get_options (&verbose, remote_host_name, sizeof (remote_host_name), argc, argv);
if (status != NO_ERROR)
{
return status;
}
ext_opt_offset = 2;
if (remote_host_name[0] != '\0')
{
node_list_argv[ext_opt_offset] = COMMDB_HOST; /* -h */
proc_list_argv[ext_opt_offset] = COMMDB_HOST; /* -h */
ping_host_list_argv[ext_opt_offset] = COMMDB_HOST; /* -h */
admin_info_argv[ext_opt_offset] = COMMDB_HOST; /* -h */
ext_opt_offset++;
node_list_argv[ext_opt_offset] = remote_host_name; /* hostname */
proc_list_argv[ext_opt_offset] = remote_host_name; /* hostname */
ping_host_list_argv[ext_opt_offset] = remote_host_name; /* hostname */
admin_info_argv[ext_opt_offset] = remote_host_name; /* hostname */
ext_opt_offset++;
}
else
{
master_port = prm_get_master_port_id ();
if (__gv_cvar.css_does_master_exist (master_port) == false)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
return status;
}
}
if (verbose == true)
{
node_list_argv[ext_opt_offset] = COMMDB_VERBOSE_OUTPUT;
proc_list_argv[ext_opt_offset] = COMMDB_VERBOSE_OUTPUT;
}
status = proc_execute (UTIL_COMMDB_NAME, node_list_argv, true, false, false, NULL);
if (status != NO_ERROR)
{
return status;
}
status = proc_execute (UTIL_COMMDB_NAME, proc_list_argv, true, false, false, NULL);
if (status != NO_ERROR)
{
return status;
}
status = proc_execute (UTIL_COMMDB_NAME, ping_host_list_argv, true, false, false, NULL);
if (status != NO_ERROR)
{
return status;
}
if (verbose == true)
{
status = proc_execute (UTIL_COMMDB_NAME, admin_info_argv, true, false, false, NULL);
}
return status;
}
/*
* process_heartbeat_reload -
*
* return:
*
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_reload (int argc, const char **argv)
{
int status = NO_ERROR;
int master_port;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, PRINT_CMD_RELOAD);
master_port = prm_get_master_port_id ();
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = {
UTIL_COMMDB_NAME, COMMDB_HA_RELOAD, NULL
};
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
print_result (PRINT_HEARTBEAT_NAME, status, RELOAD);
return status;
}
#if !defined(WINDOWS)
/*
* process_heartbeat_util -
*
* return:
*
* ha_conf(in):
* command_type(in):
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_util (HA_CONF * ha_conf, int command_type, int argc, const char **argv)
{
int status = NO_ERROR;
int sub_command_type;
char db_name[64];
char node_name[CUB_MAXHOSTNAMELEN];
char host_name[CUB_MAXHOSTNAMELEN];
char *db_name_p, *node_name_p, *host_name_p;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, command_string (command_type));
sub_command_type = parse_arg (us_Command_map, (char *) argv[0]);
db_name[0] = node_name[0] = host_name[0] = '\0';
status =
us_hb_util_get_options (db_name, sizeof (db_name), node_name, sizeof (node_name), host_name, sizeof (host_name),
(argc - 1), (argv + 1));
if (status != NO_ERROR)
{
goto ret;
}
db_name_p = (db_name[0] == '\0') ? NULL : db_name;
node_name_p = (node_name[0] == '\0') ? NULL : node_name;
host_name_p = (host_name[0] == '\0') ? NULL : host_name;
assert (db_name_p != NULL);
status = sysprm_load_and_init (db_name_p, NULL, SYSPRM_IGNORE_INTL_PARAMS);
if (status != NO_ERROR)
{
goto ret;
}
if (util_get_ha_mode_for_sa_utils () == HA_MODE_OFF)
{
status = ER_GENERIC_ERROR;
print_message (stderr, MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
goto ret;
}
switch (command_type)
{
case SC_COPYLOGDB:
status = us_hb_process_copylogdb (sub_command_type, ha_conf, db_name_p, node_name_p, host_name_p);
break;
case SC_APPLYLOGDB:
status = us_hb_process_applylogdb (sub_command_type, ha_conf, db_name_p, node_name_p, host_name_p);
break;
}
ret:
print_result (PRINT_HEARTBEAT_NAME, status, command_type);
return status;
}
/*
* process_heartbeat_replication -
*
* return:
*
* ha_conf(in):
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat_replication (HA_CONF * ha_conf, int argc, const char **argv)
{
int status = NO_ERROR;
int sub_command_type;
int master_port;
const char *node_name = NULL;
print_message (stdout, MSGCAT_UTIL_GENERIC_START_STOP_2S, PRINT_HEARTBEAT_NAME, PRINT_CMD_REPLICATION);
if (argc < 2)
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_MISS_ARGUMENT);
goto ret;
}
sub_command_type = parse_arg (us_Command_map, (char *) argv[0]);
node_name = argv[1];
if ((sub_command_type != START && sub_command_type != STOP) || node_name == NULL || node_name[0] == '\0')
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
goto ret;
}
master_port = prm_get_master_port_id ();
if (__gv_cvar.css_does_master_exist (master_port))
{
const char *args[] = {
UTIL_COMMDB_NAME, COMMDB_HA_ACTIVATE, NULL
};
status = proc_execute (UTIL_COMMDB_NAME, args, true, false, false, NULL);
if (status == NO_ERROR)
{
if (sub_command_type == START)
{
status = us_hb_process_copylogdb (START, ha_conf, NULL, node_name, NULL);
if (status == NO_ERROR)
{
status = us_hb_process_applylogdb (START, ha_conf, NULL, node_name, NULL);
if (status != NO_ERROR)
{
(void) us_hb_process_copylogdb (STOP, ha_conf, NULL, node_name, NULL);
}
}
}
else
{
(void) us_hb_process_copylogdb (STOP, ha_conf, NULL, node_name, NULL);
(void) us_hb_process_applylogdb (STOP, ha_conf, NULL, node_name, NULL);
status = NO_ERROR;
}
}
}
else
{
status = ER_GENERIC_ERROR;
print_message (stdout, MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_RUNNING_1S, PRINT_MASTER_NAME);
}
ret:
print_result (PRINT_HEARTBEAT_NAME, status, REPLICATION);
return status;
}
#endif
/*
* process_heartbeat -
*
* return:
*
* command_type(in):
* argc(in):
* argv(in):
*
*/
static int
process_heartbeat (int command_type, int argc, const char **argv)
{
int status = NO_ERROR;
#if !defined(WINDOWS)
HA_CONF ha_conf;
if (ha_mode_in_common == HA_MODE_OFF)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NOT_HA_MODE);
print_result (PRINT_HEARTBEAT_NAME, ER_FAILED, command_type);
return ER_FAILED;
}
memset ((void *) &ha_conf, 0, sizeof (HA_CONF));
status = util_make_ha_conf (&ha_conf);
if (status != NO_ERROR)
{
print_message (stderr, MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
print_result (PRINT_HEARTBEAT_NAME, ER_FAILED, command_type);
return ER_FAILED;
}
switch (command_type)
{
case START:
status = process_heartbeat_start (&ha_conf, argc, argv);
break;
case STOP:
status = process_heartbeat_stop (&ha_conf, argc, argv);
break;
case DEREGISTER:
status = process_heartbeat_deregister (argc, argv);
break;
case STATUS:
case LIST:
status = process_heartbeat_status (argc, argv);
break;
case RELOAD:
status = process_heartbeat_reload (argc, argv);
break;
case SC_COPYLOGDB:
case SC_APPLYLOGDB:
status = process_heartbeat_util (&ha_conf, command_type, argc, argv);
break;
case REPLICATION:
status = process_heartbeat_replication (&ha_conf, argc, argv);
break;
default:
status = ER_GENERIC_ERROR;
break;
}
ret:
util_free_ha_conf (&ha_conf);
return status;
#else /* !WINDOWS */
status = ER_FAILED;
print_result (PRINT_HEARTBEAT_NAME, status, command_type);
return status;
#endif /* WINDOWS */
}
/*
* parse_arg -
*
* return:
*
* option(in):
* arg(in):
*
*/
static int
parse_arg (UTIL_SERVICE_OPTION_MAP_T * option, const char *arg)
{
int i;
if (arg == NULL || arg[0] == 0)
{
return ER_GENERIC_ERROR;
}
for (i = 0; option[i].option_type != -1; i++)
{
if (strcasecmp (option[i].option_name, arg) == 0)
{
return option[i].option_type;
}
}
return ER_GENERIC_ERROR;
}
/*
* load_properties -
*
* return:
*
* NOTE:
*/
static int
load_properties (void)
{
bool server_flag = false;
bool broker_flag = false;
bool gateway_flag = false;
bool manager_flag = false;
bool heartbeat_flag = false;
bool pl_flag = false;
char *value = NULL;
if (sysprm_load_and_init (NULL, NULL, SYSPRM_IGNORE_INTL_PARAMS) != NO_ERROR)
{
return ER_GENERIC_ERROR;
}
/* get service::service list */
value = prm_get_string_value (PRM_ID_SERVICE_SERVICE_LIST);
if (value != NULL)
{
const char *error_msg;
char *util = NULL, *save_ptr = NULL;
for (util = value;; util = NULL)
{
util = strtok_r (util, " \t,", &save_ptr);
if (util == NULL)
{
break;
}
if (strcmp (util, UTIL_TYPE_SERVER) == 0)
{
server_flag = true;
}
else if (strcmp (util, UTIL_TYPE_BROKER) == 0)
{
broker_flag = true;
}
else if (strcmp (util, UTIL_TYPE_MANAGER) == 0)
{
manager_flag = true;
}
else if (strcmp (util, UTIL_TYPE_HEARTBEAT) == 0)
{
heartbeat_flag = true;
}
else if (strcmp (util, UTIL_TYPE_GATEWAY) == 0)
{
gateway_flag = true;
}
else
{
error_msg = utility_get_generic_message (MSGCAT_UTIL_GENERIC_INVALID_PARAMETER);
fprintf (stderr, error_msg, "service", util);
return ER_GENERIC_ERROR;
}
}
}
us_Property_map[SERVICE_START_SERVER].property_value = strdup (server_flag ? PROPERTY_ON : PROPERTY_OFF);
us_Property_map[SERVICE_START_BROKER].property_value = strdup (broker_flag ? PROPERTY_ON : PROPERTY_OFF);
us_Property_map[SERVICE_START_GATEWAY].property_value = strdup (gateway_flag ? PROPERTY_ON : PROPERTY_OFF);
us_Property_map[SERVICE_START_MANAGER].property_value = strdup (manager_flag ? PROPERTY_ON : PROPERTY_OFF);
us_Property_map[SERVICE_START_HEARTBEAT].property_value = strdup (heartbeat_flag ? PROPERTY_ON : PROPERTY_OFF);
/* get service::server list */
value = prm_get_string_value (PRM_ID_SERVICE_SERVER_LIST);
if (value != NULL)
{
us_Property_map[SERVER_START_LIST].property_value = strdup (value);
if (us_Property_map[SERVER_START_LIST].property_value == NULL)
{
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) (strlen (value) + 1));
return ER_OUT_OF_VIRTUAL_MEMORY;
}
}
else
{
us_Property_map[SERVER_START_LIST].property_value = NULL;
}
return NO_ERROR;
}
/*
* finalize_properties - free allocated memory by strdup ()
*
* return:
*
*/
static void
finalize_properties (void)
{
int i;
for (i = 0; us_Property_map[i].property_index != -1; i++)
{
if (us_Property_map[i].property_value != NULL)
{
free_and_init (us_Property_map[i].property_value);
}
}
}
/*
* get_property -
*
* return:
*
* property_type(in):
*
* NOTE:
*/
static const char *
get_property (int property_type)
{
return us_Property_map[property_type].property_value;
}