From: Botond Baranyi Date: Wed, 29 Jun 2016 12:18:33 +0000 (+0200) Subject: implemented the Main Controller's 'reconf' command (artf468488) X-Git-Url: http://git.efficios.com/?p=deliverable%2Ftitan.core.git;a=commitdiff_plain;h=b0caada215c3ca0bcdd40e5b9735e9f26f454b83 implemented the Main Controller's 'reconf' command (artf468488) Change-Id: Ie84819f7e01d73b0735aaab24207117e4adef28b Signed-off-by: Botond Baranyi --- diff --git a/core/Communication.cc b/core/Communication.cc index 44352b9..6c4df1c 100644 --- a/core/Communication.cc +++ b/core/Communication.cc @@ -572,7 +572,7 @@ void TTCN_Communication::process_all_messages_hc() process_error(); break; case MSG_CONFIGURE: - process_configure(msg_end); + process_configure(msg_end, false); break; case MSG_CREATE_MTC: process_create_mtc(); @@ -704,6 +704,9 @@ void TTCN_Communication::process_all_messages_tc() case MSG_EXIT_MTC: process_exit_mtc(); break; + case MSG_CONFIGURE: + process_configure(msg_end, true); + break; default: process_unsupported_message(msg_type, msg_end); } @@ -1263,20 +1266,28 @@ void TTCN_Communication::send_message(Text_Buf& text_buf) } } -void TTCN_Communication::process_configure(int msg_end) +void TTCN_Communication::process_configure(int msg_end, bool to_mtc) { switch (TTCN_Runtime::get_state()) { case TTCN_Runtime::HC_IDLE: case TTCN_Runtime::HC_ACTIVE: case TTCN_Runtime::HC_OVERLOADED: - break; + if (!to_mtc) { + break; + } + // no break + case TTCN_Runtime::MTC_IDLE: + if (to_mtc) { + break; + } + // no break default: incoming_buf.cut_message(); send_error("Message CONFIGURE arrived in invalid state."); return; } - TTCN_Runtime::set_state(TTCN_Runtime::HC_CONFIGURING); + TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_CONFIGURING : TTCN_Runtime::HC_CONFIGURING); TTCN_Logger::log_configdata(TitanLoggerApiSimple::ExecutorConfigdata_reason::received__from__mc); // take the config string directly from the buffer for efficiency reasons @@ -1311,12 +1322,12 @@ void TTCN_Communication::process_configure(int msg_end) if (success) { send_configure_ack(); - TTCN_Runtime::set_state(TTCN_Runtime::HC_ACTIVE); + TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_IDLE : TTCN_Runtime::HC_ACTIVE); TTCN_Logger::log_configdata( TitanLoggerApiSimple::ExecutorConfigdata_reason::processing__succeeded); } else { send_configure_nak(); - TTCN_Runtime::set_state(TTCN_Runtime::HC_IDLE); + TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_IDLE : TTCN_Runtime::HC_IDLE); } incoming_buf.cut_message(); diff --git a/core/Communication.hh b/core/Communication.hh index 3cf058e..1cf41e2 100644 --- a/core/Communication.hh +++ b/core/Communication.hh @@ -182,7 +182,7 @@ private: /** @name Handlers of various messages * @{ */ - static void process_configure(int msg_end); + static void process_configure(int msg_end, bool to_mtc); static void process_create_mtc(); static void process_create_ptc(); static void process_kill_process(); diff --git a/core/Message_types.hh b/core/Message_types.hh index b8873d6..cb71898 100644 --- a/core/Message_types.hh +++ b/core/Message_types.hh @@ -34,7 +34,6 @@ /* Messages from MC to HC (down) */ -#define MSG_CONFIGURE 1 #define MSG_CREATE_MTC 2 #define MSG_CREATE_PTC 3 #define MSG_KILL_PROCESS 4 @@ -42,8 +41,6 @@ /* Messages from HC to MC (up) */ -#define MSG_CONFIGURE_ACK 2 -#define MSG_CONFIGURE_NAK 3 #define MSG_CREATE_NAK 4 #define MSG_HC_READY 5 @@ -128,4 +125,13 @@ #define MSG_DEBUG_RETURN_VALUE 100 +/* Messages from MC to HC or MTC (down) */ + +#define MSG_CONFIGURE 200 + +/* Messages from HC or MTC to MC (up) */ + +#define MSG_CONFIGURE_ACK 200 +#define MSG_CONFIGURE_NAK 201 + #endif diff --git a/core/Runtime.hh b/core/Runtime.hh index 282a531..10e67fc 100644 --- a/core/Runtime.hh +++ b/core/Runtime.hh @@ -50,11 +50,11 @@ public: MTC_TERMINATING_TESTCASE, MTC_TERMINATING_EXECUTION, MTC_PAUSED, // 14-16 MTC_CREATE, MTC_START, MTC_STOP, MTC_KILL, MTC_RUNNING, MTC_ALIVE, // 17-22 MTC_DONE, MTC_KILLED, MTC_CONNECT, MTC_DISCONNECT, MTC_MAP, MTC_UNMAP, // 23-28 - MTC_EXIT, // 29 + MTC_CONFIGURING, MTC_EXIT, // 30 - PTC_INITIAL, PTC_IDLE, PTC_FUNCTION, PTC_CREATE, PTC_START, PTC_STOP, // 30-35 - PTC_KILL, PTC_RUNNING, PTC_ALIVE, PTC_DONE, PTC_KILLED, PTC_CONNECT, // 36-41 - PTC_DISCONNECT, PTC_MAP, PTC_UNMAP, PTC_STOPPED, PTC_EXIT // 42-46 + PTC_INITIAL, PTC_IDLE, PTC_FUNCTION, PTC_CREATE, PTC_START, PTC_STOP, // 31-36 + PTC_KILL, PTC_RUNNING, PTC_ALIVE, PTC_DONE, PTC_KILLED, PTC_CONNECT, // 37-42 + PTC_DISCONNECT, PTC_MAP, PTC_UNMAP, PTC_STOPPED, PTC_EXIT // 43-47 }; private: static executor_state_enum executor_state; diff --git a/mctr2/cli/Cli.cc b/mctr2/cli/Cli.cc index b4818ac..6a4886a 100644 --- a/mctr2/cli/Cli.cc +++ b/mctr2/cli/Cli.cc @@ -195,12 +195,14 @@ Cli::Cli() perror("Cli::Cli: pthread_cond_init failed."); exit(EXIT_FAILURE); } + cfg_file_name = NULL; } Cli::~Cli() { pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); + Free(cfg_file_name); } //---------------------------------------------------------------------------- @@ -217,8 +219,9 @@ int Cli::enterLoop(int argc, char *argv[]) printWelcome(); if (argc == 2) { - printf("Using configuration file: %s\n", argv[1]); - if (process_config_read_file(argv[1], &mycfg)) { + cfg_file_name = mcopystr(argv[1]); + printf("Using configuration file: %s\n", cfg_file_name); + if (process_config_read_file(cfg_file_name, &mycfg)) { puts("Error was found in the configuration file. Exiting."); cleanUp(); return EXIT_FAILURE; @@ -728,12 +731,37 @@ void Cli::infoCallback(const char *arguments) void Cli::reconfCallback(const char *arguments) { - if(*arguments == 0) { // reconf called without its optional argument - puts("Reconfiguration of MC and HCs using original configuration " - "data\n -- not supported, yet."); - } else { // reconf called with config_file argument - puts("Reconfiguration of MC and HCs using configuration file" - "specified in\ncommand line argument -- not supported, yet."); + if (!MainController::start_reconfiguring()) { + return; + } + if (*arguments != 0) { + Free(cfg_file_name); + cfg_file_name = mcopystr(arguments); + } + + printf("Using configuration file: %s\n", cfg_file_name); + if (process_config_read_file(cfg_file_name, &mycfg)) { + puts("Error was found in the configuration file. Exiting."); + cleanUp(); + puts("exit"); + exitCallback(""); + } + else { + MainController::set_kill_timer(mycfg.kill_timer); + + for (int i = 0; i < mycfg.group_list_len; ++i) { + MainController::add_host(mycfg.group_list[i].group_name, + mycfg.group_list[i].host_name); + } + + for (int i = 0; i < mycfg.component_list_len; ++i) { + MainController::assign_component(mycfg.component_list[i].host_or_group, + mycfg.component_list[i].component); + } + + if (MainController::get_state() == mctr::MC_RECONFIGURING) { + MainController::configure(mycfg.config_read_buffer); + } } } @@ -800,6 +828,7 @@ void Cli::exitCallback(const char *arguments) if (*arguments == 0) { switch (MainController::get_state()) { case mctr::MC_READY: + case mctr::MC_RECONFIGURING: MainController::exit_mtc(); waitMCState(WAIT_MTC_TERMINATED); case mctr::MC_LISTENING: diff --git a/mctr2/cli/Cli.h b/mctr2/cli/Cli.h index 190de8f..5485f0e 100644 --- a/mctr2/cli/Cli.h +++ b/mctr2/cli/Cli.h @@ -191,6 +191,7 @@ private: */ int executeListIndex; + char* cfg_file_name; config_data mycfg; }; diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc index 0af6531..8ff3258 100644 --- a/mctr2/mctr/MainController.cc +++ b/mctr2/mctr/MainController.cc @@ -688,20 +688,37 @@ void MainController::configure_host(host_struct *host, boolean should_notify) host->hostname); } send_configure(host, config_str); - send_debug_setup(host); + if (mc_state != MC_RECONFIGURING) { + send_debug_setup(host); + } + } +} + +void MainController::configure_mtc() +{ + if (config_str == NULL) { + fatal_error("MainController::configure_mtc: no config file"); + } + if (mtc->tc_state != TC_IDLE) { + error("MainController::configure_mtc(): MTC is in wrong state."); + } + else { + mtc->tc_state = MTC_CONFIGURING; + send_configure_mtc(config_str); } } void MainController::check_all_hc_configured() { + bool reconf = mc_state == MC_RECONFIGURING; if (is_hc_in_state(HC_CONFIGURING) || is_hc_in_state(HC_CONFIGURING_OVERLOADED)) return; if (is_hc_in_state(HC_IDLE)) { error("There were errors during configuring HCs."); - mc_state = MC_HC_CONNECTED; + mc_state = reconf ? MC_READY : MC_HC_CONNECTED; } else if (is_hc_in_state(HC_ACTIVE) || is_hc_in_state(HC_OVERLOADED)) { notify("Configuration file was processed on all HCs."); - mc_state = MC_ACTIVE; + mc_state = reconf ? MC_READY : MC_ACTIVE; } else { error("There is no HC connection after processing the configuration " "file."); @@ -2782,6 +2799,7 @@ void MainController::handle_hc_data(host_struct *hc, boolean recv_from_socket) if (all_hc_in_state(HC_DOWN)) mc_state = MC_LISTENING; break; case MC_CONFIGURING: + case MC_RECONFIGURING: check_all_hc_configured(); break; case MC_ACTIVE: @@ -2901,6 +2919,12 @@ void MainController::handle_tc_data(component_struct *tc, case MSG_MTC_READY: process_mtc_ready(); break; + case MSG_CONFIGURE_ACK: + process_configure_ack_mtc(); + break; + case MSG_CONFIGURE_NAK: + process_configure_nak_mtc(); + break; default: error("Invalid message type (%d) was received " "from the MTC at %s [%s].", message_type, @@ -3538,6 +3562,15 @@ void MainController::send_exit_mtc() send_message(mtc->tc_fd, text_buf); } +void MainController::send_configure_mtc(const char* config_file) +{ + Text_Buf text_buf; + text_buf.push_int(MSG_CONFIGURE); + text_buf.push_string(config_file); + send_message(mtc->tc_fd, text_buf); +} + + void MainController::send_cancel_done_ptc(component_struct *tc, component component_reference) { @@ -3840,7 +3873,8 @@ void MainController::process_configure_ack(host_struct *hc) "received."); return; } - if (mc_state == MC_CONFIGURING) check_all_hc_configured(); + if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING) + check_all_hc_configured(); else notify("Host %s was configured successfully.", hc->hostname); status_change(); } @@ -3857,7 +3891,8 @@ void MainController::process_configure_nak(host_struct *hc) "received."); return; } - if (mc_state == MC_CONFIGURING) check_all_hc_configured(); + if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING) + check_all_hc_configured(); else notify("Processing of configuration file failed on host %s.", hc->hostname); status_change(); @@ -5766,6 +5801,26 @@ void MainController::process_mtc_ready() status_change(); } +void MainController::process_configure_ack_mtc() +{ + if (mtc->tc_state != MTC_CONFIGURING) { + send_error_str(mtc->tc_fd, "Unexpected message CONFIGURE_ACK was received."); + return; + } + mtc->tc_state = TC_IDLE; + notify("Configuration file was processed on the MTC."); +} + +void MainController::process_configure_nak_mtc() +{ + if (mtc->tc_state != MTC_CONFIGURING) { + send_error_str(mtc->tc_fd, "Unexpected message CONFIGURE_NAK was received."); + return; + } + mtc->tc_state = TC_IDLE; + notify("Processing of configuration file failed on the MTC."); +} + void MainController::process_stopped(component_struct *tc, int message_end) { switch (tc->tc_state) { @@ -6049,12 +6104,20 @@ void MainController::destroy_host_groups() void MainController::set_kill_timer(double timer_val) { lock(); - if (mc_state != MC_INACTIVE) + switch (mc_state) { + case MC_INACTIVE: + case MC_LISTENING: + case MC_HC_CONNECTED: + case MC_RECONFIGURING: + if (timer_val < 0.0) + error("MainController::set_kill_timer: setting a negative kill timer " + "value."); + else kill_timer = timer_val; + break; + default: error("MainController::set_kill_timer: called in wrong state."); - else if (timer_val < 0.0) - error("MainController::set_kill_timer: setting a negative kill timer " - "value."); - else kill_timer = timer_val; + break; + } unlock(); } @@ -6309,6 +6372,8 @@ void MainController::configure(const char *config_file) case MC_LISTENING_CONFIGURED: mc_state = MC_LISTENING_CONFIGURED; break; + case MC_RECONFIGURING: + break; default: error("MainController::configure: called in wrong state."); unlock(); @@ -6316,14 +6381,35 @@ void MainController::configure(const char *config_file) } Free(config_str); config_str = mcopystr(config_file); - if(mc_state == MC_CONFIGURING) { + if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING) { notify("Downloading configuration file to all HCs."); for (int i = 0; i < n_hosts; i++) configure_host(hosts[i], FALSE); } + if (mc_state == MC_RECONFIGURING) { + notify("Downloading configuration file to the MTC."); + configure_mtc(); + } status_change(); unlock(); } +bool MainController::start_reconfiguring() +{ + switch (mc_state) { + case MC_READY: + mc_state = MC_RECONFIGURING; + return true; + case MC_LISTENING: + case MC_HC_CONNECTED: + return true; + default: + lock(); + error("MainController::start_reconfiguring: called in wrong state."); + unlock(); + return false; + } +} + void MainController::create_mtc(int host_index) { lock(); @@ -6415,7 +6501,7 @@ void MainController::create_mtc(int host_index) void MainController::exit_mtc() { lock(); - if (mc_state != MC_READY) { + if (mc_state != MC_READY && mc_state != MC_RECONFIGURING) { error("MainController::exit_mtc: called in wrong state."); unlock(); return; diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h index 561c665..c670f01 100644 --- a/mctr2/mctr/MainController.h +++ b/mctr2/mctr/MainController.h @@ -63,7 +63,7 @@ enum mc_state_enum { MC_INACTIVE, MC_LISTENING, MC_LISTENING_CONFIGURED, MC_HC_CONNECTED, MC_CONFIGURING, MC_ACTIVE, MC_SHUTDOWN, MC_CREATING_MTC, MC_READY, MC_TERMINATING_MTC, MC_EXECUTING_CONTROL, MC_EXECUTING_TESTCASE, - MC_TERMINATING_TESTCASE, MC_PAUSED + MC_TERMINATING_TESTCASE, MC_PAUSED, MC_RECONFIGURING }; /** Data structure for unknown incoming connections (before receiving @@ -164,7 +164,7 @@ enum tc_state_enum { TC_INITIAL, TC_IDLE, TC_CREATE, TC_START, TC_STOP, TC_KILL, MTC_CONTROLPART, MTC_TESTCASE, MTC_ALL_COMPONENT_STOP, MTC_ALL_COMPONENT_KILL, MTC_TERMINATING_TESTCASE, MTC_PAUSED, PTC_FUNCTION, PTC_STARTING, PTC_STOPPED, PTC_KILLING, PTC_STOPPING_KILLING, - PTC_STALE, TC_SYSTEM }; + PTC_STALE, TC_SYSTEM, MTC_CONFIGURING }; /** Data structure for each TC */ struct component_struct { @@ -345,6 +345,7 @@ class MainController { static boolean is_hc_in_state(hc_state_enum checked_state); static boolean all_hc_in_state(hc_state_enum checked_state); static void configure_host(host_struct *host, boolean should_notify); + static void configure_mtc(); static void check_all_hc_configured(); static void add_component_to_host(host_struct *host, component_struct *comp); @@ -544,6 +545,7 @@ private: static void send_ptc_verdict(boolean continue_execution); static void send_continue(); static void send_exit_mtc(); + static void send_configure_mtc(const char *config_file); /** Messages to PTCs */ static void send_cancel_done_ptc(component_struct *tc, @@ -607,6 +609,8 @@ private: static void process_testcase_started(); static void process_testcase_finished(); static void process_mtc_ready(); + static void process_configure_ack_mtc(); + static void process_configure_nak_mtc(); /* Incoming messages from PTCs */ static void process_stopped(component_struct *tc, int message_end); @@ -629,6 +633,7 @@ public: static void shutdown_session(); static void configure(const char *config_file); + static bool start_reconfiguring(); static void create_mtc(int host_index); static void exit_mtc(); diff --git a/usrguide/userguide.doc b/usrguide/userguide.doc index a440e5d..430e532 100644 Binary files a/usrguide/userguide.doc and b/usrguide/userguide.doc differ