From 37bcf90336c92ea05b4413ad0bd579157b8a42ce Mon Sep 17 00:00:00 2001 From: david Date: Thu, 9 Feb 2017 15:29:07 +0000 Subject: [PATCH 001/185] MCOL-105 - add suse boost-devel package check --- cpackEngineRPM.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpackEngineRPM.cmake b/cpackEngineRPM.cmake index 32552e855..b427afbfc 100644 --- a/cpackEngineRPM.cmake +++ b/cpackEngineRPM.cmake @@ -85,9 +85,14 @@ if (${REDHAT_VERSION_NUMBER} EQUAL 6) # Disable auto require as this will also try to pull Boost via RPM SET(CPACK_RPM_PACKAGE_AUTOREQPROV " no") else () - SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost >= 1.53.0" "mariadb-columnstore-libs") + if (${REDHAT_VERSION_NUMBER} EQUAL 7) + SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost >= 1.53.0" "mariadb-columnstore-libs") + else () + SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost-devel" "mariadb-columnstore-libs") + endif() endif() + SETA(CPACK_RPM_storage-engine_PACKAGE_REQUIRES "mariadb-columnstore-libs") SET(CPACK_RPM_platform_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/build/postInstall_platform.sh) From 03aa2f3a7fc69efd861fbd336cf29b7805c97ed1 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 9 Feb 2017 15:24:14 -0600 Subject: [PATCH 002/185] MCOL-105 - change suse boost-devel package check --- cpackEngineRPM.cmake | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/cpackEngineRPM.cmake b/cpackEngineRPM.cmake index b427afbfc..e5030c4fb 100644 --- a/cpackEngineRPM.cmake +++ b/cpackEngineRPM.cmake @@ -75,24 +75,27 @@ SETA(CPACK_RPM_storage-engine_PACKAGE_PROVIDES "mariadb-columnstore-storage-engi # Boost is a source build in CentOS 6 so don't require it as a package SET(REDHAT_VERSION_NUMBER OFF) +SET(SUSE_VERSION_NUMBER OFF) IF (EXISTS "/etc/redhat-release") file (READ "/etc/redhat-release" REDHAT_VERSION) string(REGEX MATCH "release ([0-9]+)" CENTOS "${REDHAT_VERSION}") set(REDHAT_VERSION_NUMBER "${CMAKE_MATCH_1}") ENDIF () +IF (EXISTS "/etc/SuSE-release") + file (READ "/etc/SuSE-release" SUSE_VERSION) + string(REGEX MATCH "VERSION = ([0-9]+)" SUSE "${SUSE_VERSION}") + set(SUSE_VERSION_NUMBER "${CMAKE_MATCH_1}") +ENDIF () if (${REDHAT_VERSION_NUMBER} EQUAL 6) SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "mariadb-columnstore-libs") # Disable auto require as this will also try to pull Boost via RPM SET(CPACK_RPM_PACKAGE_AUTOREQPROV " no") +elseif (${SUSE_VERSION_NUMBER} EQUAL 12) + SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost-devel >= 1.54.0" "mariadb-columnstore-libs") else () - if (${REDHAT_VERSION_NUMBER} EQUAL 7) - SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost >= 1.53.0" "mariadb-columnstore-libs") - else () - SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost-devel" "mariadb-columnstore-libs") - endif() + SETA(CPACK_RPM_platform_PACKAGE_REQUIRES "expect" "boost >= 1.53.0" "mariadb-columnstore-libs") endif() - SETA(CPACK_RPM_storage-engine_PACKAGE_REQUIRES "mariadb-columnstore-libs") SET(CPACK_RPM_platform_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/build/postInstall_platform.sh) From 6e732f82e1379ca0a0c0a40714badca5d88fbd07 Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 27 Feb 2017 10:20:35 -0600 Subject: [PATCH 003/185] bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 879a53c2f..aecbb2a35 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 COLUMNSTORE_VERSION_PATCH=7 -COLUMNSTORE_VERSION_RELEASE=1 \ No newline at end of file +COLUMNSTORE_VERSION_RELEASE=2 From b4061cd4cc61a36efeea4812d48bfab1d2f48311 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 28 Feb 2017 10:46:13 -0600 Subject: [PATCH 004/185] MCOL-552 --- dbcon/mysql/mysql-Columnstore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbcon/mysql/mysql-Columnstore b/dbcon/mysql/mysql-Columnstore index 9ab4e1875..92bb76e8e 100755 --- a/dbcon/mysql/mysql-Columnstore +++ b/dbcon/mysql/mysql-Columnstore @@ -105,12 +105,12 @@ datadir_set= # lsb_functions="/lib/lsb/init-functions" if test -f $lsb_functions ; then - . $lsb_functions + . $lsb_functions >/dev/null 2>&1 else # Include non-LSB RedHat init functions to make systemctl redirect work init_functions="/etc/init.d/functions" if test -f $init_functions; then - . $init_functions + . $init_functions >/dev/null 2>&1 fi log_success_msg() { From a3517e59652ba320feca42a91578757b3a5070f0 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 7 Mar 2017 10:00:24 -0600 Subject: [PATCH 005/185] fix issue with ubuntu 14 non-root install --- oam/install_scripts/module_installer.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 7806c5e5e..445e8e3e9 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -48,11 +48,13 @@ done shift $shiftcnt if [ $installdir != "/usr/local/mariadb/columnstore" ]; then + export COLUMNSTORE_INSTALL_DIR=$installdir + export PATH=$COLUMNSTORE_INSTALL_DIR/bin:$COLUMNSTORE_INSTALL_DIR/mysql/bin:/bin:/usr/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$COLUMNSTORE_INSTALL_DIR/lib:$COLUMNSTORE_INSTALL_DIR/mysql/lib/mysql +else + export COLUMNSTORE_INSTALL_DIR=$installdir fi -export COLUMNSTORE_INSTALL_DIR=$installdir - cloud=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation Cloud` if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then cp $COLUMNSTORE_INSTALL_DIR/local/etc/*.pem $HOME/. > /dev/null 2>&1 From c725ead5d45f17b94a3dcad89fa3bf85fd23b2b4 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 7 Mar 2017 12:32:09 -0600 Subject: [PATCH 006/185] ubuntu 14 fix --- oam/install_scripts/post-install | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 5de1b981b..caf0946b2 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -214,7 +214,8 @@ else $SUDO $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml $SUDO chmod -R 777 /dev/shm - $SUDO chmod 777 /var/lock/subsys + $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 + $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore $SUDO chmod 777 /etc/fstab From 9985bb064714f6094bbd30e2486c57786564d870 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 25 Jan 2017 11:03:03 +0000 Subject: [PATCH 007/185] MCOL-533 fix the table_usage() procedure The old procedure could be wildly incorrect when there were multiple extents for a dictionary column. The new one uses tables so that columnstore_files doesn't get hammered too hard. They can't be temporary tables due to the reuse restriction on temporary tables. --- dbcon/mysql/columnstore_info.sql | 48 +++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/dbcon/mysql/columnstore_info.sql b/dbcon/mysql/columnstore_info.sql index be8c70167..d8a9cba4b 100644 --- a/dbcon/mysql/columnstore_info.sql +++ b/dbcon/mysql/columnstore_info.sql @@ -1,6 +1,8 @@ -CREATE DATABASE columnstore_info; +CREATE DATABASE IF NOT EXISTS columnstore_info; USE columnstore_info; +DROP FUNCTION IF EXISTS `format_filesize`; + DELIMITER // CREATE FUNCTION `format_filesize`(filesize FLOAT) RETURNS varchar(20) CHARSET utf8 DETERMINISTIC BEGIN @@ -21,6 +23,7 @@ END LOOP; END // +DROP PROCEDURE IF EXISTS `total_usage` // CREATE PROCEDURE total_usage () BEGIN @@ -29,26 +32,45 @@ BEGIN (SELECT format_filesize(sum(file_size)) TOTAL_DISK_USAGE FROM INFORMATION_SCHEMA.COLUMNSTORE_FILES) TOTAL_DISK_USAGE; END // +DROP PROCEDURE IF EXISTS `table_usage` // + CREATE PROCEDURE table_usage (IN t_schema char(64), IN t_name char(64)) BEGIN + DROP TABLE IF EXISTS columnstore_info.columnstore_columns; + DROP TABLE IF EXISTS columnstore_info.columnstore_files; + CREATE TABLE columnstore_info.columnstore_columns engine=myisam as (select * from information_schema.columnstore_columns); + ALTER TABLE columnstore_info.columnstore_columns ADD INDEX `object_id` (`object_id`); + ALTER TABLE columnstore_info.columnstore_columns ADD INDEX `dictionary_object_id` (`dictionary_object_id`); + CREATE TABLE columnstore_info.columnstore_files engine=myisam as (select * from information_schema.columnstore_files); + ALTER TABLE columnstore_info.columnstore_files ADD INDEX `object_id` (`object_id`); IF t_name IS NOT NULL THEN - SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(sum(cf.file_size)) DATA_DISK_USAGE, format_filesize(sum(IFNULL(ccf.file_size, 0))) DICT_DISK_USAGE, format_filesize(sum(cf.file_size) + sum(IFNULL(ccf.file_size, 0))) TOTAL_USAGE FROM INFORMATION_SCHEMA.COLUMNSTORE_COLUMNS cc -JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES cf ON cc.object_id = cf.object_id -LEFT JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES ccf ON cc.dictionary_object_id = ccf.object_id -WHERE table_name = t_name and (table_schema = t_schema or t_schema IS NULL) GROUP BY table_schema, table_name; +SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict +FROM +columnstore_info.columnstore_columns ics where table_name = t_name and (table_schema = t_schema or t_schema IS NULL) +group by table_schema, table_name +) q; ELSEIF t_schema IS NOT NULL THEN - SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(sum(cf.file_size)) DATA_DISK_USAGE, format_filesize(sum(IFNULL(ccf.file_size, 0))) DICT_DISK_USAGE, format_filesize(sum(cf.file_size) + sum(IFNULL(ccf.file_size, 0))) TOTAL_USAGE FROM INFORMATION_SCHEMA.COLUMNSTORE_COLUMNS cc -JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES cf ON cc.object_id = cf.object_id -LEFT JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES ccf ON cc.dictionary_object_id = ccf.object_id -WHERE table_schema = t_schema GROUP BY table_schema, table_name; +SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict +FROM +columnstore_info.columnstore_columns ics where table_schema = t_schema +group by table_schema, table_name +) q; ELSE - SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(sum(cf.file_size)) DATA_DISK_USAGE, format_filesize(sum(IFNULL(ccf.file_size, 0))) DICT_DISK_USAGE, format_filesize(sum(cf.file_size) + sum(IFNULL(ccf.file_size, 0))) TOTAL_USAGE FROM INFORMATION_SCHEMA.COLUMNSTORE_COLUMNS cc -JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES cf ON cc.object_id = cf.object_id -LEFT JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES ccf ON cc.dictionary_object_id = ccf.object_id -GROUP BY table_schema, table_name; +SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict +FROM +columnstore_info.columnstore_columns ics +group by table_schema, table_name +) q; END IF; + DROP TABLE IF EXISTS columnstore_info.columnstore_columns; + DROP TABLE IF EXISTS columnstore_info.columnstore_files; END // +DROP PROCEDURE IF EXISTS `compression_ratio` // + CREATE PROCEDURE compression_ratio() BEGIN SELECT CONCAT(((sum(compressed_data_size) / sum(data_size)) * 100), '%') COMPRESSION_RATIO FROM INFORMATION_SCHEMA.COLUMNSTORE_EXTENTS ce From e9c5d86c15367e8688a065485b3fa62eca17e3f4 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 25 Jan 2017 19:34:46 +0000 Subject: [PATCH 008/185] MCOL-533 Add lock to table_usage Calling from multiple connections simultaneously is bad. This adds a lock preventing that. --- dbcon/mysql/columnstore_info.sql | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dbcon/mysql/columnstore_info.sql b/dbcon/mysql/columnstore_info.sql index d8a9cba4b..63c669500 100644 --- a/dbcon/mysql/columnstore_info.sql +++ b/dbcon/mysql/columnstore_info.sql @@ -35,7 +35,15 @@ END // DROP PROCEDURE IF EXISTS `table_usage` // CREATE PROCEDURE table_usage (IN t_schema char(64), IN t_name char(64)) -BEGIN +`table_usage`: BEGIN + + DECLARE `locker` TINYINT UNSIGNED DEFAULT IS_USED_LOCK('table_usage'); + + IF `locker` IS NOT NULL THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error acuqiring table_usage lock'; + LEAVE `table_usage`; + END IF; + DO GET_LOCK('table_usage', 0); DROP TABLE IF EXISTS columnstore_info.columnstore_columns; DROP TABLE IF EXISTS columnstore_info.columnstore_files; CREATE TABLE columnstore_info.columnstore_columns engine=myisam as (select * from information_schema.columnstore_columns); @@ -67,6 +75,7 @@ group by table_schema, table_name END IF; DROP TABLE IF EXISTS columnstore_info.columnstore_columns; DROP TABLE IF EXISTS columnstore_info.columnstore_files; + DO RELEASE_LOCK('table_usage'); END // DROP PROCEDURE IF EXISTS `compression_ratio` // From 052f8d024919bf662c7a7be3ad3addc5a24a9f62 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 2 Mar 2017 17:56:32 +0000 Subject: [PATCH 009/185] MCOL-533 fix units for table_usage The fix for MCOL-533 accidentally removed units processing --- dbcon/mysql/columnstore_info.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dbcon/mysql/columnstore_info.sql b/dbcon/mysql/columnstore_info.sql index 63c669500..60dab7eac 100644 --- a/dbcon/mysql/columnstore_info.sql +++ b/dbcon/mysql/columnstore_info.sql @@ -40,7 +40,7 @@ CREATE PROCEDURE table_usage (IN t_schema char(64), IN t_name char(64)) DECLARE `locker` TINYINT UNSIGNED DEFAULT IS_USED_LOCK('table_usage'); IF `locker` IS NOT NULL THEN - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error acuqiring table_usage lock'; + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error acquiring table_usage lock'; LEAVE `table_usage`; END IF; DO GET_LOCK('table_usage', 0); @@ -52,21 +52,21 @@ CREATE PROCEDURE table_usage (IN t_schema char(64), IN t_name char(64)) CREATE TABLE columnstore_info.columnstore_files engine=myisam as (select * from information_schema.columnstore_files); ALTER TABLE columnstore_info.columnstore_files ADD INDEX `object_id` (`object_id`); IF t_name IS NOT NULL THEN -SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(data) as DATA_DISK_USAGE, format_filesize(dict) as DICT_DISK_USAGE, format_filesize(data + dict) as TOTAL_USAGE FROM ( SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict FROM columnstore_info.columnstore_columns ics where table_name = t_name and (table_schema = t_schema or t_schema IS NULL) group by table_schema, table_name ) q; ELSEIF t_schema IS NOT NULL THEN -SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(data) as DATA_DISK_USAGE, format_filesize(dict) as DICT_DISK_USAGE, format_filesize(data + dict) as TOTAL_USAGE FROM ( SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict FROM columnstore_info.columnstore_columns ics where table_schema = t_schema group by table_schema, table_name ) q; ELSE -SELECT TABLE_SCHEMA, TABLE_NAME, data as DATA_DISK_USAGE, dict as DICT_DISK_USAGE, data + dict as TOTAL_USAGE FROM ( +SELECT TABLE_SCHEMA, TABLE_NAME, format_filesize(data) as DATA_DISK_USAGE, format_filesize(dict) as DICT_DISK_USAGE, format_filesize(data + dict) as TOTAL_USAGE FROM ( SELECT TABLE_SCHEMA, TABLE_NAME, (SELECT sum(cf.file_size) as data FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema) as data, (SELECT sum(cf.file_size) as dict FROM columnstore_info.columnstore_columns cc JOIN columnstore_info.columnstore_files cf ON cc.dictionary_object_id = cf.object_id WHERE table_name = ics.table_name and table_schema = ics.table_schema GROUP BY table_schema, table_name) as dict FROM columnstore_info.columnstore_columns ics From b55c526a5d7e57dc25e626efc01313222355f147 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sun, 5 Mar 2017 09:58:20 +0000 Subject: [PATCH 010/185] MCOL-605 limit connections for I_S table I_S.COLUMNSTORE_FILES now caches a connection per dbroot instead of using a connection per file. --- dbcon/mysql/is_columnstore_files.cpp | 206 +++++++++++++++------------ 1 file changed, 115 insertions(+), 91 deletions(-) diff --git a/dbcon/mysql/is_columnstore_files.cpp b/dbcon/mysql/is_columnstore_files.cpp index 664f06e38..f70e646e0 100644 --- a/dbcon/mysql/is_columnstore_files.cpp +++ b/dbcon/mysql/is_columnstore_files.cpp @@ -49,49 +49,51 @@ ST_FIELD_INFO is_columnstore_files_fields[] = {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0} }; -static bool get_file_sizes(int db_root, const char *fileName, off_t *fileSize, off_t *compressedFileSize) +static bool get_file_sizes(messageqcpp::MessageQueueClient *msgQueueClient, const char *fileName, off_t *fileSize, off_t *compressedFileSize) { - oam::Oam oam_instance; - messageqcpp::MessageQueueClient *msgQueueClient; - std::ostringstream oss; messageqcpp::ByteStream bs; messageqcpp::ByteStream::byte rc; std::string errMsg; - int pmId = 0; - oam_instance.getDbrootPmConfig(db_root, pmId); - oss << "pm" << pmId << "_WriteEngineServer"; try { - msgQueueClient = new messageqcpp::MessageQueueClient(oss.str()); + bs << (messageqcpp::ByteStream::byte) WriteEngine::WE_SVR_GET_FILESIZE; + // header?? + bs << fileName; + msgQueueClient->write(bs); + // namespace?? + messageqcpp::SBS sbs; + sbs = msgQueueClient->read(); + if (sbs->length() == 0) + { + delete msgQueueClient; + return false; + } + *sbs >> rc; + *sbs >> errMsg; + *sbs >> *fileSize; + *sbs >> *compressedFileSize; + return true; } catch (...) { - delete msgQueueClient; return false; } - bs << (messageqcpp::ByteStream::byte) WriteEngine::WE_SVR_GET_FILESIZE; - // header?? - bs << fileName; - msgQueueClient->write(bs); - // namespace?? - messageqcpp::SBS sbs; - sbs = msgQueueClient->read(); - if (sbs->length() == 0) - { - delete msgQueueClient; - return false; - } - *sbs >> rc; - *sbs >> errMsg; - *sbs >> *fileSize; - *sbs >> *compressedFileSize; - delete msgQueueClient; - return true; } -static bool is_columnstore_files_get_entries(THD *thd, TABLE_LIST *tables, BRM::OID_t oid, std::vector &entries) +static void cleanup(std::map &clients) { + for(std::map::iterator itr = clients.begin(); itr != clients.end(); itr++) + { + delete itr->second; + } +} + + +static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) +{ + BRM::DBRM *emp = new BRM::DBRM(); + std::vector entries; CHARSET_INFO *cs = system_charset_info; TABLE *table = tables->table; @@ -103,64 +105,11 @@ static bool is_columnstore_files_get_entries(THD *thd, TABLE_LIST *tables, BRM:: off_t fileSize = 0; off_t compressedFileSize = 0; we_config.initConfigCache(); - - - std::vector::const_iterator iter = entries.begin(); - while ( iter != entries.end() ) //organize extents into files - { - // Don't include files more than once at different block offsets - if (iter->blockOffset > 0) - { - iter++; - continue; - } - table->field[0]->store(oid); - table->field[1]->store(iter->segmentNum); - table->field[2]->store(iter->partitionNum); - - WriteEngine::Convertor::oid2FileName(oid, oidDirName, dbDir, iter->partitionNum, iter->segmentNum); - std::stringstream DbRootName; - DbRootName << "DBRoot" << iter->dbRoot; - std::string DbRootPath = config->getConfig("SystemConfig", DbRootName.str()); - fileSize = compressedFileSize = 0; - snprintf(fullFileName, WriteEngine::FILE_NAME_SIZE, "%s/%s", DbRootPath.c_str(), oidDirName); - if (!get_file_sizes(iter->dbRoot, fullFileName, &fileSize, &compressedFileSize)) - { - return 1; - } - table->field[3]->store(fullFileName, strlen(fullFileName), cs); - - if (fileSize > 0) - { - table->field[4]->set_notnull(); - table->field[4]->store(fileSize); - if (compressedFileSize > 0) - { - table->field[5]->set_notnull(); - table->field[5]->store(compressedFileSize); - } - else - { - table->field[5]->set_null(); - } - } - else - { - table->field[4]->set_null(); - table->field[5]->set_null(); - } - - if (schema_table_store_record(thd, table)) - return 1; - iter++; - } - return 0; -} - -static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) -{ - BRM::DBRM *emp = new BRM::DBRM(); - std::vector entries; + std::map clients; + messageqcpp::MessageQueueClient *msgQueueClient; + oam::Oam oam_instance; + int pmId = 0; + std::ostringstream oss; if (!emp || !emp->isDBRMReady()) { @@ -176,14 +125,89 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) if (entries.size() == 0) continue; - if (is_columnstore_files_get_entries(thd, tables, oid, entries)) + std::vector::const_iterator iter = entries.begin(); + while ( iter != entries.end() ) //organize extents into files { - delete emp; - return 1; + // Don't include files more than once at different block offsets + if (iter->blockOffset > 0) + { + iter++; + continue; + } + table->field[0]->store(oid); + table->field[1]->store(iter->segmentNum); + table->field[2]->store(iter->partitionNum); + + WriteEngine::Convertor::oid2FileName(oid, oidDirName, dbDir, iter->partitionNum, iter->segmentNum); + std::stringstream DbRootName; + DbRootName << "DBRoot" << iter->dbRoot; + std::string DbRootPath = config->getConfig("SystemConfig", DbRootName.str()); + fileSize = compressedFileSize = 0; + snprintf(fullFileName, WriteEngine::FILE_NAME_SIZE, "%s/%s", DbRootPath.c_str(), oidDirName); + try + { + msgQueueClient = clients.at(iter->dbRoot); + } + catch (...) + { + msgQueueClient = NULL; + } + if (!msgQueueClient) + { + oam_instance.getDbrootPmConfig(iter->dbRoot, pmId); + oss << "pm" << pmId << "_WriteEngineServer"; + try + { + msgQueueClient = new messageqcpp::MessageQueueClient(oss.str()); + } + catch (...) + { + delete msgQueueClient; + cleanup(clients); + delete emp; + return 1; + } + clients[iter->dbRoot] = msgQueueClient; + } + + + if (!get_file_sizes(msgQueueClient, fullFileName, &fileSize, &compressedFileSize)) + { + cleanup(clients); + delete emp; + return 1; + } + table->field[3]->store(fullFileName, strlen(fullFileName), cs); + + if (fileSize > 0) + { + table->field[4]->set_notnull(); + table->field[4]->store(fileSize); + if (compressedFileSize > 0) + { + table->field[5]->set_notnull(); + table->field[5]->store(compressedFileSize); + } + else + { + table->field[5]->set_null(); + } + } + else + { + table->field[4]->set_null(); + table->field[5]->set_null(); + } + + if (schema_table_store_record(thd, table)) + { + cleanup(clients); + delete emp; + return 1; + } + iter++; } - } - delete emp; return 0; } From 82c383ac20d1d522ae2a18a0d0af071c82cb7976 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 17 Jan 2017 10:25:59 +0000 Subject: [PATCH 011/185] MCOL-353 Fix lag at end of cpimport The end of a cpimport adds a delay which is 1 second multiplied by the number of PMs. This in-turn is multipled up with the number of connections/threads causing a long delay when you have several PMs. The delay is not required as we already have a 20ms delay and we will re-enter the recv() if there is no data and we are still connected. --- writeengine/splitter/we_sdhandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/writeengine/splitter/we_sdhandler.cpp b/writeengine/splitter/we_sdhandler.cpp index fa3e0a876..6b9c148e3 100644 --- a/writeengine/splitter/we_sdhandler.cpp +++ b/writeengine/splitter/we_sdhandler.cpp @@ -994,7 +994,6 @@ void WESDHandler::onNakResponse(int PmId) { void WESDHandler::onEodResponse(int PmId) { if (getDebugLvl()) cout << "Received a EOD from " << PmId << endl; - fWeSplClients[PmId]->setRdSecTo(fPmCount); //Set Rd T/O to 1 sec if (fRef.fCmdArgs.getMode() == 0) { From cf98559f98f2dc0f4e294d8534452f2f604acbcd Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 09:56:43 -0600 Subject: [PATCH 012/185] update version --- VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index aecbb2a35..acfcdf7aa 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=7 -COLUMNSTORE_VERSION_RELEASE=2 +COLUMNSTORE_VERSION_PATCH=8 +COLUMNSTORE_VERSION_RELEASE=1 From 689022bb22fcea5641ee9347cdbe0a2652112173 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 10:23:44 -0600 Subject: [PATCH 013/185] MCOL-613 - add check for pm1 upgrade --- oamapps/postConfigure/postConfigure.cpp | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 1facf1a7c..13efa8940 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -52,6 +52,15 @@ #include #include +#include +#include +#include /* for strncpy */ +#include +#include +#include +#include +#include + #include #include #include "boost/filesystem/operations.hpp" @@ -423,6 +432,51 @@ int main(int argc, char *argv[]) exit(1); } + //check for local ip address as pm1 + ModuleConfig moduleconfig; + + try + { + oam.getSystemConfig("pm1", moduleconfig); + HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); + string PM1ipAdd = (*pt1).IPAddr; + + if ( PM1ipAdd != "127.0.0.1") + { + // now get the local ip address + int fd; + struct ifreq ifr; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + + /* I want to get an IPv4 IP address */ + ifr.ifr_addr.sa_family = AF_INET; + + /* I want IP address attached to "eth0" */ + strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1); + + ioctl(fd, SIOCGIFADDR, &ifr); + + close(fd); + + string localIPAddr = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); + + if ( PM1ipAdd != localIPAddr ) + // configure pm1 and local ip address don't match, error out + // can only install from pm1 + { + cout << endl; + cout << "ERROR: postConfigure install can only be done on the PM1" << endl; + cout << "designated node. The configured PM1 IP address doesn't match the local" << endl; + cout << "IP Address. exiting..." << endl; + exit(1); + } + } + } + catch(...) + {} + + // run my.cnf upgrade script if ( reuseConfig == "y" ) { From 37c0df25051aafb00b236b022fd3393b5b82593d Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 10:57:29 -0600 Subject: [PATCH 014/185] MCOL-604 and MCOL-607 - change the chmod from 777 to 755 --- oam/install_scripts/columnstore | 2 +- oam/install_scripts/post-install | 12 +++++------- procmon/main.cpp | 8 ++++---- procmon/processmonitor.cpp | 8 ++++---- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index 3a7777320..c236be011 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -81,7 +81,7 @@ start() { exit 0 fi - ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 + ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 755 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index caf0946b2..7027cc702 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -123,7 +123,7 @@ cd / test -d /var/log/mariadb || $SUDO mkdir /var/log/mariadb >/dev/null 2>&1 test -d /var/log/mariadb/columnstore || $SUDO mkdir /var/log/mariadb/columnstore >/dev/null 2>&1 -$SUDO chmod -R 777 /var/log/mariadb +$SUDO chmod -R 755 /var/log/mariadb test -d /var/log/mariadb/columnstore/archive || mkdir /var/log/mariadb/columnstore/archive >/dev/null 2>&1 test -d /var/log/mariadb/columnstore/corefiles || mkdir /var/log/mariadb/columnstore/corefiles >/dev/null 2>&1 @@ -206,24 +206,22 @@ fi #setup MariaDB Columnstore system logging if [ $user = "root" ]; then $installdir/bin/syslogSetup.sh install > /tmp/syslog_install.log 2>&1 - chmod 777 -R /dev/shm rm -f /etc/default/columnstore else - $SUDO chmod 777 /tmp + $SUDO chmod 755 /tmp $SUDO rm -fr /tmp/* > /dev/null 2>&1 $SUDO $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml - $SUDO chmod -R 777 /dev/shm + $SUDO chmod -R 755 /dev/shm $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 - $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 + $SUDO chmod 755 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore - $SUDO chmod 777 /etc/fstab + $SUDO chmod 755 /etc/fstab sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore sed -i -e s@prefix=/usr/local@prefix=$HOME@g $installdir/bin/* - fi #check if MariaDB Columnstore system logging was setup diff --git a/procmon/main.cpp b/procmon/main.cpp index aa210ef85..b521a9008 100644 --- a/procmon/main.cpp +++ b/procmon/main.cpp @@ -119,11 +119,11 @@ int main(int argc, char **argv) USER = p; // change permissions on /dev/shm - string cmd = "chmod 777 /dev/shm >/dev/null 2>&1"; if ( !rootUser) - cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; - - system(cmd.c_str()); + { + string cmd = "sudo chmod 755 /dev/shm >/dev/null 2>&1"; + system(cmd.c_str()); + } // get and set locale language string systemLang = "C"; diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index e474c69d5..dbcf4225c 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -950,11 +950,11 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO log.writeLog(__LINE__, "MSG RECEIVED: Start All process request..."); // change permissions on /dev/shm - string cmd = "chmod 755 /dev/shm >/dev/null 2>&1"; if ( !rootUser) - cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; - - system(cmd.c_str()); + { + cmd = "sudo chmod 755 /dev/shm >/dev/null 2>&1"; + system(cmd.c_str()); + } //start the mysql daemon try { From 5cbc67c9c66d6f0c12800e01f29ac8ca9bde4cce Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 11:42:15 -0600 Subject: [PATCH 015/185] MCOL-604 and MCOL-607, undone some precious changes per review --- oam/install_scripts/post-install | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 7027cc702..c1df3f2b3 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -208,15 +208,14 @@ if [ $user = "root" ]; then $installdir/bin/syslogSetup.sh install > /tmp/syslog_install.log 2>&1 rm -f /etc/default/columnstore else - $SUDO chmod 755 /tmp $SUDO rm -fr /tmp/* > /dev/null 2>&1 $SUDO $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml - $SUDO chmod -R 755 /dev/shm + $SUDO chmod -R 777 /dev/shm $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 - $SUDO chmod 755 /var/lock/subsys > /dev/null 2>&1 + $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore - $SUDO chmod 755 /etc/fstab + $SUDO chmod 644 /etc/fstab sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore From 620cdc4264ca2dd92fab0de7004504b345e5bed5 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 13:16:55 -0600 Subject: [PATCH 016/185] MCOL-604 and MCOL-607, undone some precious changes per review --- oam/install_scripts/columnstore | 5 ++++- oam/install_scripts/post-install | 2 +- procmon/main.cpp | 2 +- procmon/processmonitor.cpp | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index c236be011..cc0411915 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -81,7 +81,10 @@ start() { exit 0 fi - ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 755 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 + if [ "$user" == "root" ]; then + (mkdir -p /var/lock/subsys && touch /var/lock/subsys/columnstore) >/dev/null 2>&1 + else + ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index c1df3f2b3..f73536170 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -215,7 +215,7 @@ else $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore - $SUDO chmod 644 /etc/fstab + $SUDO chmod 666 /etc/fstab sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore diff --git a/procmon/main.cpp b/procmon/main.cpp index b521a9008..9e71c8b29 100644 --- a/procmon/main.cpp +++ b/procmon/main.cpp @@ -121,7 +121,7 @@ int main(int argc, char **argv) // change permissions on /dev/shm if ( !rootUser) { - string cmd = "sudo chmod 755 /dev/shm >/dev/null 2>&1"; + string cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; system(cmd.c_str()); } diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index dbcf4225c..551e124c5 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -952,7 +952,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO // change permissions on /dev/shm if ( !rootUser) { - cmd = "sudo chmod 755 /dev/shm >/dev/null 2>&1"; + cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; system(cmd.c_str()); } From 98d7434d972998fbfef411bf801cd3ad16383ccc Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 14:25:48 -0600 Subject: [PATCH 017/185] MCOL-604 and MCOL-607, undone some previous changes per review --- oam/install_scripts/post-install | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index f73536170..224ebee3f 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -123,7 +123,11 @@ cd / test -d /var/log/mariadb || $SUDO mkdir /var/log/mariadb >/dev/null 2>&1 test -d /var/log/mariadb/columnstore || $SUDO mkdir /var/log/mariadb/columnstore >/dev/null 2>&1 -$SUDO chmod -R 755 /var/log/mariadb + +if [ $user != "root" ]; then + $SUDO chmod -R 755 /var/log/mariadb >/dev/null 2>&1 + $SUDO chown -R $user:$user /var/log/mariadb >/dev/null 2>&1 +fi test -d /var/log/mariadb/columnstore/archive || mkdir /var/log/mariadb/columnstore/archive >/dev/null 2>&1 test -d /var/log/mariadb/columnstore/corefiles || mkdir /var/log/mariadb/columnstore/corefiles >/dev/null 2>&1 From f5274d1f9c621d5b9b561ae493cb91ba4f80a995 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 15:03:13 -0600 Subject: [PATCH 018/185] fix compile bug --- procmon/processmonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 551e124c5..093f92305 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -952,7 +952,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO // change permissions on /dev/shm if ( !rootUser) { - cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; + string cmd = "sudo chmod 777 /dev/shm >/dev/null 2>&1"; system(cmd.c_str()); } From 24d42b72bf7be19d8ed10ebc9335e7969b352dcd Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 8 Mar 2017 17:02:32 -0600 Subject: [PATCH 019/185] add missing fi --- oam/install_scripts/columnstore | 1 + 1 file changed, 1 insertion(+) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index cc0411915..a02001bc9 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -85,6 +85,7 @@ start() { (mkdir -p /var/lock/subsys && touch /var/lock/subsys/columnstore) >/dev/null 2>&1 else ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 + fi if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start From 3e3b776fe6bab7c03ff2c3b77112b734aac20bb4 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 9 Mar 2017 15:03:02 -0600 Subject: [PATCH 020/185] MCOL-613 - change to check for multiple ip address matches --- oamapps/postConfigure/postConfigure.cpp | 77 ++++++++++++++----------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 13efa8940..fe3e37c99 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -53,10 +53,12 @@ #include #include +#include +#include #include + #include /* for strncpy */ #include -#include #include #include #include @@ -438,40 +440,49 @@ int main(int argc, char *argv[]) try { oam.getSystemConfig("pm1", moduleconfig); - HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); - string PM1ipAdd = (*pt1).IPAddr; + if (moduleconfig.hostConfigList.size() > 0 ) + { + HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); + string PM1ipAdd = (*pt1).IPAddr; + //cout << PM1ipAdd << endl; - if ( PM1ipAdd != "127.0.0.1") - { - // now get the local ip address - int fd; - struct ifreq ifr; + if ( PM1ipAdd != "127.0.0.1" && PM1ipAdd != "0.0.0.0") + { + struct ifaddrs *ifap, *ifa; + struct sockaddr_in *sa; + char *addr; + bool found = false; - fd = socket(AF_INET, SOCK_DGRAM, 0); - - /* I want to get an IPv4 IP address */ - ifr.ifr_addr.sa_family = AF_INET; - - /* I want IP address attached to "eth0" */ - strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1); - - ioctl(fd, SIOCGIFADDR, &ifr); - - close(fd); - - string localIPAddr = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); - - if ( PM1ipAdd != localIPAddr ) - // configure pm1 and local ip address don't match, error out - // can only install from pm1 - { - cout << endl; - cout << "ERROR: postConfigure install can only be done on the PM1" << endl; - cout << "designated node. The configured PM1 IP address doesn't match the local" << endl; - cout << "IP Address. exiting..." << endl; - exit(1); - } - } + getifaddrs (&ifap); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family==AF_INET) { + sa = (struct sockaddr_in *) ifa->ifa_addr; + addr = inet_ntoa(sa->sin_addr); + //printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); + + if ( PM1ipAdd == addr ) + { + //match + found = true; + } + } + + if (found) + break; + } + + freeifaddrs(ifap); + + if (!found) + { + cout << endl; + cout << "ERROR: postConfigure install can only be done on the PM1" << endl; + cout << "designated node. The configured PM1 IP address doesn't match the local" << endl; + cout << "IP Address. exiting..." << endl; + exit(1); + } + } + } } catch(...) {} From dcbcdcf6ba87a97eae495893ce0be121272205fb Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 9 Mar 2017 16:51:52 -0600 Subject: [PATCH 021/185] MCOL-617, change how the debian packages is installed remotely --- oamapps/postConfigure/postConfigure.cpp | 79 +++++++------------------ procmgr/processmanager.cpp | 26 ++------ 2 files changed, 27 insertions(+), 78 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index fe3e37c99..a1aa13199 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -109,7 +109,7 @@ bool updateProcessConfig(int serverTypeInstall); bool uncommentCalpontXml( string entry); bool makeRClocal(string moduleType, string moduleName, int IserverTypeInstall); bool createDbrootDirs(string DBRootStorageType); -bool pkgCheck(); +bool pkgCheck(std::string columnstorePackage); bool storageSetup(bool amazonInstall); void setSystemName(); bool singleServerDBrootSetup(); @@ -126,7 +126,7 @@ typedef struct ModuleIP_struct std::string launchInstance(ModuleIP moduleip); -string calpontPackage1; +string columnstorePackage; //string calpontPackage2; //string calpontPackage3; //string mysqlPackage; @@ -2747,7 +2747,11 @@ int main(int argc, char *argv[]) break; } cout << "Invalid Package Type, please re-enter" << endl; - EEPackageType = "rpm"; + if ( rootUser ) + EEPackageType = "rpm"; + else + EEPackageType = "binary"; + if ( noPrompting ) exit(1); } @@ -2788,59 +2792,18 @@ int main(int argc, char *argv[]) //check if pkgs are located in $HOME directory string version = systemsoftware.Version + "-" + systemsoftware.Release; - if ( EEPackageType != "binary") { - string separator = "-"; - calpontPackage1 = "mariadb-columnstore-*" + separator + version; - //calpontPackage2 = "mariadb-columnstore-libs" + separator + version; - //calpontPackage3 = "mariadb-columnstore-enterprise" + separator + version; - //mysqlPackage = "mariadb-columnstore-storage-engine" + separator + version; - //mysqldPackage = "mariadb-columnstore-mysql" + separator + version; - - if( !pkgCheck() ) { - exit(1); - } - else - { - //mariadb - calpontPackage1 = "mariadb-columnstore-*" + separator + version; - - calpontPackage1 = HOME + "/" + calpontPackage1 + "*." + EEPackageType; - //calpontPackage2 = HOME + "/" + calpontPackage2 + "*." + EEPackageType; - //calpontPackage3 = HOME + "/" + calpontPackage3 + "*." + EEPackageType; - //mysqlPackage = HOME + "/" + mysqlPackage + "*." + EEPackageType; - //mysqldPackage = HOME + "/" + mysqldPackage + "*." + EEPackageType; - } - } + if ( EEPackageType == "rpm") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm.tar.gz"; else - { - // binary - //string fileName = installDir + "/bin/healthcheck"; - //ifstream file (fileName.c_str()); - //if (!file) // CE - calpontPackage1 = "mariadb-columnstore-" + version; - //else // EE - //calpontPackage1 = "mariadb-columnstore-ent-" + version; - //calpontPackage2 = "dummy"; - //calpontPackage3 = "dummy"; - //mysqlPackage = calpontPackage1; - //mysqldPackage = calpontPackage1; + if ( EEPackageType == "deb") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb.tar.gz"; + else + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm.tar.gz"; - if( !pkgCheck() ) - exit(1); - calpontPackage1 = HOME + "/" + calpontPackage1 + "*.bin.tar.gz"; - //calpontPackage2 = "dummy"; - //calpontPackage3 = "dummy"; - } - - //If ent pkg is not there, mark it as such - //{ - // glob_t gt; - // memset(>, 0, sizeof(gt)); - // if (glob(calpontPackage3.c_str(), 0, 0, >) != 0) - // calpontPackage3 = "dummy.rpm"; - // globfree(>); - //} + if( !pkgCheck(columnstorePackage) ) + exit(1); + if ( password.empty() ) { cout << endl; @@ -3050,7 +3013,7 @@ int main(int argc, char *argv[]) // checkRemoteMysqlPort(remoteModuleIP, remoteModuleName, USER, password, mysqlPort, sysConfig); cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + - remoteModuleIP + " " + password + " " + calpontPackage1 + " " + remoteModuleType + + remoteModuleIP + " " + password + " " + columnstorePackage + " " + remoteModuleType + " initial " + binservertype + " " + mysqlPort + " " + remote_installer_debug + " " + installDir + " " + debug_logfile; @@ -3120,7 +3083,7 @@ int main(int argc, char *argv[]) if ( pmwithum ) binservertype = "pmwithum"; cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + - " " + password + " " + calpontPackage1 + " " + remoteModuleType + " initial " + + " " + password + " " + columnstorePackage + " " + remoteModuleType + " initial " + binservertype + " " + mysqlPort + " " + remote_installer_debug + " " + installDir + " " + debug_logfile; @@ -4033,14 +3996,14 @@ bool createDbrootDirs(string DBRootStorageType) /* * pkgCheck */ -bool pkgCheck() +bool pkgCheck(string columnstorePackage) { while(true) { - string cmd = "ls " + HOME + " | grep " + calpontPackage1 + " > /tmp/calpontpkgs"; + string cmd = "ls " + columnstorePackage + " > /tmp/calpontpkgs"; system(cmd.c_str()); - string pkg = calpontPackage1; + string pkg = columnstorePackage; string fileName = "/tmp/calpontpkgs"; ifstream oldFile (fileName.c_str()); if (oldFile) { diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 8dedf915d..cf183bc89 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -4477,10 +4477,6 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } string calpontPackage; - string mysqlPackage; - string mysqldPackage; - string calpontPackage1; - string calpontPackage2; string systemID; string packageType = "rpm"; @@ -4513,23 +4509,13 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str homedir = p; } - if ( packageType != "binary") { - string separator = "-"; - if ( packageType == "deb" ) - separator = "_"; - //mariadb - calpontPackage = homedir + "/mariadb-columnstore*" + separator + systemsoftware.Version + "-" + systemsoftware.Release + "*." + packageType; - mysqlPackage = homedir + "/mariadb-columnstore-storage-engine" + separator + systemsoftware.Version + "-" + systemsoftware.Release + "*." + packageType; - mysqldPackage = homedir + "/mariadb-columnstore-mysql" + separator + systemsoftware.Version + "-" + systemsoftware.Release + "*." + packageType; - calpontPackage1 = homedir + "/mariadb-columnstore-libs" + separator + systemsoftware.Version + "-" + systemsoftware.Release + "*." + packageType; - calpontPackage2 = homedir + "/mariadb-columnstore-enterprise" + separator + systemsoftware.Version + "-" + systemsoftware.Release + "*." + packageType; - } + if ( packageType != "rpm") + calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.rpm.tar.gz"; else - { - calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.bin.tar.gz"; - mysqlPackage = calpontPackage; - mysqldPackage = calpontPackage; - } + if ( packageType != "deb") + calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.deb.tar.gz"; + else + calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.bin.tar.gz"; string cmd = "ls " + calpontPackage + " > /dev/null 2>&1"; int rtnCode = system(cmd.c_str()); From 2b974063ccf9ee3649568f125d176af13c11b494 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Mar 2017 14:39:25 -0600 Subject: [PATCH 022/185] MCOL-617 - removed a sleep and change lower timeouts --- oam/install_scripts/performance_installer.sh | 14 ++++++------- oam/install_scripts/user_installer.sh | 21 ++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/oam/install_scripts/performance_installer.sh b/oam/install_scripts/performance_installer.sh index 13eab4b4e..db5c155ce 100644 --- a/oam/install_scripts/performance_installer.sh +++ b/oam/install_scripts/performance_installer.sh @@ -63,7 +63,7 @@ if { $PKGTYPE == "rpm" } { # check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " send "ssh $USERNAME@$SERVER 'time'\n" -set timeout 60 +set timeout 20 expect { "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } @@ -82,15 +82,14 @@ expect { "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } -set timeout 30 +set timeout 10 expect { -re {[$#] } { } "sys" { } } send_user "\n" #BUG 5749 - SAS: didn't work on their system until I added the sleep 60 - -sleep 60 +#sleep 60 if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { # @@ -107,7 +106,8 @@ if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { } set timeout 120 expect { - "package dummy" { send_user "DONE" } + "error: --purge needs at least one package" { send_user "DONE" } + "dummy" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } @@ -154,7 +154,7 @@ if { $PASSWORD != "ssh" } { } set timeout 180 expect { - "package dummy" { send_user "DONE" } + "dummy" { send_user "DONE" } "directory" { send_user "ERROR\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } @@ -182,7 +182,7 @@ if { $INSTALLTYPE == "initial"} { } set timeout 180 expect { - "package dummy" { send_user "DONE" } + "dummy" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } diff --git a/oam/install_scripts/user_installer.sh b/oam/install_scripts/user_installer.sh index 4703d7841..46caac10a 100644 --- a/oam/install_scripts/user_installer.sh +++ b/oam/install_scripts/user_installer.sh @@ -67,15 +67,15 @@ if { $PKGTYPE == "rpm" } { # check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " send "ssh $USERNAME@$SERVER 'time'\n" -set timeout 60 +set timeout 20 expect { "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } "authenticity" { send "yes\n" - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } } "sys" { set PASSWORD "ssh" } "word: " { send "$PASSWORD\n" } @@ -86,14 +86,14 @@ expect { "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } -set timeout 30 +set timeout 10 expect { -re {[$#] } { } "sys" { } } send_user "\n" #BUG 5749 - SAS: didn't work on their system until I added the sleep 60 -sleep 60 +#sleep 60 if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { # @@ -110,7 +110,8 @@ if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { } set timeout 120 expect { - "package dummy" { send_user "DONE" } + "error: --purge needs at least one package" { send_user "DONE" } + "dummy" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } @@ -156,7 +157,7 @@ if { $PASSWORD != "ssh" } { } set timeout 120 expect { - "package dummy" { send_user "DONE" } + "dummy" { send_user "DONE" } "directory" { send_user "ERROR\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } @@ -184,7 +185,7 @@ if { $INSTALLTYPE == "initial"} { } set timeout 180 expect { - "package dummy" { send_user "DONE" } + "dummy" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } From 4d7082823274883cc1d165abcc6e9f5bbed58f23 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Mar 2017 14:40:18 -0600 Subject: [PATCH 023/185] change for ubuntu deb package install for addmodule --- procmgr/processmanager.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index cf183bc89..5ff672a85 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -4481,7 +4481,14 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str string systemID; string packageType = "rpm"; - oam.getSystemConfig("EEPackageType", packageType); + try + { + oam.getSystemConfig("EEPackageType", packageType); + } + catch (...) + { + log.writeLog(__LINE__, "addModule - ERROR: get EEPackageType", LOG_TYPE_ERROR); + } // // check for RPM package @@ -4509,11 +4516,11 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str homedir = p; } - if ( packageType != "rpm") + if ( packageType == "rpm") calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.rpm.tar.gz"; else - if ( packageType != "deb") - calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.deb.tar.gz"; + if ( packageType == "deb") + calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.deb.tar.gz"; else calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.bin.tar.gz"; From 3735c728dd815e50819c19f2eda45355e5e3b487 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Mar 2017 16:10:48 -0600 Subject: [PATCH 024/185] MCOL-617 - removed the mysqlrep call on removeModule --- procmgr/processmanager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 5ff672a85..c0d53c989 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -5361,6 +5361,7 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool } //validate the module list to be removed + listPT = devicenetworklist.begin(); for( ; listPT != devicenetworklist.end() ; listPT++) { int returnStatus = oam.validateModule((*listPT).DeviceName); @@ -5374,6 +5375,7 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool if(manualFlag) { //stopModules being removed with the REMOVE option, which will stop process + listPT = devicenetworklist.begin(); for( ; listPT != devicenetworklist.end() ; listPT++) { string moduleName = (*listPT).DeviceName; @@ -5676,9 +5678,6 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool rpw = "root"; } - log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); - processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); - return API_SUCCESS; } From 253cb5b01545ebc1997f4045913626e2509cc80b Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 13 Mar 2017 10:47:33 -0500 Subject: [PATCH 025/185] MCOL-617 - fix binary package type --- oamapps/postConfigure/postConfigure.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index a1aa13199..d95f0674b 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2750,7 +2750,7 @@ int main(int argc, char *argv[]) if ( rootUser ) EEPackageType = "rpm"; else - EEPackageType = "binary"; + EEPackageType = "binary"; if ( noPrompting ) exit(1); @@ -2793,16 +2793,16 @@ int main(int argc, char *argv[]) //check if pkgs are located in $HOME directory string version = systemsoftware.Version + "-" + systemsoftware.Release; if ( EEPackageType == "rpm") - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm.tar.gz"; + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm.tar.gz"; else - if ( EEPackageType == "deb") + if ( EEPackageType == "deb") columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb.tar.gz"; else - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm.tar.gz"; + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.bin.tar.gz"; - if( !pkgCheck(columnstorePackage) ) - exit(1); + if( !pkgCheck(columnstorePackage) ) + exit(1); if ( password.empty() ) { From f0ded2ea25821644b90fa33c9942e5df3d26c976 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 13 Mar 2017 16:59:35 -0500 Subject: [PATCH 026/185] MCOL-617 --- oamapps/postConfigure/postConfigure.cpp | 66 +++++++++++++------------ 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index d95f0674b..fa7ce14a9 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2676,7 +2676,42 @@ int main(int argc, char *argv[]) /* create a thread_data_t argument array */ thread_data_t thr_data[childmodulelist.size()]; + // determine package type + string EEPackageType; + + if (!rootUser) + EEPackageType = "binary"; + else + { + system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (oam.checkLogStatus("/tmp/columnstore.txt", "Name")) + EEPackageType = "rpm"; + else { + system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (oam.checkLogStatus("/tmp/columnstore.txt", "Status: install")) + EEPackageType = "deb"; + else + EEPackageType = "binary"; + } + } + + try { + sysConfig->setConfig(InstallSection, "EEPackageType", EEPackageType); + } + catch(...) + { + cout << "ERROR: Problem setting EEPackageType from the MariaDB ColumnStore System Configuration file" << endl; + exit(1); + } + + if ( !writeConfig(sysConfig) ) { + cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; + exit(1); + } + + string install = "y"; + if ( IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM || pmNumber > 1 ) { // @@ -2719,22 +2754,6 @@ int main(int argc, char *argv[]) cout << endl; - //Write out Updated System Configuration File - string EEPackageType; - if ( rootUser ) - { - try { - EEPackageType = sysConfig->getConfig(InstallSection, "EEPackageType"); - } - catch(...) - { - cout << "ERROR: Problem getting EEPackageType from the MariaDB ColumnStore System Configuration file" << endl; - exit(1); - } - } - else //nonroot, default to binary - EEPackageType = "binary"; - while(true) { prompt = "Enter the Package Type being installed to other servers [rpm,deb,binary] (" + EEPackageType + ") > "; pcommand = callReadline(prompt); @@ -2775,21 +2794,6 @@ int main(int argc, char *argv[]) } } - //Write out Updated System Configuration File - try { - sysConfig->setConfig(InstallSection, "EEPackageType", EEPackageType); - } - catch(...) - { - cout << "ERROR: Problem setting EEPackageType from the MariaDB ColumnStore System Configuration file" << endl; - exit(1); - } - - if ( !writeConfig(sysConfig) ) { - cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; - exit(1); - } - //check if pkgs are located in $HOME directory string version = systemsoftware.Version + "-" + systemsoftware.Release; if ( EEPackageType == "rpm") From 52e499dde4f17a62f540f51183a042060e36722f Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 13 Mar 2017 17:00:11 -0500 Subject: [PATCH 027/185] MCOL-617 --- oam/install_scripts/syslogSetup.sh | 17 ++++++----------- oamapps/mcsadmin/mcsadmin.cpp | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/oam/install_scripts/syslogSetup.sh b/oam/install_scripts/syslogSetup.sh index 5a409d356..87c1b0cf5 100755 --- a/oam/install_scripts/syslogSetup.sh +++ b/oam/install_scripts/syslogSetup.sh @@ -155,11 +155,6 @@ install() { checkSyslog if [ ! -z "$syslog_conf" ] ; then $installdir/bin/setConfig -d Installation SystemLogConfigFile ${syslog_conf} >/dev/null 2>&1 - if [ "$syslog_conf" != /etc/rsyslog.d/columnstore.conf ]; then - $SUDO rm -f ${syslog_conf}.columnstoreSave - $SUDO cp ${syslog_conf} ${syslog_conf}.columnstoreSave >/dev/null 2>&1 - $SUDO sed -i '/# MariaDB/,$d' ${syslog_conf}.columnstoreSave > /dev/null 2>&1 - fi egrep -qs 'MariaDB Columnstore Database Platform Logging' ${syslog_conf} if [ $? -ne 0 ]; then @@ -179,9 +174,9 @@ if [ ! -z "$syslog_conf" ] ; then $SUDO /etc/init.d/syslog restart > /dev/null 2>&1 $SUDO /etc/init.d/syslog-ng restart > /dev/null 2>&1 - systemctl restart rsyslog.service > /dev/null 2>&1 - systemctl restart syslog.service > /dev/null 2>&1 - systemctl restart syslog-ng.service > /dev/null 2>&1 + $SUDO systemctl restart rsyslog.service > /dev/null 2>&1 + $SUDO systemctl restart syslog.service > /dev/null 2>&1 + $SUDO systemctl restart syslog-ng.service > /dev/null 2>&1 fi @@ -215,9 +210,9 @@ if [ ! -z "$syslog_conf" ] ; then $SUDO /etc/init.d/syslog restart > /dev/null 2>&1 $SUDO /etc/init.d/syslog-ng restart > /dev/null 2>&1 - systemctl restart rsyslog.service > /dev/null 2>&1 - systemctl restart syslog.service > /dev/null 2>&1 - systemctl restart syslog-ng.service > /dev/null 2>&1 + $SUDO systemctl restart rsyslog.service > /dev/null 2>&1 + $SUDO systemctl restart syslog.service > /dev/null 2>&1 + $SUDO systemctl restart syslog-ng.service > /dev/null 2>&1 $installdir/bin/setConfig -d Installation SystemLogConfigFile "unassigned" diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index 1229f24c2..e90e31559 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -5011,7 +5011,7 @@ int processCommand(string* arguments) if (oam.checkLogStatus("/tmp/columnstore.txt", "Name")) system("cat /tmp/columnstore.txt"); else { - system("dpkg -s mariadb-columnstore > /tmp/columnstore.txt 2>&1"); + system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); if (oam.checkLogStatus("/tmp/columnstore.txt", "Status: install")) system("cat /tmp/columnstore.txt"); else { From 2d8797f2bd8fe394db9ce04d7ee6993950d9a16a Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 09:07:23 -0500 Subject: [PATCH 028/185] change snmpmanager to alarmmanager --- utils/loggingcpp/SubsystemIDs.txt | 2 +- utils/loggingcpp/messagelog.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/loggingcpp/SubsystemIDs.txt b/utils/loggingcpp/SubsystemIDs.txt index 409aee8ca..83e99097c 100644 --- a/utils/loggingcpp/SubsystemIDs.txt +++ b/utils/loggingcpp/SubsystemIDs.txt @@ -15,7 +15,7 @@ 08 - oamcpp 09 - servermonitor 10 - traphandler -11 - snmpmanager +11 - alarmmanager 12 - configcpp 13 - loggingcpp 14 - messageqcpp diff --git a/utils/loggingcpp/messagelog.cpp b/utils/loggingcpp/messagelog.cpp index d3185f6c3..0df5e6bdd 100644 --- a/utils/loggingcpp/messagelog.cpp +++ b/utils/loggingcpp/messagelog.cpp @@ -57,7 +57,7 @@ const vector SubsystemID = ba::list_of ("oamcpp") // id = 8 ("ServerMonitor") // id = 9 ("traphandler") // id = 10 - ("snmpmanager") // id = 11 + ("alarmmanager") // id = 11 ("configcpp") // id = 12 ("loggingcpp") // id = 13 ("messageqcpp") // id = 14 From e527d7963ae3e35f54899ab2103bb56cb7ce509f Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 09:11:40 -0500 Subject: [PATCH 029/185] remove the checkSystemRunning - system reported down msg --- oam/oamcpp/liboamcpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index 810aac264..14a8baa19 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -9677,7 +9677,7 @@ namespace oam return true; } } - writeLog("checkSystemRunning - system reported down", LOG_TYPE_DEBUG ); + //writeLog("checkSystemRunning - system reported down", LOG_TYPE_DEBUG ); return false; } From 9d82a3e0a3e457cd62fb73855899e6e91985766b Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 09:18:02 -0500 Subject: [PATCH 030/185] MCOL-617 - change permissions on alarm files, issue on non-root install with lock errors --- oamapps/alarmmanager/alarmmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oamapps/alarmmanager/alarmmanager.cpp b/oamapps/alarmmanager/alarmmanager.cpp index e03f38b4d..80ff571f5 100644 --- a/oamapps/alarmmanager/alarmmanager.cpp +++ b/oamapps/alarmmanager/alarmmanager.cpp @@ -111,7 +111,7 @@ void rewriteActiveLog (const AlarmList& alarmList) unlink (ACTIVE_ALARM_FILE.c_str()); // create new file - int fd = open(ACTIVE_ALARM_FILE.c_str(), O_RDWR|O_CREAT, 0664); + int fd = open(ACTIVE_ALARM_FILE.c_str(), O_RDWR|O_CREAT, 0777); // Aquire an exclusive lock if (flock(fd,LOCK_EX) == -1) { @@ -154,7 +154,7 @@ void logAlarm (const Alarm& calAlarm, const string& fileName) ml.logDebugMessage(msg); } - int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664); + int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0777); ofstream AlarmFile (fileName.c_str(), ios::app); // Aquire an exclusive lock From 7d8dd96de26a5823d48e485f151dc9275b4b895b Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 10:39:03 -0500 Subject: [PATCH 031/185] backed out previous change of permissions --- oamapps/alarmmanager/alarmmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oamapps/alarmmanager/alarmmanager.cpp b/oamapps/alarmmanager/alarmmanager.cpp index 80ff571f5..5d3990b2d 100644 --- a/oamapps/alarmmanager/alarmmanager.cpp +++ b/oamapps/alarmmanager/alarmmanager.cpp @@ -111,7 +111,7 @@ void rewriteActiveLog (const AlarmList& alarmList) unlink (ACTIVE_ALARM_FILE.c_str()); // create new file - int fd = open(ACTIVE_ALARM_FILE.c_str(), O_RDWR|O_CREAT, 0777); + int fd = open(ACTIVE_ALARM_FILE.c_str(), O_RDWR|O_CREAT, 0644); // Aquire an exclusive lock if (flock(fd,LOCK_EX) == -1) { @@ -154,7 +154,7 @@ void logAlarm (const Alarm& calAlarm, const string& fileName) ml.logDebugMessage(msg); } - int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0777); + int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0644); ofstream AlarmFile (fileName.c_str(), ios::app); // Aquire an exclusive lock From c34f9d8005b2a0155a3cd884cb953127ac5f42a8 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 10:41:32 -0500 Subject: [PATCH 032/185] change for nonroot log to be 777, problem with alarm locking file --- oam/install_scripts/post-install | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 224ebee3f..069098c49 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -125,7 +125,7 @@ test -d /var/log/mariadb || $SUDO mkdir /var/log/mariadb >/dev/null 2>&1 test -d /var/log/mariadb/columnstore || $SUDO mkdir /var/log/mariadb/columnstore >/dev/null 2>&1 if [ $user != "root" ]; then - $SUDO chmod -R 755 /var/log/mariadb >/dev/null 2>&1 + $SUDO chmod -R 777 /var/log/mariadb >/dev/null 2>&1 $SUDO chown -R $user:$user /var/log/mariadb >/dev/null 2>&1 fi @@ -151,7 +151,6 @@ mkdir -p $installdir/data/bulk/job >/dev/null 2>&1 mkdir -p $installdir/data/bulk/rollback >/dev/null 2>&1 mkdir -p $installdir/data/bulk/tmpjob >/dev/null 2>&1 rm -f $installdir/data/bulk/tmpjob/* >/dev/null 2>&1 -chmod -R 755 $installdir/data/bulk >/dev/null 2>&1 #create columnstore temp file directory mkdir -p /tmp/columnstore_tmp_files >/dev/null 2>&1 From f22327d66f5e8a6c24a124d0c59c1a1e13c0e5e9 Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 6 Feb 2017 12:05:49 -0600 Subject: [PATCH 033/185] MCOL-480 remove the annoying warning log message. This code path is normal and shouldn't log anyything. --- utils/messageqcpp/inetstreamsocket.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/utils/messageqcpp/inetstreamsocket.cpp b/utils/messageqcpp/inetstreamsocket.cpp index 57c863aea..bfbb291b3 100644 --- a/utils/messageqcpp/inetstreamsocket.cpp +++ b/utils/messageqcpp/inetstreamsocket.cpp @@ -436,15 +436,15 @@ const SBS InetStreamSocket::read(const struct ::timespec* timeout, bool* isTimeO uint8_t* msglenp = reinterpret_cast(&msglen); size_t mlread = 0; - bool myIsTimeOut = false; - if (readToMagic(msecs, &myIsTimeOut, stats) == false) //indicates a timeout or EOF + if (readToMagic(msecs, isTimeOut, stats) == false) //indicates a timeout or EOF { - if (!myIsTimeOut) - logIoError("InetStreamSocket::read: EOF during readToMagic", 0); - if (isTimeOut) - { - *isTimeOut = myIsTimeOut; - } + // MCOL-480 The connector calls with timeout in a loop so that + // it can check a killed flag. This means that for a long running query, + // the following fills the warning log. +// if (isTimeOut && *isTimeOut) +// { +// logIoError("InetStreamSocket::read: timeout during readToMagic", 0); +// } return SBS(new ByteStream(0)); } From eaa1374ea201632d0c1f5537783653fbe0f02a73 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 13:57:48 -0500 Subject: [PATCH 034/185] remove checkSystemRunning - system reported down log --- oam/oamcpp/liboamcpp.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index 14a8baa19..02c985b6a 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -9677,7 +9677,6 @@ namespace oam return true; } } - //writeLog("checkSystemRunning - system reported down", LOG_TYPE_DEBUG ); return false; } From 3b3b92c3d57a3af921891e8ee28d5490bbb4f0f8 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 14:11:02 -0500 Subject: [PATCH 035/185] removed sudo from sysylogSetup to fix issue with rsyslog.ver being root user --- oam/install_scripts/post-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 069098c49..657edf909 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -212,7 +212,7 @@ if [ $user = "root" ]; then rm -f /etc/default/columnstore else $SUDO rm -fr /tmp/* > /dev/null 2>&1 - $SUDO $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 + $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml $SUDO chmod -R 777 /dev/shm $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 From 5f828fbc3648cccb4d59aef17235595e8604e162 Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 6 Feb 2017 12:05:49 -0600 Subject: [PATCH 036/185] MCOL-480 remove the annoying warning log message. This code path is normal and shouldn't log anyything. --- utils/messageqcpp/inetstreamsocket.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/utils/messageqcpp/inetstreamsocket.cpp b/utils/messageqcpp/inetstreamsocket.cpp index 57c863aea..bfbb291b3 100644 --- a/utils/messageqcpp/inetstreamsocket.cpp +++ b/utils/messageqcpp/inetstreamsocket.cpp @@ -436,15 +436,15 @@ const SBS InetStreamSocket::read(const struct ::timespec* timeout, bool* isTimeO uint8_t* msglenp = reinterpret_cast(&msglen); size_t mlread = 0; - bool myIsTimeOut = false; - if (readToMagic(msecs, &myIsTimeOut, stats) == false) //indicates a timeout or EOF + if (readToMagic(msecs, isTimeOut, stats) == false) //indicates a timeout or EOF { - if (!myIsTimeOut) - logIoError("InetStreamSocket::read: EOF during readToMagic", 0); - if (isTimeOut) - { - *isTimeOut = myIsTimeOut; - } + // MCOL-480 The connector calls with timeout in a loop so that + // it can check a killed flag. This means that for a long running query, + // the following fills the warning log. +// if (isTimeOut && *isTimeOut) +// { +// logIoError("InetStreamSocket::read: timeout during readToMagic", 0); +// } return SBS(new ByteStream(0)); } From fa5b939a4d3f9cc34934d005f0bdd37b2a4d71d6 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Mar 2017 15:26:33 -0500 Subject: [PATCH 037/185] MCOL-617 - remove package type prompt --- oamapps/postConfigure/postConfigure.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index fa7ce14a9..98d637a6d 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2754,27 +2754,6 @@ int main(int argc, char *argv[]) cout << endl; - while(true) { - prompt = "Enter the Package Type being installed to other servers [rpm,deb,binary] (" + EEPackageType + ") > "; - pcommand = callReadline(prompt); - if (pcommand) { - if (strlen(pcommand) > 0) EEPackageType = pcommand; - callFree(pcommand); - } - - if ( EEPackageType == "rpm" || EEPackageType == "deb" || EEPackageType == "binary" ) { - break; - } - cout << "Invalid Package Type, please re-enter" << endl; - if ( rootUser ) - EEPackageType = "rpm"; - else - EEPackageType = "binary"; - - if ( noPrompting ) - exit(1); - } - if ( EEPackageType == "rpm" ) { cout << "Performing an MariaDB ColumnStore System install using RPM packages" << endl; From 4dab49a237e80ffd9fb6397e42e3ec367ffba496 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 15 Mar 2017 09:25:45 -0500 Subject: [PATCH 038/185] update version --- VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 879a53c2f..acfcdf7aa 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=7 -COLUMNSTORE_VERSION_RELEASE=1 \ No newline at end of file +COLUMNSTORE_VERSION_PATCH=8 +COLUMNSTORE_VERSION_RELEASE=1 From 442376cb50056c7fe3905f47e0da2998bc8a71ff Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 15 Mar 2017 09:27:24 -0500 Subject: [PATCH 039/185] backed out version change --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index acfcdf7aa..b406842f7 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=8 +COLUMNSTORE_VERSION_PATCH=7 COLUMNSTORE_VERSION_RELEASE=1 From 02ec99807914ef570d6d3206c095441ba03e65b5 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 16 Mar 2017 10:40:35 -0500 Subject: [PATCH 040/185] backed out change to check for non-root on permissions --- oam/install_scripts/columnstore | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index a02001bc9..26ec19a25 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -81,11 +81,7 @@ start() { exit 0 fi - if [ "$user" == "root" ]; then - (mkdir -p /var/lock/subsys && touch /var/lock/subsys/columnstore) >/dev/null 2>&1 - else - ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 - fi + ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start From 4392e4ed9f549fd55ebe1e46834f3f280625be12 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 16 Mar 2017 11:28:10 -0500 Subject: [PATCH 041/185] check in version from develop-1.0 --- oam/install_scripts/columnstore | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index a02001bc9..26ec19a25 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -81,11 +81,7 @@ start() { exit 0 fi - if [ "$user" == "root" ]; then - (mkdir -p /var/lock/subsys && touch /var/lock/subsys/columnstore) >/dev/null 2>&1 - else - ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 - fi + ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start From d4225d6635f2fbb24030209c5d845ad1a7600aab Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 16 Mar 2017 15:58:19 -0500 Subject: [PATCH 042/185] change code to determine package type --- oamapps/mcsadmin/mcsadmin.cpp | 14 +++++++------- oamapps/postConfigure/postConfigure.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index e90e31559..8e304cc6e 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -5007,13 +5007,13 @@ int processCommand(string* arguments) cout << endl; if ( rootUser) { - system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (oam.checkLogStatus("/tmp/columnstore.txt", "Name")) - system("cat /tmp/columnstore.txt"); - else { - system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (oam.checkLogStatus("/tmp/columnstore.txt", "Status: install")) - system("cat /tmp/columnstore.txt"); + int rtnCode = system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) + system("cat /tmp/columnstore.txt"); + else { + rtnCode = system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) + system("cat /tmp/columnstore.txt"); else { SystemSoftware systemsoftware; oam.getSystemSoftware(systemsoftware); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 98d637a6d..02151c772 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2683,12 +2683,12 @@ int main(int argc, char *argv[]) EEPackageType = "binary"; else { - system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (oam.checkLogStatus("/tmp/columnstore.txt", "Name")) + int rtnCode = system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) EEPackageType = "rpm"; else { - system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (oam.checkLogStatus("/tmp/columnstore.txt", "Status: install")) + rtnCode = system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) EEPackageType = "deb"; else EEPackageType = "binary"; From 8d8ee34b154e12a713d27eaa6037bff0f7282f70 Mon Sep 17 00:00:00 2001 From: David Hill Date: Fri, 17 Mar 2017 15:48:38 -0500 Subject: [PATCH 043/185] MCOL-616 - tweak the install scripts when checking for dummy package --- oam/install_scripts/performance_installer.sh | 11 +++++++---- oam/install_scripts/user_installer.sh | 13 ++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/oam/install_scripts/performance_installer.sh b/oam/install_scripts/performance_installer.sh index db5c155ce..302576455 100644 --- a/oam/install_scripts/performance_installer.sh +++ b/oam/install_scripts/performance_installer.sh @@ -106,8 +106,9 @@ if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { } set timeout 120 expect { - "error: --purge needs at least one package" { send_user "DONE" } - "dummy" { send_user "DONE" } + "error: --purge needs at least one package" { send_user "DONE" } + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } @@ -154,7 +155,8 @@ if { $PASSWORD != "ssh" } { } set timeout 180 expect { - "dummy" { send_user "DONE" } + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } "directory" { send_user "ERROR\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } @@ -182,7 +184,8 @@ if { $INSTALLTYPE == "initial"} { } set timeout 180 expect { - "dummy" { send_user "DONE" } + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } diff --git a/oam/install_scripts/user_installer.sh b/oam/install_scripts/user_installer.sh index 46caac10a..3cf649459 100644 --- a/oam/install_scripts/user_installer.sh +++ b/oam/install_scripts/user_installer.sh @@ -111,7 +111,8 @@ if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { set timeout 120 expect { "error: --purge needs at least one package" { send_user "DONE" } - "dummy" { send_user "DONE" } + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } @@ -157,11 +158,12 @@ if { $PASSWORD != "ssh" } { } set timeout 120 expect { - "dummy" { send_user "DONE" } - "directory" { send_user "ERROR\n" ; + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } + "directory" { send_user "ERROR\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } } send_user "\n" @@ -185,7 +187,8 @@ if { $INSTALLTYPE == "initial"} { } set timeout 180 expect { - "dummy" { send_user "DONE" } + "dummy is not installed" { send_user "DONE" } + "dummy which isn't installed" { send_user "DONE" } "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; send_user "\n*** Installation ERROR\n" ; exit 1 } From e1af0b190c28ed69e43e113dd98b34d09da56e62 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 17 Mar 2017 16:18:43 -0500 Subject: [PATCH 044/185] add code back to set /tmp to 777, installs failed in post-mysqld-install --- oam/install_scripts/post-install | 1 + 1 file changed, 1 insertion(+) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 657edf909..9df86005c 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -153,6 +153,7 @@ mkdir -p $installdir/data/bulk/tmpjob >/dev/null 2>&1 rm -f $installdir/data/bulk/tmpjob/* >/dev/null 2>&1 #create columnstore temp file directory +$SUDO chmod 777 /tmp mkdir -p /tmp/columnstore_tmp_files >/dev/null 2>&1 #setup core file directory and link From a5ef8d2132236ee07b802244dc269224b1bf0e06 Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 20 Mar 2017 16:51:21 -0500 Subject: [PATCH 045/185] fix amazon startup issue when ot using iam role --- oam/cloud/MCSInstanceCmds.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oam/cloud/MCSInstanceCmds.sh b/oam/cloud/MCSInstanceCmds.sh index 006cf9f17..8cea9c559 100755 --- a/oam/cloud/MCSInstanceCmds.sh +++ b/oam/cloud/MCSInstanceCmds.sh @@ -108,13 +108,13 @@ getRole() { iam=`curl -s http://169.254.169.254/latest/meta-data/ | grep iam` if [ -z "$iam" ]; then - exit 1; + return ""; fi Role=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/` if [ -z "$Role" ]; then - exit 1; + return ""; fi echo $Role From bf901e7d4aed790f51909e71a5668d4bce08cf20 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 21 Mar 2017 18:09:40 -0500 Subject: [PATCH 046/185] MCOL-630 - amazon install and failover issues fixed --- oam/cloud/MCSInstanceCmds.sh | 6 +++--- oam/install_scripts/module_installer.sh | 17 ++++++++++++----- oamapps/postConfigure/postConfigure.cpp | 8 ++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/oam/cloud/MCSInstanceCmds.sh b/oam/cloud/MCSInstanceCmds.sh index 8cea9c559..fbd0b6f31 100755 --- a/oam/cloud/MCSInstanceCmds.sh +++ b/oam/cloud/MCSInstanceCmds.sh @@ -149,15 +149,15 @@ getPrivateIP() { state=`aws ec2 describe-instances --instance-ids $instanceName --region $Region --output text --query 'Reservations[*].Instances[*].State.Name'` if [ "$state" != "running" ]; then # not running - if [ "$state" != "stopped" ]; then + if [ "$state" == "stopped" ]; then echo "stopped" exit 1 else - if [ "$state" != "terminated" ]; then + if [ "$state" == "terminated" ]; then echo "terminated" exit 1 else - if [ "$state" != "shutting-down" ]; then + if [ "$state" == "shutting-down" ]; then echo "terminated" exit 1 else diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 445e8e3e9..fcc80ab8c 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -57,15 +57,22 @@ fi cloud=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation Cloud` if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then - cp $COLUMNSTORE_INSTALL_DIR/local/etc/*.pem $HOME/. > /dev/null 2>&1 + cp $COLUMNSTORE_INSTALL_DIR/local/etc/credentials $HOME/.aws/. > /dev/null 2>&1 if [ $module = "pm" ]; then if test -f $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab ; then echo "Setup fstab on Module" - touch /etc/fstab - rm -f /etc/fstab.columnstoreSave - cp /etc/fstab /etc/fstab.columnstoreSave - cat $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab >> /etc/fstab + if [ $user = "root" ]; then + touch /etc/fstab + rm -f /etc/fstab.columnstoreSave + cp /etc/fstab /etc/fstab.columnstoreSave + cat $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab >> /etc/fstab + else + sudo touch /etc/fstab + sudo rm -f /etc/fstab.columnstoreSave + sudo cp /etc/fstab /etc/fstab.columnstoreSave + sudo cat $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab >> /etc/fstab + fi fi fi fi diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 02151c772..2d2115ce0 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -3683,6 +3683,14 @@ bool setOSFiles(string parentOAMModuleName, int serverTypeInstall) system(cmd.c_str()); } + //check and do the amazon credentials file + string fileName = HOME + "/.aws/credentials"; + ifstream oldFile (fileName.c_str()); + if (!oldFile) + return allfound; + + string cmd = "cp " + fileName + " " + installDir + "/local/etc/. > /dev/null 2>&1"; + system(cmd.c_str()); return allfound; } From 6841b261a319930af32640838b204822f9e5de23 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 22 Mar 2017 17:45:45 +0000 Subject: [PATCH 047/185] MCOL-605 Fix multi-node "Unkown error" The string stream which builds up the PM details wasn't cleared on each run. This moves the creation of the string stream up to where it is needed so a clean one is used each time. --- dbcon/mysql/is_columnstore_files.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/mysql/is_columnstore_files.cpp b/dbcon/mysql/is_columnstore_files.cpp index f70e646e0..2ddb393fe 100644 --- a/dbcon/mysql/is_columnstore_files.cpp +++ b/dbcon/mysql/is_columnstore_files.cpp @@ -109,7 +109,6 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) messageqcpp::MessageQueueClient *msgQueueClient; oam::Oam oam_instance; int pmId = 0; - std::ostringstream oss; if (!emp || !emp->isDBRMReady()) { @@ -155,6 +154,7 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) if (!msgQueueClient) { oam_instance.getDbrootPmConfig(iter->dbRoot, pmId); + std::ostringstream oss; oss << "pm" << pmId << "_WriteEngineServer"; try { From e185325d06975b5b291e465cfbd5ce59df009314 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 23 Mar 2017 10:21:40 -0500 Subject: [PATCH 048/185] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e9a325907..b30bf9338 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.0.7 -MariaDB ColumnStore 1.0.7 is the development version of MariaDB ColumnStore. +#MariaDB ColumnStore Storage/Execution engine 1.0.8 +MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.0.7 is an GA release. +#MariaDB ColumnStore 1.0.8 is an GA release. This is the first MariaDB ColumnStore release. #Building From c6c0bd026a3bbefd8002a1d9dc38e66e23304bd6 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 23 Mar 2017 10:22:29 -0500 Subject: [PATCH 049/185] Update README --- README | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README b/README index 9ebf34303..b5545b633 100644 --- a/README +++ b/README @@ -1,13 +1,12 @@ -This is MariaDB ColumnStore 1.0.6 -MariaDB ColumnStore 1.0.6 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.19 and adding entirely +This is MariaDB ColumnStore 1.0.8 +MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.0.6 is an GA release. This is the first MariaDB +MariaDB ColumnStore 1.0.8 is an GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. Additional features will be pushed in future releases. A few things to notice: -- Do not use alpha releases on production systems. - The building of the ColumnStore engine needs a special build environment. We're working on making it available for everyone to build. From 1e7f1319b9fda5129ae07f13ef1a6b95d048ee3c Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 27 Mar 2017 11:30:37 -0500 Subject: [PATCH 050/185] add columnstoreClusterTester --- .../columnstoreClusterTester.cpp | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 oamapps/postConfigure/columnstoreClusterTester.cpp diff --git a/oamapps/postConfigure/columnstoreClusterTester.cpp b/oamapps/postConfigure/columnstoreClusterTester.cpp new file mode 100644 index 000000000..bc47f7e37 --- /dev/null +++ b/oamapps/postConfigure/columnstoreClusterTester.cpp @@ -0,0 +1,243 @@ +/* Copyright (C) 2016 MariaDB Corporaton + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/****************************************************************************************** +* $Id: columnstoreClusterTester.cpp 64 2006-10-12 22:21:51Z dhill $ +* +* +******************************************************************************************/ +/** + * @file + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +using namespace std; + +typedef std::vector PrivateIPList; + +string password = "ssh"; +string OS = "centos7"; + +char* pcommand1 = 0; +string prompt1; + +int main(int argc, char *argv[]) +{ + + + for( int i = 1; i < argc; i++ ) + { + if( string("-h") == argv[i] || string("--help") == argv[i]) { + cout << endl; + cout << "This is the MariaDB Columnstore Cluster System Test tool." << endl; + cout << "It will run a set of test to check the checkup of the system." << endl; + cout << "This can be run prior to the install to make sure the servers/nodes" << endl; + cout << "are configured properly" << endl; + cout << "User will be prompted to provide the server/node IP Addresses, OS and password" << endl; + cout << "Items that are checked:" << endl; + cout << " Dependent packages installed" << endl; + cout << " OS version" << endl; + cout << " Firewall settings" << endl; + cout << " Locale settings" << endl; + cout << " Node ping test" << endl; + cout << " Node SSH test" << endl; + cout << " ColumnStore Port test" << endl << endl; + cout << "Usage: columnstoreClusterTester -h " << endl; + cout << " -h Help" << endl; + exit (0); + } + + cout << endl; + cout << "This is the MariaDB Columnstore Cluster System test tool." << endl; + + cout << endl; + string IPaddresses; + //get Elasitic UP list + prompt1 = "Enter List of IP Addresses of each server/node starting with the local first (x.x.x.x,y.y.y.y) > "; + pcommand1 = readline(prompt1.c_str()); + if (pcommand1) { + if (strlen(pcommand1) > 0) IPaddresses = pcommand1; + free(pcommand1); + pcommand1 = 0; + } + + //get Elastic IP to module assignments + if ( IPaddresses.empty ) + { + cout << "Error: no IP addresses where entered, exit..." << endl; + exit (1); + } + else + { + boost::char_separator sep(",:"); + boost::tokenizer< boost::char_separator > tokens(IPaddresses, sep); + for ( boost::tokenizer< boost::char_separator >::iterator it = tokens.begin(); + it != tokens.end(); + ++it) + { + PrivateIPList.push_back(*it); + } + } + + cout << endl; + //get OS + prompt1 = "Enter OS version (centos6, centos7, debian8, suse12, ubuntu16) > "; + pcommand1 = readline(prompt1.c_str()); + if (pcommand1) { + if (strlen(pcommand1) > 0) OS = pcommand1; + free(pcommand1); + pcommand1 = 0; + } + + //get Elastic IP to module assignments + if ( OS.empty ) + { + cout << "Error: no OS Version was entered, exit..." << endl; + exit (1); + } + + cout << endl; + //get root password + prompt1 = "Enter User Password or 'ssh' if using SSH-KEYS, which is used to access other nodes > "; + pcommand1 = readline(prompt1.c_str()); + if (pcommand1) { + if (strlen(pcommand1) > 0) password = pcommand1; + free(pcommand1); + pcommand1 = 0; + } + + //get Elastic IP to module assignments + if ( password.empty ) + { + cout << "Error: no password or 'ssh' was entered, exit..." << endl; + exit (1); + } + + + + *********************************************************************************************** + + + string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "ERROR: failed update of root password on " + module << endl; + cleanupSystem(); + } + + + string cmd = installDir + "/bin/remote_scp_put.sh " + ipAddress + " " + AMIrootPassword + " " + x509Cert + " > /tmp/scp.log_" + instanceName; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) { + pass = true; + break; + } + + //assign um Instances + std::vector::iterator list = existinguminstance.begin(); + for (; list != existinguminstance.end() ; list++) + { + string module = "um" + oam.itoa(um); + + cout << "Assigning Instance for " + module; + + string instanceName = *list; + } + } + + +void setRootPassword() +{ + Oam oam; + + cout << endl << "--- Updating Root Password on all Instance(s) ---" << endl << endl; + + InstanceList::iterator list1 = uminstancelist.begin(); + for (; list1 != uminstancelist.end() ; list1++) + { + string instance = (*list1).instanceName; + string module = (*list1).moduleName; + + //get IP Address of um instance + string ipAddress = oam.getEC2InstanceIpAddress(instance); + + if (ipAddress == "stopped" || ipAddress == "terminated" ) { + cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl; + cleanupSystem(); + } + + string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "ERROR: failed update of root password on " + module << endl; + cleanupSystem(); + } + } + + InstanceList::iterator list2 = pminstancelist.begin(); + for (; list2 != pminstancelist.end() ; list2++) + { + string instance = (*list2).instanceName; + string module = (*list2).moduleName; + + if ( module == "pm1" ) { + string cmd = "/root/updatePassword.sh " + rootPassword + " > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "ERROR: failed update root of password on " + module << endl; + cleanupSystem(); + } + continue; + } + + //get IP Address of pm instance + string ipAddress = oam.getEC2InstanceIpAddress(instance); + + if (ipAddress == "stopped" || ipAddress == "terminated" ) { + cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl; + cleanupSystem(); + } + + string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "ERROR: failed update root of password on " + module << endl; + cleanupSystem(); + } + } +} From f9be0a823cf2e7c15cfc355ebab3d5932f58178d Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 27 Mar 2017 13:53:34 -0500 Subject: [PATCH 051/185] change to 1.0.9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index acfcdf7aa..b51c8091e 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=8 +COLUMNSTORE_VERSION_PATCH=9 COLUMNSTORE_VERSION_RELEASE=1 From bf49643377ebf564e886deae916d3f482f000ffc Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 27 Mar 2017 13:54:53 -0500 Subject: [PATCH 052/185] change to 1.0.9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index acfcdf7aa..b51c8091e 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=8 +COLUMNSTORE_VERSION_PATCH=9 COLUMNSTORE_VERSION_RELEASE=1 From f41c0f07d3bb0dcc8ca3c3cc89be82df1c158d75 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 28 Mar 2017 11:00:50 -0500 Subject: [PATCH 053/185] add columnstoreClusterTester - update --- .../columnstoreClusterTester.cpp | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester.cpp b/oamapps/postConfigure/columnstoreClusterTester.cpp index bc47f7e37..82a8f5c50 100644 --- a/oamapps/postConfigure/columnstoreClusterTester.cpp +++ b/oamapps/postConfigure/columnstoreClusterTester.cpp @@ -52,6 +52,7 @@ typedef std::vector PrivateIPList; string password = "ssh"; string OS = "centos7"; +string user = "root"; char* pcommand1 = 0; string prompt1; @@ -68,7 +69,8 @@ int main(int argc, char *argv[]) cout << "It will run a set of test to check the checkup of the system." << endl; cout << "This can be run prior to the install to make sure the servers/nodes" << endl; cout << "are configured properly" << endl; - cout << "User will be prompted to provide the server/node IP Addresses, OS and password" << endl; + cout << "User will be prompted to provide the server/node IP Addresses, OS" << endl; + cout << "Root/Non-root user install name, and password" << endl; cout << "Items that are checked:" << endl; cout << " Dependent packages installed" << endl; cout << " OS version" << endl; @@ -87,7 +89,7 @@ int main(int argc, char *argv[]) cout << endl; string IPaddresses; - //get Elasitic UP list + //get Ip Addresses prompt1 = "Enter List of IP Addresses of each server/node starting with the local first (x.x.x.x,y.y.y.y) > "; pcommand1 = readline(prompt1.c_str()); if (pcommand1) { @@ -96,7 +98,6 @@ int main(int argc, char *argv[]) pcommand1 = 0; } - //get Elastic IP to module assignments if ( IPaddresses.empty ) { cout << "Error: no IP addresses where entered, exit..." << endl; @@ -124,13 +125,28 @@ int main(int argc, char *argv[]) pcommand1 = 0; } - //get Elastic IP to module assignments if ( OS.empty ) { cout << "Error: no OS Version was entered, exit..." << endl; exit (1); } + cout << endl; + //get User + prompt1 = "Enter Install user (root or 'non-root user name') > "; + pcommand1 = readline(prompt1.c_str()); + if (pcommand1) { + if (strlen(pcommand1) > 0) user = pcommand1; + free(pcommand1); + pcommand1 = 0; + } + + if ( user.empty ) + { + cout << "Error: no User type was entered, exit..." << endl; + exit (1); + } + cout << endl; //get root password prompt1 = "Enter User Password or 'ssh' if using SSH-KEYS, which is used to access other nodes > "; @@ -215,24 +231,6 @@ void setRootPassword() string instance = (*list2).instanceName; string module = (*list2).moduleName; - if ( module == "pm1" ) { - string cmd = "/root/updatePassword.sh " + rootPassword + " > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "ERROR: failed update root of password on " + module << endl; - cleanupSystem(); - } - continue; - } - - //get IP Address of pm instance - string ipAddress = oam.getEC2InstanceIpAddress(instance); - - if (ipAddress == "stopped" || ipAddress == "terminated" ) { - cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl; - cleanupSystem(); - } - string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) != 0) { From b59e478b553af88d5bfab070a4b8d1ceb9763ee2 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 28 Mar 2017 14:24:35 -0500 Subject: [PATCH 054/185] mcs gluster tester --- oamapps/postConfigure/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/oamapps/postConfigure/CMakeLists.txt b/oamapps/postConfigure/CMakeLists.txt index 334c0b46a..095f24c5e 100644 --- a/oamapps/postConfigure/CMakeLists.txt +++ b/oamapps/postConfigure/CMakeLists.txt @@ -56,3 +56,14 @@ target_link_libraries(mycnfUpgrade ${ENGINE_LDFLAGS} readline ncurses ${ENGINE_ install(TARGETS mycnfUpgrade DESTINATION ${ENGINE_BINDIR} COMPONENT platform) +########### next target ############### + +set(columnstoreClusterTester_SRCS columnstoreClusterTester.cpp) + +add_executable(columnstoreClusterTester ${columnstoreClusterTester_SRCS}) + +target_link_libraries(columnstoreClusterTester ${ENGINE_LDFLAGS} readline ncurses ${SNMP_LIBRARIES} ${ENGINE_EXEC_LIBS}) + +install(TARGETS columnstoreClusterTester DESTINATION ${ENGINE_BINDIR} COMPONENT platform) + + From 267022e4c9c20255214c5e42ceff0588793b9e5e Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 28 Mar 2017 15:08:16 -0500 Subject: [PATCH 055/185] update to cluster tester --- oamapps/postConfigure/columnstoreClusterTester | Bin 0 -> 116587 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 oamapps/postConfigure/columnstoreClusterTester diff --git a/oamapps/postConfigure/columnstoreClusterTester b/oamapps/postConfigure/columnstoreClusterTester new file mode 100755 index 0000000000000000000000000000000000000000..8353dcb811b82e9fe43bf55f5f9e3d3ac2033976 GIT binary patch literal 116587 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

&COhj)3*#BJu6Ot-;3^iL3Ig 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 literal 0 HcmV?d00001 From 965a198eb65407886ac12d369b5745cb74c2873d Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 28 Mar 2017 16:10:43 -0500 Subject: [PATCH 056/185] update to cluster tester --- .../postConfigure/columnstoreClusterTester | Bin 116587 -> 120944 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester b/oamapps/postConfigure/columnstoreClusterTester index 8353dcb811b82e9fe43bf55f5f9e3d3ac2033976..24c70f676cf2c18e342c8929cff4e964b4b21ff9 100755 GIT binary patch literal 120944 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

&COhj)3*#BJu6Ot-;3^iL3Ig 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 From 055a6154c58a9b44fccf7d8cea4de8ed1912c6e2 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 28 Mar 2017 16:51:03 -0500 Subject: [PATCH 057/185] update to cluster tester --- .../postConfigure/columnstoreClusterTester | Bin 120944 -> 121130 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester b/oamapps/postConfigure/columnstoreClusterTester index 24c70f676cf2c18e342c8929cff4e964b4b21ff9..4c26fa247c80aeb07e2f4544055f316d36a6dcc6 100755 GIT binary patch literal 121130 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 Bl_dZG literal 120944 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 Date: Wed, 29 Mar 2017 11:43:15 -0500 Subject: [PATCH 058/185] update to cluster tester --- .../postConfigure/columnstoreClusterTester | Bin 121130 -> 133248 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester b/oamapps/postConfigure/columnstoreClusterTester index 4c26fa247c80aeb07e2f4544055f316d36a6dcc6..0dd69aad8c010dc8cf68084f55d9925af4386927 100755 GIT binary patch literal 133248 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 WG?g%ia&|#eRHm!io0TmI{(k_e0!Bgr literal 121130 zcmdqK30xJ``#(M?D4BY3E84GxrIiY}VP#!J@{(92TBa2sqEZS37p2TZf$~Na?R!!A zDL*ZrEUnB6F&E4h$+G;kNoqA$DrqxYjNkix&Y8J$hkH?r&-e9z{inv6=Q+=Lw)33l zEHigln4Efkhp@1YnmRgY=W1cNcdd2_jQm&A?n@_D9xg3GJ3@15PVEG(6HpO2U9t#Q zd1qYrt7^tIQqfUhIL?F)5|PlsC2oxC@e-{WS3^3ll;=NO>Q-LE&y$qKRnwfJoLK4_ zJyw=SkIfQz{a3|COZ&<*o%j1sl=AkUm?$WX>zRtsxEl2?Mm_3zs7I6{oS@`|@{6tvGOki9 zO&dHrciQlwgJ(}4I6F75xMW~S!tjB^hYl*r9~3X_CV$e7y>OC{Wcbkuh&uPi$rxby zu47+%@4Eiqo;-A8{ku`mow8xgRlR3#Kp8D};$+i=Y3I0HPA&4-Q=&>o*Lgd2iRuup z^}l_|`shyUE3T<=Ms|p}Sc}xc%f@sF>(agNy2tx#6Vqa}(yl2H$-T7ju3FC?+GD+^ zYqvN%l{&+;f{xBHqa&lkwZ1Me*P^uKtSINiE@7j)BxsAeg>S0U+#O=W<2!V5E$R>% zAD+~;TNJpD*21K}Q7PP6cT@ihx-52uFVSYXwDA6#)}imxtjW<@SY}^mII$DAA)?bISpjf$!pt<{xk$JT1r_j1<}m&1pvBT9N}ksWXDKwl)`G>$R2IbQ)OxL%;{Q`L36x?Y6q1f1zOFU2_p z=jAxBzod3qj<5`@~i#ttw0oN7kekHCitNT}QU8U|{Q&;2i25#0U zpbpoyIM*wf7sl*Hob?27Y{I!&-1+}`2ey{!ll6 z;(7q*Uq*qtw(uH;|8aK28ICgoXJ?#8;5-s%SDX%Q+6l+xy?685`JerM zSts9te&<{`wrB4Xcf33;Vcu)=%1)a(r}EmAt6$b*e~)`|_A%+xW?V8V>8kF(-8k>m zH?KY->7%jzuIhZj=VN=kd5m*$uUCd_zae|>_ZRM6a^s{@=b= zT(_n2xp#IXbUW%Y@3gmH+dgkx?+FW5K3(9uf5Hsz}6?>!3d!$>R8yBDZYvV_^7u|fsV_mb( zJ#G8cju(zS_vl+jO?c(YPiGG8de*&1K3LQ5oY%kUx%l>3GkdQ1Y{<66lD%_ACvW?< zcJkYq-z+=n)N#EA-!!15OH);c6TcbxOW8#Y2OfCkiGH_VTmJErk;OMY8@qPq&5IYF z{!Q$=j}F)wy=e4Q)(1#{-N{Iqq(xNPN#3775bx^GC* zia9UdUp4LR(jQ8nA2;Wl`m<6#+VWuEr~dqQ)iItcA55Hg!^I!8mFIu7-j)9Q zvdhn^-t(|?-;K3rJh6DuJ5e_-e(Wg6*}v|eJL2N}n~%td%sO}X2U9zit@_0=?wG1q z7u0|K;LMy=DId(c`G~Mt5l@DB_ReWuank8cAMEY^(eMeUb#V;7Y1jq-;cyi6IR9+q zksu{Eof8~ic2;owzJ%cT*FxaChv0Kt2)SEA&<_lu|Lzd@+7ZF^yd?zvv=I2$L+E*J z2>jPYAm>UkMgJi6Q784bhH+L(o4P z!rsS2$h|9sy}Lr-j}C!}A9W%0UmwEWM?&DA2!U@3q32B@8Mh^q&hpJ?xFBWIBW3 zGehX#F$Dko5b^(X2tI=#Gnm|qL*U;E!6z$(AG#lpd7{=$TfW%^j(*=>5H9fzZ%aJa zkUVZbigW+tH20J&0Y{2|H7zz)(wFXY2~4TN4?Ioc)4rGZt_uG$7MqmYtmF<*_#S;F zzIvymuT%IN6o2hkiNBf)T^tkpYg%9JD6K9<>a$FuwO57`@6cRoT|ZjkFFIfHZ~VX| zFvo|1z}{!crU=-KBprk4h9U z!crWkDEd+x|6(wt{tZe`L;u&%U;08%=R~RJWX0!(UXtFa^g-B&qY;6`_=!^f!P;9K zZ>#>2w!oz@^77dj=?Bf`hZOjyCwDBa4Ww^~mU0W;k$7WW_WMBP2e;G{%_@#FRU9^K zmh_Pd|2;Y$yf^)7{xm&aASx&ABhhP|Jlp{ZwDZ^_?i-vzi4 z@&BHrH}urPBtBNP7lt!&ymz|9NBtn_cPM;3+C54;R*Rh=^;BqW=K#g0S<)Nvc?{Z7 z^xvN)-jF*9`cThOKv-QE?KrN75T{aspH#pXMzRZ`uq02)Qc1#VI~hl|BvcN%}h! z{>EfU->B@Bt%m&;)$bxFNk2y_`XmGc`PaQG`D7~m6!dH2ohl9uzx}HEV}s%kHN-Ir zamYN7V9S$7t2nPaMrz_#^p8VN=0m4Vp8+RIxh`ez<%)hQ#yjSvOcf`S75;UMYi!3% z8~^)NJ2o`A1m!D={@*7B=RbF_#Mk^H=?%MHAEM$)_4o0L&t}zLQ7X<2`V&<@EmiG^ zbSjQdPnP_nRDL*G;diNaDYf~n6ahfH8jq8Hb1C|&2G}>{In&)JyxSgcv_o#MUuG;Zkh3CGR zh!fQx`zrk1$cK!>M&*Yn(D8U7mU$BMgl}8|eo^7wxC(pUmw2udcs!%xIocM_9pjb$ z2V8>A@XwzrPFyzs)T{V!-YV&nL@iBwPUVf#JrbX<@b@{DKX*!eohFYaHLg`}mUzSe zy_}Lh_6vz0C&{%-K|s4ol|JbH;u#L*MupzyN4knyWC@Qk18wPLp(-bcUYcbz7AyJK`}=7SME+4fN&fNZw>)mg zxJ;Zd4X%}b3uxloN4 znM!}7y)IIC`+A`Z1`hTY&DQQesyvX{(JuSEZt)Bz3=Mo%@{CTp%XDYnm zw~N%eph3+y3_U-HReXMve8QDse;q0PmS*!?w(4K@d38S{p4Iqb^vC_+M|*3Oy)a)K zzoK14yls(kjdsjd?P8yAf1&29nKpgSQgPyHmVDMo_S$u5FY>SXK;n_U#Bqrl@0P1| zrQwHn#k>xBs`gdgNZX|1&9znXf!g92-c8z7s`9fe#q+@!Dc3%aJ^yIw&jMS2IZwrv zQ_0Oy{L7J_slW3*$@vb2{~?}okJ2)2`vcp>IC5O8apZu=Z?H@4!%R|qlGJ>|KHqy+ zwQsDlx09mxD!hH3Tz|6E(>_nG9w6}rd!_zHyKEKuJG3Y@KS$Vz;}z)7@i%jUq<5#v?C37rCCV1(=_(GLw)yr>bP$mzZSi@!$^-WKUOL*B z{x4PYCAX401A#$4E)@^xR^r%#0Ao8=t9*rU633hoa@?%5jhh1u`pqsuhqNG$u|p*P zOyxJH!v7~(@=x345}2h5f18?LWqvR5Mjq&*_{1tcXjXCb94zf>wCz(3>?irx*yi(v z2n^a~pU+>4ya!ik)i%3cKU30cYJ4~JnTmcyJ_Txi^^MZ!1P~DKYH$h6aD{&diGp}d z;Rh=G9yK3}`ccyFP!J3lXHV%D_TIa)@>%sKga8AYC~LQh79mT|${j0uV^X?9joQBIMp9<;I{ zMuW(_?BYUDQ{phfp4_|{`6hH#{1>m~!E;Y5Dm@p5aB;LZLZv!{jw1JIj+Z zGr#cKYAw42LY`6@YC7&1-_ML}t7YU*yDBH!BO|r7WsJfhe&Pa8 zVe;JM_?!ZN4;Ze(zTHANZY1?YZ@abt{cU>A>>T7J8H{ZOnx&KZm22&VxK`b>mC=D7 z{^$0!5@7bOv8F-sxyUYs1%>(9IYmWrL*`@^(0C@+{Jgl~1z9t5GKzAq%gLCPKO4z9 zB{erTIXNK>=yYI3d>^dG`~9Qr8+*w=ij}~QeDFB2g^@~Bp)-fgYeqhr8=LWuQ=3fl zwtn{aA6J(`4}n0cw(fUAkk>A+g9kdTL%tEhoSR&=(bUPh-2aZL1&4J zV?rvC1C8uG~^h-)k8oX<#$h zR;WQNv-Cn^;4}Md+vDp*T0bN{!$@bLnfn{b=0_w(>j2Ph*|(LL^Gg<>fdA1kvr=Q!AV$iqGaHZz3rvvarw!HH$N8E=b#e=^}x`ws{2 z$i_yBVMS}V9Kw7zQ1LbvA%7?G0+3zz1m{}VeZkij)g;5wzoM1AC`In4X@@lq4#zy z3+teX**;YWT>1LrBM@(-b$e~Zp+5mkJV+io$f`xHgWHbD_#xACW@Hu5_GH-SlZ?j0 z8gFfBQ7tHxXaD&Qh#9_WEns(@=$D5-{su%t`|O>xc0?PgE98WxUGgK_(3rCsG1snJ zA@q8C<&A)*2wZdo%~?a|&C2q~g(BNMe&}J%JOZRym#=DB*xpM{V={HPow`*t9dy27 zoxvS^z_#3S5NRw}S(Q z&LE20Lqt8QYs=I&pTh}n8?#iy{=c920xVVgaDOA^*sM%WwxpdlgVG;s$$Y??Q<9Ti zFgq*H_DnTysF)5G|0?2KGI3laLIjmu6i!h{v)vODC&g~bC)}?PTcTT<$?8MX_;IB*=kx#0_w!aDV}Jt{NlpwoM6>M z5e0AxqFulv%uq}Mh~lh@29~s1%*Tzi>^|k@@dW`47R;>{CjLENV;BuGY#$mU%T(lV z^Drij2bn<~nnFfq47utL#U?~k{3Bn58*Z*yZY3HVBL((C3fp+v==w1;j zl0vF)EM5;1Qh%54;cFV$UH_qaL79ct>5!W!kS}6dtt|hCU0+E!NIU&g3);aqAw%td z;if|n)?OYvxTwQ;Xx&t?x*e1PTc z;o3GDFhG_$GYD0oy&N8jKemF}+qrFs3b5Vm|Mu3#Iy4s>E0(oytJM$I$blq5cP!<$ zk9cWC2@6gpb|)PJmd)29&-Cmw&Y;BM_{mvzNmj;; z!W``489(^q0GeJj6u*hXn3Ta^(aDEpcof3dY*>tU)#HZn*^F7qd?YOx78DoeWX#Pi z^b}{!R`kQN`Eonz#|;6`dAZa1cmqbrp)Nq4`i+4_UV8qp8MBLvW(i`*9-fgQM_THT zomJ$)Yhyz2%;Ky<{3tCOuMHRGK(eI8&+hPJx;cG9 zH@`^yByVU6Tx7B_GWbVv7DP35WjX4Z{=Y)qK z*k8?=PBN%DbOxTMB&%9fL;ZHp*mh1YvT!1A%yAKZ;8>D1Eq87lAERaS*O?jSk0j(U z*viQ&6sF-vMtS@}U-m4isfg(K*o^dyoH+%aYw;_j0=y5NUxC*;g=g%&lgT+IBVa`C|k>Eu+ zdFT;2gQw&1Ti#&x>*TZAkE8K$zFk;~CvbxUpTV{xWBC-f9T^(Wf!mR#dXn6Z9OaYQ zc4TOIw%d+e<VL-F-c0$Fyd8OBvV-UB?aL4!KH!u3c43OQ z4T|vA1|GK$9z9`vyReiQ$@0oTJ972EbkL4WdNI* z2FEUAY9%LS*+s=-NqUHmG^YKn1&BA@{5-Mp5x;P0)qcY)?U#zx`=K_WuwZObQU>=j z#-^r>PRfWM6pwGvi2KQtfgd_3E-nBZsU=OGoH#lqBW}<-qBJXuAPo=Rk1#g zto`>Q&^l|8VioyW{-f3d-cT6q# zz81XGfF3n@V1%I}Q#f=&-m?JUFnn$DsZyl$iEci1l`b1ms=b2nE zrd#kX3%B;5e02ieOqfHCZ@GZqB+Q}4S0munggM0css;QaVGb?6 zQUO0rnC|iw2>5Zr97=qd0)BunhY(+yfbSs8p~L4A@XdrdWcXqQyqGYD3ZGNJ*AeCr z;foS*Az=;;K25+^5$2HKYyJy}e$xnZDDX83cnV<-0lo$SPaw?H@2eB=1%#RMeai(r znlMwnuSURU5oU__RSP(tFjKp)RKTYbKALcWfKMjORPM_Z@UeuM!hLB1?n#)b+vgH+ z7s5>0zE}ZwAk0+la|-zPZGf4geNh7bkuX!UPZRJS!c57&<^!~UCt)YyMgf09xG&)b z0dFPD)a$Dg@MgkHxxVEBev>f1mJ9m@yqYjmudiCbFA`?T^_2?vX~Imkz5)S1PM9gy zmnq-}2s5?%(gb`5VWw1{OTaf1W-9f?3V1PLrcj?#z}FFG>hwhkxR5YYrcV>_RfL%; zea(N0_9x5~>1!156v9l6z6JqLAk5U~s}t}AgqiYu%LP1|@KC}v0zQi{Q-yU#jjMw;qESbyuAqnOgOFjFU;pJ0>QwYV2R`sxcd* z2t>K7%46;WJ%MOrb=>&d5*Mu5jLc` z6qvXco$;lbVPZ@H-QCPK_))dN3$VvPvJJlct)<1gj@~C(fcJ+}c(7(U0Rl3~`#vQoxT92Juo}ain@%fL$i2ya-K(WJj0o z#(gyIb?*dLe?4Y7C{n$D>DLmjyhRkcEANsOz@Fu#bFtD=IK-?}wKQfs3ianNMlT(R z;u(V+CzT7~j+gI>DF7y+!Eu*pn^gb;+U9}%vTc^w3l^yY*#RwmX%-5~KXp`mj_zOj zx?nH7Lqd9oo+3BiJIbeGY-7)++SFLGD@f3L(1$=YD7(Wb4}^43s`ndrRYA1=-LEYz zj+e`0VnyYZf|hma2vy%eBD7+6B`d-P^^-9Pk!tg*H398`VLZuL; zAh^mOM*{Wx`xc0f`;-+kSz#p7BCd`KugJRP(*M9xZDb_3yQ9=>cIJ@d6Dcfx?xL6gq>;(xZz#yPUrIOX_Vw})B0?<#y zyl{0QJy3dt8rt*+L<5W(@}5)EzaUGFXzMVj4FJY7f`i&g%o30Ph%)aNZtt6G_{Yuk zX`jZnqt&I2$w`znt3F`;_v0)I-iEQnDQ}_u|_{$*Gv#i3O z1;!%0pIFJ^DFVX3CRiU)1ds=Wdsrfe*L$#-(PJq55|q_ub}=lk5llvn z1gXB80u0Ls17i`s><80w{+U93mK1&jML>A26u$2rCuLK3XTR_RSXr&v!f@*V4d}y^mEvD*HCMj1T{^&KZZ+%IgO9x1*~}9?XZrK)&8apb8lAUUF4@#9Rm%VVAq|5?#NCzJ=bz26Uzq$b}Z$3&L%R z)PO)=qZA=PMV1qJGeVd=2@qLFB>&u$5Tuaws9r;5s)8DOjSEGAl%R*f1jozku`DU?gy}8SG2B`Q4Vb)nWx()$le*V`6Q;|;)!aC# z?FltG%IY@=cgfaF9ogh4?}qqtdp}Pd@SS_@fpB-lcQ>4k7)tg2+SExos%$t;Ko;w7y|j)*AEQxVrHb`#b|hEWp9=jDA0vs5u`T0cR9M z>g9^FeGcNg7|cX3b~#=?pbs2{upYvwSr<#s*Xw7nBCe+h1`i1{-S7k%iF(CpzCY1Q zs{hkALwgsa0PQ18>!lPZB@(8ILYnsbw-BHhI?7*QgR2K5#gi{5m-n0)v%B9q+HC#(K7ni*gqkX0IM|;nWZ=ru=My(n!o@(o@jrM zU#iR@Ho%-S$OTT2tSxr-6zuO(ig;quD7YEb_5NeYV`5Au84<%04UW*ei;|TBV9qYk zUsrNj93XdvP!sbSyFw3$0@h7~2BO0j53r}{Z77lfdN#;?!_l8*|60wRtJ-FcVIrSD zYZCSZVcd7VBS9)c=SS?}tVv<$EWvIRL#BBTT!E|3t2xA|oet-bpuCViLFZ)OF=8O` zb(p3V7y2qN+pgvun>!==oe(FpO+^FdRBQ4m=>{NG9)QaO1_vYV9;9#-iarnj)`|E- z+%0B-8F$eTCK`mAAnqm#on_pSubw0ja%hne_P$TWoxvSR&IwgT!b1!4-d$OsyD`G) zOI39uS4YvOSI~e3;2~O_VpSb|zo1KRbrQS51}>{dVOV#}%gI_7qZi7xOoOys>XvA4cfu^@7FZ<<(26CVH{tBEYu z`zR9y1DKdbWX+jUTLN@OCXtoc3T1TyL^5yaFAJU$SREroF`Nby4OJzr#q4`jf#hr{ zSfC1|9+raXqCkl|8kVWpyIwSuu~>aQrhqzj#`Z0BBtRWYiQK9bCqQI1k#8tU0z}pj zxlB-EBSauq3M31cv+&3y$(w-SE$sh>K9%F}YVNJq-ra%r6Ak+%t;L#qQ~|{WH2VTo zP;D=mt_q~~7FOd_L4mzSyeN=5>0bd*9xGIYvI8P<1J;wV0WK5~g~-Z8)+px?pmmKz zRw_yYL^721m%oIJGq$IE}}y|A2E^BV2{H--eJ^&TMM^$1=q>Ae}=taU*{Jzp3fEWJC*6OqK- zRkDqmis1yger3KV1N{kbRS{GJ->um}(YFHW&-Vc--N^UP?3OXmpgO8(CC)SMV1b$M z-(-7mb-7p1Wr3PvkflCZAmpZrO!Z&y5~==X2A5!rRIh>5$b-B$^WdwhI*~FDZl>;c zfCmFu(0aeudkVK!c@XL%<%KqF!Ug6=6nE>#RDxK*)l zMh%(ey8^=*e7TsxW6&ZmXg9Q<1gNr$$UTaZ0Fh}#ZWEMunLFh~ zvM`f{3EY@xN>@mB8hzJJ=^g^B`8cum7kce-qG6+?wdA37sz7qK6g;g8q&}8{+f{+o z-cnGa3Y@t!w^J+1Pm+1gkh`li=36Hk>m|U>0GY6-WXUj7EX47)uhFZ}`Now#3X!<=`jt&7MY?zb*hN^4H0v zi|S_NFSf6wdsEUi-68pjd1s@^kNQcv2Nb^xjm&f{QYZbyv_aKP4QoIt`iH&XCQ*RR zi~#a$6gD#eJ5^yZUAM4KR#;a6b}+GJc&>+66vp6r-$>j#DtfAXP=ILBkH;+8y=Xn3 zEXLJMy(01Q#48f7Ow3sKs;ft$+O3+*-KsaZ33C$oy_(q*1$=&5>o4d;LD)1y1PQJi z@jR7VL;qnb%4by43zmkwV~6xctA@N*6*Sw!KT{Pn*bBxQHSCTZqzaU$EymA?z3E&hlnmv z1=Y%4v*1z`h_@r)+oosu&l>*o0sis*`!7?z^sFc5Tp|Bt#jRE5Izkns+1=Xwxon|U znd@U!5Noeds|s3Wu79DxcbZhqH@8KoDEd`X1vS5)|2&6(s+;QYujnLp-qRFs&0df~ z-ftf;&5jZTo|sX>>@!f>R8RhID$bIDC*~Ycek5yG$=bdOb-hPjpORPVBf>$=u0H-u zI;K_V)~W)RJvseL6&P(SxN#P6iz;ZgTUCSt@dk#{TGsHyoGrATq^dQFzz&>Qj#On0 zEK?fyQ@A<{t_LM>?}pBKkz$PL&sr<634pJ=B%>pw(Vm#Igd*>JDqXSM-osX?f*O0l z1FE3fUa&|Nl-dhsse%G~!9^(W-4Ym8O*hk=NB9qIYT8KkXGt2WFPp{_Gg7GEO|j0j zv;O%LX;+%P;8RuLvKPFG0$;QgBs!&x@6}Y|J^Ukti%OmtJbFaiSF^^~{t%0`v&>hr zoc4lCSo2wXO;5}S!8ZY=fgvv$cw&Z&@@Ur1Qz1S>UFWImyT6NopthP4D_sVKcl=j6 zrPZF!MpYn#)RN?%Qw1_;ECqL=z;~ULCA>v}jTlupfSCgGRP_dX!6XzkRVlB^YMz*3 z!n(6qw3%MtfPZ{BGIC|osXW{5-N1xB)a`9@b3?T&B^VQ*E!@R6L) z>dzb%_*}2)HF{!;l3i`D(@ilewHN&SF_<0U@Aa~#CnjEK{Siw25$5|+b-^Fi_3{0} zZr?^+*Q~-`ogRS)U|gHcLB%x)E9_sv@oQpP=EL);rk!gxVVa?T&ijv)w)<5UmAMf< z$v|zhvEpMHEb?^*y`KW;Ts=}ewoo(NajL}0lE3gC8tYUe+v-06@QswJvel*QJu!oY zi9dY=6Cb7X9#HBusBvYGDF1-vx3K&sRZiKAtvFG>0_7A%<@FmWDpxg)Pti-WJTb9? zz6|uf^Hs2(%PT4`r%3NQ{e0FRt_laK>kxUR>eWg$?7PEF31pS|EBx!EPrcau_bpUS zlLE9M-=0-8stj&X_JVJ=f#FH}M9rqpeLZn!tdE<%ox#I=|0R7*oqX5rW*S_S$^LTmx9PgK-uym9Uw=g>54qP4O*Y?0WFQeWi z&QZPs05_&js!ia8UB4_#(;q}7DTUyg*y|ysGjNh_mYCR+uE?ZoH0gH0E=gBSy6vPJ zXVMXr{9ZBXx^@Iz1L;mN=?F@?+f2GXq}xQgKY)|^5tMW@Nw*4Z#-sE{M^wbNxtfM+ zH(p`;@Rd$!sCyL}na9G~6TuQiy->8q1y-w&uv>m~^oV$W1&F;7Kk`x^aT>}O%aU%- zOH@~&7D5tAe*>mNDWum&e2v={pmF;FvCss!b;Lp(ZtuqJ0anJBPi)k zGU?7CU4PP5nsfvu-LD@QaxWmAlXTf89YIOA#iW}`x@gj!ZPF2xbWfRd(@7Uax?Uz7 zK}omJq$?m@BCT_O1d3e4Zl>APAA8d zEhAk6={_*&2uiy1OuCmyw~2Jmm~;ds-O(o90@BryuFRw(DCzdTZ`k`L=~j_$s!2ys z($$-E?~-mg>4une1SQ?0Cfz5bTSmGgO*(>-Zk|c!BV7&Yb^#~-LQv9OWYYaiy8B4? znn_1c(w%0~wUDlwba$F`1SMTdgJEyiaL_Fw-PI-?K}q+qN!N#TrKC$T=?F@?=S{lf zNLNC-<4ih&lI|vx&Plog()|RSw3ncy%P{FqBi$_0y=~GFlyoCZxD;6{!=xi9>Fzb@(n#kbT}P9S zprp$;>86k_fpnh&C;dWD(v3CgW{@tHbSq3cf|Bkeldgbt{Yh78(h-z&zrJVKdmZVV zq{}wx2uivwCS4inqDgnQNk>r9J!R6}Lb@o@^)l%QO1gz6-9w~{BwZ75(q4j+?o!}N zM>Rg@ zP25)EGKm{$;yxj67IFPd+)m;Oi0fhE_7Yb@+<~_Zdw(OYlsKP>>)Z*rCB$t5E^eP_ z$~6sdpdrVYM4}-#u`!kdC%X4lTHN2GSWqvbOa^c^(LJNj2hDEz)3p@O1gr9g`0FDsFskfz@#H6={|eQ@QVnvQqs9iI)ajJrAa4(poDZzla8RI zyTzmv!B;@K{lH0k2}-)@CY=bhS)^+)=?F@?b4)rBxS6C|X3`OqbiGYF8O)?BHR&ds zbl+|=>=l8VM!Lx+9YM)&y-6p6*-g4wla8RId&s2g$zXPoF4CkUDCs;VU0>2AkggFp z=@){MF4d$vgLJW^TV>J_lyosB-7wPiCtbBkM^MuJS#Q`oigZrW%`)i-O1ckCIyXCN zH0fL>9YIO=tV!o0zec_f8*S>6LYz)qxQV-nxMt#-&AOKox1YGrOx)$fX_ULk#7!eE zlDL&7PGtWm;%a~s{zLYUU5BLMFo{-iJzGNo^G#ecam$FCY2x~K2W~lW=_YO#ajS?s z&&1UbS4Z3#CQc}_iMXSIGZbmq2t{t(Xn1`)D`t}DM-vz20B#m>Uzj*IaRtO}HgQXc zD6IVxEDRGaRIHAZA;%)`bP(<4RMGkB*6q!L+x=563R?H{PP240CCzz!XmuO*D zvkA8eO4 z-acPy(h-z&Q6}Bpq>CcI>rFa>l1^W5=%N`otlS4Z>J;w}=x?FeUAEpib={gwY}{;& zxOAyg3)2fRJCha=yC(Bpc;pd~`uI-j8omayG2#S4sjmYAygv`X7rzgMX@X6pC_M5M zgAK8g&81{>3fRQGwVJyk?g5+KRmX2*Yq=Nw!HZ|6yR0cv{DhHPY$v%ZJBqEY@f3w8 zc9BgVt;W1jd$o(G{ywU|TZ4fW)p_ys4_>{yr8;Z!Ia2aiO{>H!6-_UQA7wN>EoD9d_IwLj zv2T>@d2y6qiLII7BF2~^wyqW;UXvnLN)gXV5l>1Hk4m%dgQPwdNysViS0gTt@}Ie1 z7}VvTtTl|WNqUuXeP^TMt87GH9PR>Ll__oE#Zi7oNC_pOBm}pm7ljRhXT-}bz5%?W zS-z8Shu@><*eDY|@qNKNq1%VN!+x#i+sr#W{l?F2P2AT|P2xV|9UI%Xm3M3x-zMJi zX9d1m-Z3V8D|yEN^gYcx#*+AX`syQjcMox0dB=xUtHqDy7xPa1OumG74wmNeE{b>4 zd57Ij%{PU2J$c8Ur&mvMSB;wWm{Uu~7Hfk3h-mdu8TUA`Wa<+w-p(DCf?_=!KGdIQ zu{R=?h$rOz@w^{P2UnfYSmV^<_JN=UH+)=w9%w4+icf%yq1bT-%MIt_g4a)9s$)2; zPndcIo)Y%?cp84%ga>PQ&3%{t^x340=ye-;d?SBP79OMDnIsroe=E^=60^fy_9lL5 z);mV`qQUr{)9sK}9rs;|_x&r~-kt8U-OXteQ|jxg`E%F$wN7!V&s=~sb1x`=o>9%` z8LP(P_5DfifiAwqU$(!y+xykL4p*#OrQzTQ7=FHD4U1YD)%)M82pRNi_jd$6e!=5j zyXQQ2ScCih{l%!fT2|hQ%J|``tiMy$FCEq60ViJn?J)^8^&1dTS8R;<>wYA}pTzSO zciE`eTR`AB(Nv-Lq%{d+p`G`umWC^Q^HIfdlIAOtSFrgd-R=DY%@^&i?<`)}s_dlR z)jC4&wg#=uII3Mv`_U#%Z?Fx&=WPKB(FoCQ?{>BW9%dmGI_Okp%nd?#$Rk~iNkPis@&RzbK|-;B^WWO)Nkd0UjcBmMHKX+cQ)rYU(-0_7Rb z)Ztu$3tCHJfb+lsTAgjRV7x?wk5$H|n?n?Y(xbnV+bnvVA)Z;3hkKciv?07jT zNxb#rsBPBcUT4;gub0#aQIs(UKP1v{^3#5^;cEV^U+!N%{m- z7jOK%Dc>X72`;PnPWw~@79K-JEV>(Ar?NzMFRCZHa-Os7y)gX@G>S>)((qjX8BBUS z_=z-E8;<<}>aqN_w*1*s$lt4X0YiWLrLQW*6O`AuC`E`yu}dYg->CuDy{Ls9s<@XJ z8y5Ys9fL*jE;L%y)OD*{a5OvCrtPoTx^RbxP5lZ8!Fwrkv^FX`0xCDHtxVfrbwNwT zRi!rii7Ki1n0KL~Y1XTgutDkB!4=W*b7ly|^rqZm3WN|C@(dZ{Wk@na=^gdN{q z;*YlDxA75PWyG)dNhv0uha~=EJ3d?DU$Ns)m-u___#ZI%fd4!@p3j1)za76&;z!u= z$I^K8ly#IQ+5;F=mMu$8Ep-g&=1h)PHytvq&*?TLRH>+lL@% z`rJ}y;Zu@+E$Evbv=lgQn~R#Va4DJ1v)w@!-&RoW12~6Byf`8rB(!$CPB+9Ah^C2!32}w z3lb!?A~?n*c!LC8S`qNeEV7**BEkCr1C@NrB$!Wv`&tp?nFLcvkO5G<4m1wIMUVC`8>nnP&M%Sm?#?KzZmhtQr~N!Lbue)|H-L$#;peDsqCuv`mh z%f+%!T^EQiz67*a+HgiLoE)?bil?AIx#<6(x$t7B)>P|HJqsU^U1KEiclhy++w#ot zJb~t90JMbf!uw^tFxIQGtzTT_EuJISS?2S#4!pUK@y5w#st*2WH%gz0n(|8&HQXrF zpt61^aQLv(nU&Zd_;@+)jgLW`42&llpTQ_j;-X?c>FOgQf#o3>)=tJ#PyOQO#gCHC zmA^F*OH;m$_B7B)Mc7Uh>j>tWz4v!-vxNp#vEurmCCwT4mV0D+WaSV~SMMg;CgqK6cHFgAB1)+MzdUq9 zq$d(`gnlEBa@VHzDz?l0lSg~@Gm*XAQU0Q8NvEtsVpNpcV7btH! ziD1IB!jyITP^jXY%zlmSnm~SDL8>=x!VXy&>f$4!b3v_NjH=aG--|DdW<+uuqQ@KH z(Bjpx%1(+b+aKnMg4vPS3^M)0QJz~4Q6RaxYuSOY;?E@t0Us@i5%%Wmn$l*K4u7uv0I9d2mfhqz8Lpo!J1D$x*AF@4K|xnxjaw!|hE%+azQ2 zD=E4%8L`uG|FPte)W836;u<>(S8tM2KSsD*Y&q5^2}$~m6pPk85k-OfJ*kyPr*yoo z(Kiu(WqjN8efR0Z(bv@geVw87O;GyIlGoT}xKiI-5%mH3enhd*HxET^>nqw1{fLgN zTu3jXH_(I5@;Xl>+{5i@Y$^F;>savAe}O~fdW73Y^_>gY59`PFuNM7rVSl~1@Ys&2 zz6aqLOT1vKvA++G`%t@-oR$1m^*#z% zKE26DHRn`I{*>*vz3CODkKq5boqy*BWnZ&l-^zb0yfpTBM2SP}fe_`kDE=%@36hrwUy+fnL!X#NY`KHn<-9y|Xh zPyl}%3V(eBE7OU2sN`=9(H~XDQ+X;931_UxeBD*%GuoXo?@xL=gCsqFymMo-axA{# zf)yvHf_kT?pn$QT&du~+o&-XUJZ7%6*T;`|jQSf%UYTU!xKd!$4m~+O5tJkIjrlx4 z&nHb)G1$zH)TaS(yqp}hBq<7)9!rvXR3`WKCiMmoy(EdbJUYlzfOE(KnPaGEUYG2j zt?WIDR91T#@JxX?OSqt8g1vj#wPK_7a zRBT4;&o8C(#j~3ApkNb;DM_nmHTMX@z51<)yTEuCyeiM5OM18~k8YX3Jl+|j9h2?U zb=8>v_#*~Wpt;EL;V~?9SL}0?%k^X@F_URY>+h~SCnmLWI;JwbnclpeQC~TROpErUkQm~-I&GU!*60-;|-se zBDIc*iRKNiPKFG4;#p@j1gLFzJY+`K_anyfP>CRUEpV`3)DVH!UM<~XhM zdjzGUD$1OSK}{6%`Is2@cC4Vt;Ce7}lvm+jtQ$Ll&h71pyKvrdDU}rI!8g`i=-b!F zOlD2Nmp8G7o|CJgu>Qak(i^e5bHBXnFUaMT$!3*4o7C{-&%feYw!TD7ffL1)a14G; zUos_2(}yD(*+a8nrkIWCy;)C9z$&kgN#L~9n3vgSVq@^7-umSJbjTVy8GsnC(ecq5 zhzQJQ-MERyH4TLtedtYg>d!xp--);)vG;{K+HwqmLY;aSw=3bGSy5tk9(`>56KyA`h%>%=A!?b9z*Ch-N6ZdSq<=&$*^K?OIoD9n-$;} z(MsOEAk!a%UcSp1ivWhg-^>?2HxT|VU;R(wTTUhr-_0t}4<)|ktQqkwr_C^oQxknD zHmFNSJzVN!Q=!4NHskv!(8>7j&AZ_7EvGz)Z$rgeg<#rQrFF>J=SFz#AVONTx0cUX8#pr3Y=2-Uy+iPs(aP}M0WGuJY{ z4RYBCFPS`FV}&5`{lvq-`{O%Y_%k5B*Mf%`-xE&gKn(Gf9v}84c7gq_Q@eANhDm(*^Pywb_n*JDU`?j58hWZYI1@6*2&0{6E#6oKF;|2{&BcU$7b6z|X2 zEs<|SR9@QK?M;n|tk~+gBDM0|@gw&-%CEtogYZan)Sf55j9W1lv#QehQ5d)TU>irz zgu2Kgch~WA%i}~@G|KpW`INHon6QmW(OOF7nK8aC7`@DO$Dovv-#NKoLaRYZ2ZUrUj^C)jV&(-e2Rk^5dD` zq9)#RYN1@ASuv)a7}qP4dZ&2zLfZ-_A`vQhu7_Ej3NPxby5w@<&E!Gcy^1?Op&@531TanJ*Aj2%Og zfbYi`<)!nZwc;-YcepQXJm#EAMAL)pKW>QRju<^xWbs_C@Z2%_XZQK_uDDcmx>9Ju zhO`*l9oo@YPfz{9hb$FNMFnB#NW5kSTg&?p0byoc&%J(Mm);-X>!w?{e)aCB35W-X zaMWVHvqMiffba1mL>i%om_%2Vgt0YKy}zf7+~)DPtFFc(i9*g&fi_6!hfs*tkMtW< zd_hWO?-)#V(VoJdctw7UVa`!d?k{~40$;UV@zJcp%^XNd!P|7j_sIHmu87Sce=#v> z(kg2EGz3~A$j8T_{!ZzqTWq8I09MYZrZ^wnsNw{Xh9+}Vj0G28JxCPZ&*v<~2hr+V zfhX%yKl;h{qR_1rZqt-2zxzYDvSJh@2olch7#9Y=z51SerT*l{S1;qX(y9+F*snyL zab=^T>do%IF)0=kp`--9poi5qK5IMjD^D+X z)i|vBi$JlHN-Tu-OOj$`7UZXsS}pXRy9aWS3ID~=5^-+XHK-PaJM>w5B@yG#)cbz*tm@HKvR84Wot-DBFMyVJ@t{E&hmF`Bwv+vNqh!O!2v= zN2+%(KXI+^fM6hs_v-!FXw(m@bYoNF2auz!o3MYrPWK3c9il(_qi067E&mFg%f5BH zD>EY9XJ%;wv=A_y zJVg+yO_A}6Ftw_n(OosGar}Ut>Qf|2@(XlZ_LJEdwt zq~3!-+4ubZviA#4wKNeFMUg3(jYjG}(t%jPhz641fY^JNM8(o667?BTW$WDmsSy1a z-?=|eAQ@fSP9Gj{J!tI?nFKDWesKX!X3V!6Hcn{fSBn&ZV{*1dLD zxVz)!F_E4lh3PwVXfqjsMG;FQ!39n3LBl#dUsfpQaKiF@`cz3`|Hk@ z77R_r?^7sO@e%r`$_Lny$9O6lMLfRnj@R648^cqp&IwEPE{O7dgHGtK>V2Gh+_o|&J-BH$AoUKtpA5MHm>>qsVwi@y|~ zNKx&vL*J(;9s$MpitjuxQeb4tNa(W8gYQ)BU@y~az+QBprU%@wO7mdf$jy$MG(c|e zPezkhY;{zG(?6JJo7)v)1H;!5=z#vjzxAYg5hC$~bBdgz{b)`#lrP&K?)izs{#&9u z_4~8Xi7{v>wp{jkhR|teDBGXF)g-QG{NeR&bY~g3=JU!mR73AX2UZPxYADE<+Uip< zPfQfZQ5OI?9)qX;7~zUK6nP@}IJgt#HdQjS+;}_V2pd1%Hxa%%+oS1Av@Kdxe?TeJ zQ!3=$==lLNhHUD38)M76p$T2N&mTi9@04HC4T@AnEX;I5AOAb$w{<7Fj}sc1ub-bG zNhjJ!r%Tdbz?B^Eo_YsKc!rJeY!V{ysv_Rcpfofs{~`+BVE=MAhPX*+$)+7BU12L- zhf+PS+S+>TXPkh_dCd+z)@TAeurTIBYJ!SqjS*iChGZcOQ!YFW<@V^=ql#uYwPNwu z?FBd$jfOXC@sfEq(6If|s34Es_CpKXW4B=Pt_doyqbV=ZD(|P9(DIfXn!K=}^6ms< zY2W)`W7=2NhP>!QlXv@|VE#OX@{VHn$)Y@5kFd%;GMHTat_OplUUM7#x*_0krvG_q zRYc#Q@>WbY`OA`EmHCZSmmA3hP=94+qCbo zE1hP1Rz(cq$FN1Tj_r>pjj8=!Y*MPWpk* z$*`_P=F#wdwz5$-f<`)}pZ}S%+G;VFMH}!(R$V<*{0K8Gv3AXyAd2{jLe~g&5Ob^}Nv6TQs2yA&2M9orAV#;#6m#{S8xqPzkjvV(|dz6f$6i z{ib07_G5rh_Cs~rZ!!vLKdOYZztUzuthLz>F@MMYFE6v2duRW)%*9k9;u_NqtGOL% z?kQ~UL}<#Z@8)3rv=;6B1;)TucCMGnvIw=BR{7g`1*{6Ra}oGgx6wc20-A5#X$Q0C zG1FqJJwu?QwC5Vy0eg-KX;1ey?0Lc)XwNQaA85}D;MEf>eruxh9XvRBE-n71UQ=>v!s^D6WU_a8HvL7nbeloJ!PjqnmQ8lFf zH`(lmwKn^~_n`L6+54Kw8eWajZ@ZC8wtmqVyD|XKN{<0r+&U9&6s336wCIA+hYueCSinLz!4f1Vl8h} zAqxz9W+LjqTizr*lTUWx>Z(k}zix1Fuz{-Z@|71m9cgJs@Iq5>dVfs37ygDh?`pc2 z3^wR{ajUE$!!-Rw>V=8@%YufJ>g$y_(a;_Bs{g{v@2Khxpl(_d{QV~WpqBIK0DqoW zA^f@N6c~!f8bSP-%rQa9>I-UUaGmLv(Ei+4E=Vt;va&WRCQ^)m+Vbb86Hq6FKOZH( zHvBo5{=5o-ryTMqZUg-J9`%AhX9ybl^UQQ9PT4qWyTzZSF!-SU#QPi{;i04V7kE}p zj-2kQ*?22BPWWqLj04*<5Q;~$`ng2O&8BoVtyuY24&1^-#_8S2y~Ss^tCFL~c(2Bm zO*R6D^S+3i=o95f_57co73VtUK~zOutYe1xr+Tk51$EbBVQtfLwycmtoY<9^RVF;7 zXF>&Qm)wB-#$7%)wvmJ>RSWT4LHs@TQD&+gyI+rHeT;u6Q!;uHdXS+V-)E?tM7_}? z)A9FD7lRZ}ANXbs7KKQ%N2-wCC0rp;(W+G%fRcZmImP>@=<@Jr*|!CBr>Jti&6q z;$iSaOktqIcr;&X)v!)|g(}#z!3!4H6i7q55YJtiH^faQZ%{G|^-wV_3K}PHtH_;F zbv|^R7~^D*LkgKN*=aaiA4K)xf3jEpujB_tRG3Df5SZ@sB;!rnR0baQ3I6`8DpHNg`LW`i z6{QYzrbf_As2cdTN^DzitDvv_{v&R!DlpRdezCluh_{G`Mci9|6;*`!QmgFC`k!qj!r( zF&Ho9UyBcnkJC^M@lky|S}tgOboUQ@`kn=%(UVRvnmP2axki#kQ)3lMRS{h%clbmYuUf35_w@xbLoW4|1axiB3a10F5CKf_a( zF#I9+;yrSTX8y4nOFqQ!qOc~%9FVV&V1NwchpjD#b7D@BCpT}VQyVn6FlSD_CnqC2 zf6kn&yy=6AW?7I$*##Lh|6hCG0^e3~&slG0ML6sYMl zEwrR9uxWwy_dhddB;Ao@Cn4S6_xrwHh>z}n&YYP!bLPyMxudISMuPsK7-gxcsS$Jg z#N4@k(f*_er=oTw5nmHqJD7_0+R0QR8BO(X5P?i|AZ=&*!Wmn#^hG0=MSGWsBb%bh zXuLNX&)CUuj-{gOf!pb5h6+xLBU=-Z zaDOxpXiM})?IblMg9eEs<$W;N!nciy{=tEGFq1$nI})jkf^FNL+h^NHwon7+ED`I% z{juJV=qKSK8BV7~=V09KAgSRk3Dz2y}&;Ie0yGRbltr8V1K`` zm)OGYPYb)l7YzEF#F}u7T4Xo-0458;d&%S*F@*=M({v zdElBv$`%o5bzWv5IWLh8Nx8XRqz+3Cst&VJKjKOa#zUI3ra!S(=GTDG!j*1wg|V)k z1xg*kR;V!|U%pC^(nF2Ow!zl^kf0BVt~DW)*Pl$pGwBU!fqxO%DfB55Ufmy65KJHy zj>R+1JFpTEgTV}CKQNd^B?iKT_J%Xz%!XuCNO|$_KvbwQO7mH+3C4NOXjsct!E7g!~7+kXkckO{DozRhr4M1<} zqQPj2#N~Fa4a4HV>1JhWO5WUgW zgKGsGp&+?e<7y zFa<|F$L>wo8xn)|`Y=3kCP9t~K6WsAfnB{}PJ9-Iw#+$iFrAtQQ|%w@jm}%0NTf6K zqC=5rlKKz6F9WeTAe79cYWk8%xb*I!{qPn#2V?mWnHB!CDGCk4JKtGZs7}H%p^mW9|_0p z)ln%UnTo-2qMekB=Nq~m2w#S5q!~(pCP~Hf;+R#^vL4-lR81fVliNTNgP$_u^ST)3 zo?JGW%MNtdzTRFMe$n(CcyZMn(TT2@*OrLSr9QE#%d)i~CpE{$%!>&zonD_v^&(Gq z8Ut$ydWGgMsWR3W&D+R~`AbSZNIlaeiQ4D%?2nVQR`?atVSeT5J{penu~Jm);IUIO zY*-)5^vSkMzi+RJr68ets7C%bXG4wrFKb2kz6+W45<8xtGQwIx_WHgkR1b3nflWqp z5eDn6i2Y>}mqp{D7_x+6N^Ebc9l1%ep)7#jv)S@%;X#Zl0MfDW?x ziA_adxX-j>Yfv&pD+qk%F85y?oCC$i&~+GqXsWbV4rCIr*A%(|_AQ5at{&R>a$?76 zwi(vsXGWFgUKZUzgLaTyfxK$6p$dhP9GB=2#I8MmhDY&b!zG?)MfA(S)lVfl7G zKZ{2gkON8MG)Z{oY{Iv52JDwazUOmyel4VQMsB=aun9AW}XV5>`&NhQ_-Y7 z6Z6`#^JeM_szeob&?BD~~7m3Gy;mk^B@GOpuvavN?5qWh^m4M#;lDIp4vm zN9*-q)uZzrs(N((gH?~tcd+Uq6Oz|z3XPU5$;L($3fTpq3YeBGp)rQ36cJx2mqV>Y zs%P0Bk&~-mhgtS{r3I}H_vT6XJ6)SXT2Ph$z4{?=O+-TD)QxJpE)nb1&2&!iOS@>k zk6j*3H4nxkb8KuZ$ccZB-Gxc>{3T1W3#qK?96568i}Zz4p>#AEmid>`En$w1m&M&p$U?5CnumYvY5V$k5P|C81C}ks1j1X9JL>h@27okcinVZgn_~p2dO| zb8=1|RTr{kfrT6s=tmVoB4!+-ntBmpVRaUbN1{-alBX=~{{?j=@%;q4Mkf0tHUG3N zkR!lTiQP1cT8TIcbxVs z`-u%C`vYx3cgW+;Q;1(zN0&cpls|I#%QqDw>)_^o^`5BO-@)xP+NbS%QJ#HM%R))C zEmW-c9j&i5Tc2&eE`R4=yZpk|XX`+1)%I?G(kq*;sl1^-tQU=Iy5&i)WEp)*QF&A3 zkJjr5^Y3GREoVF9`d(8lYA2V!Tk}1w%F}$Bj%xXuZ-RPh`GW0j=QB#Ko8>2&X8B5d z(Boz2vns#9tET9}`5$@d^nIM}=JYL}P<)bkoIiRzjBvhDL%vSm&3M%hl-!+$eERM( zUG$x0y4><_?hm~ki!QG&hvkTuy%OL3eMPhFV*V}6?|x3D>vrMkr@Ts0UEXe%pJe?E zvpk#S$-?o6zS>V0egB^>v;HGoADinv%+!9#EBS4s{+d6@e7l)yy_KrB#&!OEEPp4< z@6mFY%EHI_W9#wH_FBbuH^TRNeC*`=-G*I{aDK1GIe(9lf0*yLFjc+t#;2H$VOzR; zMO(0|z0;4KW9%)rwqhf?Q>ZxI9vI9-hit^nm+?v-yM=Z#(}#x-y&;)ME9uLy9;W?S zxkxLvf)-ABgYg59sFcU+1+IvU7E^eG4yX^WA!KEe8Nq5sEzdco5#ks9Rc46x(9Un7skdWeL#rKp!J}8K>I-Jzlg6D z6ArqKa8UOo$iHQ5Y!ztzttbza-h(v)y63B7W4l1N{Rdu^1-kWXV`KKQpkGHi%H0OK z19S)IZqPlTdqMYt3JX3DbUJAD?WhN63up)ED$qXAKG0#%&7fOBw}Ng5-3Gb~bQkC- z=pNAhpnE~9(7yek)u5B^7#s6adqG!$()%Qnp!J}8(7qwi{h)pSiFzCfd7vGj)!#rn z=^k_hbPwnb(4p-p4|Fr=eo6+KsSSK2Hgg_6?7-)Hqbqw zdqDSt?ggzn8uk1p^bJ}K+5*}K+6OuWIt;oQbSvmC&>f(AKzD=g1>Fl;{VnwCF(@C@ z25kYY2kir01-b)t3+R5(?Ua5O@`G*z73jCUpe>-2?g1a@D$t#vL!hIeefOfhmB@GB z*jNu}^@C^^=zh>Wpp(7>I{@7SY99xAp!J~j51}2Pn?W~&Zv8I3S`G3aMSEellfDOi zfv(zxdQ5{JoJ3W2Gr0$JKd3kX^?Dlp4Y~(33A*(e=m~Ti z=ypo~KKMb0K=*;JdKT@N3>?%AIt1DRx@tG_6ArqWaL^IZ`X9jFKwCgZK_@*2Jx@V> zKyA?dpe>-2eu(-K4mw0Q=m_CBV7Y^E(A}V`aKL3hXdh_RRMhjw&=cqm&<@beIC`}e zbP|G*U7$lRLLbn}=9f?}(5;{&pxa(Szk}`o6&UZ;uR_nDTS2#j(uHE=<+{96xQ41+ zryTQvNn2bWs3IH(=EVLR#>QqV7Wub0zYu3L|F&+_1!GuLRy9{nzwo%D*H0Q27o2?V z?D=P(NdhQ;6aMXkkAO?aUW9)X|MnKaGr&iIqieDk@n401#rSUpPW%|k*^Aop0RHU( zK8w(%%BqcJ!J{fC1&(g1oFwb@5@3=Cm1Qp~=S}=8R$qEsSh4cY22SPU^jP*HIZK(p zJc}xQbTPk)_XDT;nsTlv!GAOJn{w^~z8i8dl(QGr=V{=(ir~KhzOxAaF7O>i@F`d< zZ#Qt#H(jpFJ6fe>eV{yvki1;kmk@K1MmDqgU-2a~(27SF`h>5tYExNL<@Al^%PQSN zM^#QoC;2KT`QW>VzYG6%Y5v_4^Irk}Nw8lj|D}of?*e}d_$B2PA8Ow* zP;?*oN(rJm_j;*|JJ|K&nX80m?w$5Ypcud6O3TL_=lORb{CErgC4Uy|H3hrML5_ zN*fAB<_4;X>VqFa?g;8}byjX$rG4p9S=|#%?R^(~^p29JDsU61w9BWu&>rd?9{<31 zAf|W}^-%Q#Q`sF3LDc6>;Ojw5@q~l#Ukmv9!8Zx9#YBA9gKs0Q&?S3OzBhr>_?}CsZ2wwEzA13D# z`K9FDj`Zn8h;-lVm4Jq<<8jE5dqQ=y~Gf*|NzKk-S?W zZ=^(dG|tFQlJGz8ki3sW-bLg~1C{QwVH(umt(@dPx(R8oL(W#n`5^fz_|j|2{FT$M zE^nx`ud47>R&TO=mF|s4G*x=bB1cuafxyc)R89vcoU3w+($ABfB)5%?HBfn1nDy@} z@bkSefGyxZ9sJ5p{?5@4WG9sVYm#?8=eU{46;3YRG~F)tY6}$wLOoAv+oUI?LI6XmaHI z2mKCVP4zIfic9dTPrPnu0Ljp_IkOD_92i{l&r(&1lUq9?+ z1Z%dP_*`)b>W#9lCR@FV=C(~0O{!nLWvkJv=;>^)!bU0o?Z|IqZFei>PnOP)h|FOW zWa6#J^E%lp@;71rso0|O7jJ75wY8~o*j4r_+JxZ)lgn>w^U+<9w-o&|vSMuPOEVzv zr9ycPq&sBJ>Tc(x@=HEgR7pGv)jWPZqxx?M;sR@`sPtvpMzaFJNH1 zcZ`k6C6e@m-P!SXHt7g!T}oez&uV-k4!cZCAW)Sz2Yl1<0;Y-hy1>_S0DPYS-!||i zr~p|nl$$Or_g3)jI{?0?!B>y9`grn4A9Us7_?up~ZE=c@<4GU%uLpAO1+Dl9j6&C~ z3^6PX7zCO$ewWf-0Qg`o*^Bb_;@>`7qZcp}8?XwmJa$S3&-c z$DQ&?Z+AidcHmNP-zbz{OmEabuOnYQzS8_GK37n_T>qe`aDy}lh!jEzO{ zncDCO!3(a{eD!u*1COm1kU63;hIZ(Ib8XI#>I_=C0MHuU^aXue& zB+{o@=ZK|>Pu`zm%@#hoFQ4T)#ee3lE?2^O*j4@omxYh_x~!L6)-PQc`Y@4CeoB{0 zg)AsvFH*KDP=7}HSoyK8Nhg+9yFAE58NhqYF(}|9%PT&t3O?>^(E6KPFT2FsE(J-J z6RjEIJavE4hsyB_zZXo~;}WYcz^6N0u(cl&vn<2on)MmftwOv|X8l`*7%MBk-4YL! zTmNdgwp3VKEb&4GSifpnk6KjoL(Mbhnp_Dv3(7z35|>%nHoK9lTLR{WW;J}mG~_JXnT=J!RGo%k`Tw>srh8ZkhF><@!klR-WIotS2q;yrqOGS!1q$u{OD^uPsK| z*47o`0oNU6|FS|{Sz%qXLi}5W^`lntlZp=l`J6TH=~l7n2`2LaB*oER}M_RwQQ2hKT>#czJ>MFzbXQv(a*fR0ViPoI~@ydzT ze+0yzPPG0#AU038ZVrfBrdyv5h`Xm-kGF_-rxSkdN!BAR;wvGd(GmTr`JE&EdFx3wWC>FYg=Dv z7GJfkU-`wKYzz3+XIQWL#Vu!8Z#9XZoDl@_?K2l6@7A+Uez{3}=4|VCO=9cW)-RjH z*Uq+pyl}SXAt2{i_ce)coMYY6B))f!^~*-_*%_32-we;=jpCgd)+3E#%S>xWqxi~9 z>syWDftl8m4dVLha~^3BPgGkEHi%cMtsM>GPu1498pM`a)_*pLugtP;YY-32vi{j8 z9-Dp6MxS_Rw)M7GZ26G&8?X4vhpbmKWm=ZQBwry}*{TI==m#GSR)ug?>Y)mlG0PyD>r+H;=RUu*3?Pke5^b@x*7`8xZK zrQ(S?Yui%sN}cuPrQ%O@))$wGD;HRIpDTX0;N(XZi^mrp2Wf9CJPw>UE;)&UI|2o0CahCYq3D%Zb;=0M!rdi^)$=18o;=ak& zAFIXpCtJ_Y7C)P8JvCdrJ=uDAwzzVNb?3SYMtk9-Cr)eztgViuJkK z;`dXmf0`}+ajNysEOEnB>kqTU*QQ#(o+Z9B)p~iBcy6lo!&%~2Q>`aviN8#>9-1Yt znP$B?Q+#Qf^}Ctko@v${GsRD)y@j2EKb>mbHdB1&H0zd`;-=HAtuw_pPP49^DZYD} zb>&R)!fDpVnc}t6tnbbcTTZtgm?3UG-MV{**m1h`pEJbMr(0j0Ax2NPMrMdNPq%(? zj`+N7y;d#mu&rNIi-&FN?>fp;exu7Z;=xpo%vm%=^ex42x}3i(Un4doBH zT)PVSO&rECb&2&Wmxx+lDTBi;zp_lc>Y61dl9CCPCr`(WVtvUa?$;B_S=J?@%^DDW zNP*0{nbzy&;%b-mN`<)3W&NN+{LWQ=Plb4_to+Uj@nYGun=8b7WexcJRC)PWx%hRt z$~V`$$-9{ z{r@f(Uv!nfRE}w`{DpFHW!bbx%EcXJ7vS^$vhusj#rASAA8MvUZBo^-pT%^u&1K!; z5>N7!D(8#8{rQ^){-%MyY2a@f_?rg)rh)&@HE_RIDxm6CMU&rFbo4$&Wg`CQ^Z8Y$ z`V_?H#LaX!r+b%$b&{kye@}_@E&Tn1VJ#oIX#ZoF<>JIL}!IRD7&T<#mr^7VOn&DZlgmG0iBsNic)K>zAdar@ds6&7QdhM(zm?0etOvMlC0k<&acZ!{#nVZ;`Zxub-o_ftKfE( z(u>A*zG2pT2kX6qf6Y1}9H9*?Z#^&7rF zhVR7&ul#f@-(N3$^3zFtKb`%{Df*tNK6~lr^bazQrvvhO>wnba)2(G*d5?9!yxcRr zl41i%Uc*OuCB^Q!yp}Fg6i+MVgM5c@oftWrsphleLxX9<}0rq zDX*j&AO5(y*Y&PvMII@+@SK|I|M27B-ATm{Cz+rmJQ|VLKECgddl~t^lWb-`Y1VEb z+d(tal}y(#UB`42(;JxH#`GShk1_o*(_b-to9PjkEB#DkI)mv#rp-)OGF`)T9n(!r zZ(w>G(|edc#`MQbf5r4|rbqlem(O$t(}hf%nXY8IhUq${o0#6f^fspVFnx^akD308 z>Dx??z+qpyrZJttbRpAbrYo7QVY-g#CZ;zqy^ZNTOdn(VW2V1i`Zm)eKFQ@XoxyY= z(`KeCnaaxI4;@mbYguFC61#d?TlXxxuBN_bfnDqNEO0NZoo`on;srh}c;TPK=hn>< zq9(mz0I#|O&7>6V)1UALy=W>aYT|gKV~wvNFgFuk%XfH%LCxyHSby(aya%s_?)t)b zSy)Z)hB)LYnn|e?e$klYCWJJ+cPva9_*1e!BWmOqziRM(HGE!!8>A)ZjeMde+80`r z!fTI0eZ9!5?;tdy-+K{KZvd1sLg7>@yg|v(pD&FdBMGCDAy?KiJP?aO2;OZ*e`;hU zRDrAU>c$#+1rA>MB-Q%9|C|B|oL_SgH?<(`+ z4$q_+u;pFukM?^Sp)-v6`7>o+nUvxDXUn_XA2WXwlHP_7)#Yz3^GfEe4D4lxt>+Q# zuO$=ywBaAk89Kk7SB80F+0F`}>4Dm=^H0ZTx>n*J%_%y+o~PV1DHZ1jmMN?~ z5@=4)`Sm=|A6GegIYHN7^J#h+*l3Q?_j;b$omBa^D->6N8~(WB z(DRxuU+35Dzrx6`=gA!@m0!=Rl%HY;GygTfNGEz;*Kvi|01%gs7t~#D-qiP>#fSX- zHqRF}=l2>0Q^grIz23;*!~UyBJ!Tel8+A#F>UP0Z&XK&aDJ`- z5ssrqIDhwPI;Wzx^HyxbJ+)uw-_Psk{ii8Qqwg-}U&gJt2Z{OltIzUD_Uf}#{+lP~ z=g#$?Mt9;vet!De30;paRQbKS!zEhSf6oE0#6KOE>9}$FGL>K38E4PhkG_8eA1FrE z`E^|B=KMzS1^IuAyi}6TU(a!A{Q>5G!^rRD{9eva-v`aV?ED*iei#49_I3F>&f2`3 z^~d@3_|Waqc4&buzy7=0!?J{3?J9q@yvzO3`87St$S*i979A?TTN@UO(D^i-Y~*+I z`$gQHD!;C$u7S>{?@t07VY>ZZ&hO>?+l&mh&d8L^oJw*VxXwSvz*VhO9!feM|8&{; zto>a6Or3!fja!H9=jY%05yiQiD{wjz@4!FZ9BtR+ABvUVw^`+Xq$6KyuHH_x_+2?_ zS6}8WNGyl9(DQVDVmWG}=U*pYA-0xz^C9`UTv%fGsABjLLeGQwnaVNK>-o)zPZE0G za^gn{Js&yoqlBJkoH%B3_Ww@&7@_9{Cw{EZ{@#gK3hl?8_;K*pzI;f2E*Dio``!G+ za#)x4r%wC?_{U;$CJXKVocvRS_G?ajs?h$*iBHS!gF5jOh4wE_e7ewn!-=1SgOA~S zNPaHItgOd*eqy;eMdQ#V!&p8aeWvNI3}23R-|wYcu}1zCA_7YIh=Ffo zyy^k3{21Ua z=wWnaSR&gQKb`q|zT=gM{LUXf&1C+O4=esv%snSb|VPX13Z|A@hVE%T4;Qv9#VQiS+C^Lv?pI^%ar9OI?R zCy|Ye&w{ga(TvUbXBhtqvBG0p>sA?>Rx?Couj5aMHhi?n2)|pzBr1e~OrN zNm$-9yV%FLU|jp*$p}nIKl?9M{2H%ie4l}LGQQWqH!wbG;GbuFkAXkT_-+G#h4Ebm z{tn|?4Ez)X22}se27WH%UIV{`@l^(XIpf0yek0>M4SWaV9R^PCyP*2)Fz`P!zTLo2 z`GDfzX5i;BK4Rb(GrrZp2N@qS@EaLV8u)#T_Zj$481H2qW+SgZGu~t1C&FN;y)A~E z3mC6A@DSr}1OErcs}1~1jN1nO1mn{Ud@tiw27VL*4XWoP1E0;fFz{B!_pfq}i?xjJ zGw^?6e6NB3JL97U{vF2m82F2f?>2CH{|D87mw`{iI-T&H20owh9R}XX_;v%Q_lJ<2 zZ3cb~<0A%s2jg1}{AtFw82D?9Z#M8r2wAAyVFN#d@gW1hfbpb(U&45wfe$j?W8l{^ zzRJM=gYganf0*$W1OF-GUITxR@p=P46`KImUblgt%XqbcU(C2|;OiKlZs7mIc$I8H=YYZ&h_@CzAVW#DTW z?=bLxV7$e^uVvh8;9qCF-oPJX+-=}LWW3tIf62IQ;D2U(x`7{q5J%cM$3@ysPG`K@ zz-xgQi-&!{Db7iL+biwwS!IUVIA^p(oU^AyoU_}&b)2)yz(XbKb186_C|q}}*Y&(l z)sw3!u3~(|z;9uE)WGkS@)3{mc@`bNJu30SbTOs$J8ns9nd4 zoyNNCY>5}Pm&z&DU-W(@idVN8>%{XUezK_N{S9po7fZZwUACI}&Gl3qxDb;I)`Op7 z++06iC*>5bfFFm6HEh z(eZ1qWdA0207+{xpu;=Sh-t(lm6|Kl>Vz(&No?(KId~U<9`Nj7ukQPK!+A#yla)t~!%P`c*PKMcTTbTc9;3VJsUrG+Wvx2TaGOo|LB@`@< zfdR;IG1)mD>wp*Q$4=m~{;znY1o@5zeEN0?{%2VJ$SKZo_aUgB z&^Y@;?H?k*i}mj(nO~pN)AD}{ob05B&$G_t`b@P|x%%APPZ>`DCw~3D+j_?DWPbgA zT3v^ifs;P#4Le_YhLSUC*v}V%OZ$1+Do3H+uK`28jD-6inXfJ=SyJcw$`tLiN7NA7p6|0@{R?>pA`bBqr^>y`P>Rbs?% zffs9+b+(eP-*bE(^S1y$gY22(mQ{>jF7e~UDEIq^82=C8#pFLJ@xp!e-7H6+i^g!4 z*Bij8AIFobPVac3>x0NxtUmR?r61;V*((&g_-qM& ze6_NuoTp3R`+-Y6|H&&Q*Sb^z7h@tOeDr07`xGn&88_#tn;F;VmhWZ$-vcMT;e?Mw z^mwOZJ|thiXI$&&QpP);SLMRJ$m@RK#q{$m^XqfUy8h?RR`T`v<`-Db2yoKpPL4NP z7=M=e&Gx<~`KO89JfCWR-UNfE`s;JK+OBQ`PV)6Rcg_DG^Xqfky1i59C^`BZw3hRa zz>Br_X67%@GjJNGJ9(VyadG@yCBNq>uWTu%U3py&oa(91>o+jI6L_(5pI|vv>{oR? zt80{e{a*BkSxypoF*#QNCwmy-ais0xd6uKk?XP7yZ)tqDS0YC+K64()M?7<%!WqWz z#H#v?^0?D}Yydd5SO0#1?w9MBf8Ucz4$MhjFEYP=AHJ^Vk#6N5Y$HBA0eG?Yo&%ih zM8C&f_j{7@EkEFZ!ImZttcN{9gr5_0iw2NO1ihFTwv>3H^$LwGC z0)@L@@k$ZPSx_7}wQDD@L$zPJj`{WX5VRkA9eA<&9EZThW|{fqEZ|fh{ks%BoY)M! zn4Bo{n{no5#z%L1r3APIdF^04`Mg)&|60Lff^*{XLL}n12BbfZE&fbFV~hW&E?ii`D0*68JZOlO0wWc6gWMNB=&d z4rtDR63+m-`pPTwX^lR{Z++DYPCg0$!}1>wr^zM%m9-xs;r% zfz$Zy(ck-F`L9SEQB_x1BGVavw}kxDmXMrNgw6b`m_G=-Sbb8!slEDlSoFNGm2v$$ zAJ^&nFmA@BZv&U(n)PEd|FH;M2_NP0em>*v630BkaRtH*dBuT~ow$wo?c2bm{eRyp z`E)&xUaIyt%<~M>ffs9U18|a~zaORdZElxxP7!;#TvZz(?$rFdRk?cpdYkbP#u0YP zYX&B)V&yggr*b>k|4(B6FEhTI=P!-#VtkbOb$j1r-2JpyO2F`u*NIT9?8o1F<-PXj zOM#RAt4{Vwyh{ER;&SHS{+{BecSF&&gK_=)HM(8DU|fIC?5B!d1THAv-Ux6icjt+! z+>bH;_e${plKDrup4*szrnk8KWx%UoCwl*i*+mezv^S2odpO}<;G`e>2l#*sZcSc) z@fMeVI;u_lNuI|aV*ZZ~8h_3!IWJ`X z2Y?rozlZt7ZpE+X!HQwwd|Hf+pm zw*$BHam`{f=?dZ=VW-(K^&Jh%Nw5dhYqLSHgPV^#x>mj52LJy(-?0AUQGUK;3VJN&)f{$ z=DhjjMk#-qu-RYf`rps;?N561*~N=2U;MYi^}Kd$TXFd_fm1)~-_e}R(#{87tp33g z_#kjl>35sXi5SN32V_VD+>sXimDPn-E~kvQT;BMy87xa_ajypr=? z=0CDS;pTc_4&(a!@oSmC8924K!_entTF$dx$$1X*-^jQ*e~G-`$8PK&Oyk>LT~Yd5 z6G_sLK=bcPtOi4|OgNE)3xtQ}_kj zWGa!YsjXjp7=$dIe>jBH9h4B+l3=}~F^d;S5p~gcZ&9WAJE5rg>bH3D^Ue5iwE?9c zzf&vo-KsAA=|G`oiwTKzh5W$Nm3)&}vjXEF4$=712Lxizu2HM%a^ual^$EEh@5vHs{H zokZQLk`{52PN9~m6i;n1u_lAx?~XQwGhw7(a!JYGHmhAU&JST1`!Ult{08X!>`%$j zZ*2S5`8|t6p^i>}SJ%a%=I*w}u0VTRDD-~IE&LhJLo2(^`D51dS4`{V(9Hf2b+O^< z_qU-{{G-#JMFl@P9e`;C(-_cc|KjZLUyrMc<@^K4fBg!1Jb6DgUAj)oTH70Zt)WnQ zaCImUN`}+v^@&t3`Yo7gtq+A_3HiNJn3bydLiLNot)9AMA{`sb`|09B7B_zKFP;cR zBjF4gpeex<$1kt1!%qk5bWd%#Kb#sE2*<-~qp4QUA|I@1r9b3r^>wZYH3wSpTXzs+ zvbiTnuUF~5&c+s!mX)*U(!}ciSUS_{ncvva*4^3~?CMs&4iaU>$4t-Y(cy}PZ6 zYY@_EYYTZ=J?<5OwopT0S)i?}M7nQPetLa$C>lxjhvQIVqp!82y{#)0Y;5tb@RiQq z)ZX2YRe+=T`W2AgU8-yk)vYVgc5x{NS^3h^JsuK2o`6~^A-DoRomr}gS`slH$08C@ zBKIQ7Tq4aQC3lZkyZKT(;}x!2*j>8+7L$nP)^=af-d#*}FPZA8_jPx*2ih7tLqT6x zcPC^h8_KhR1;LAh>W4@}T|V8(dFgdXmkGs_7t8GU@zPEo)KrwGw${Oe!iutasH6al z935V)B8zl#NdeRpWyz%_H2J!GT^D!wi*vX+JBpBlAx{tUWu@ADEBv7%sUBdZ(rViq zF7(5hG!@O*6lg>j6-}Gp8o-akHe6UDwX4(bFPU1KZD^6&)&avW&q_TMNuIBgTm5at zYRst}?ZINHb&Z{VGBf-un%wFOc6E1@Om6Zw`?_1ZR$@{pQn6Zclw=!45*G*I%!(y= z<|8m@3JH)7su=E>-`2gNy}7gf!$lQ3 z-?wrZ(n@s30-3j=wY_n9@!U-?p+?LdrAlsXEtyKL70vH1s#NlQB@-7nwy%KFgQWA4 zMn>vzN|1r9XJL07aX@TsJlY#b`g(g)awMv>x?EZt-YJong1%~NZ*Imcpyp}CFT1G# zhEs2&PReCxKba4CJSqTy^XtkNSqq@8sezoL1NSuh5F<1h@S^Sx16kbE{$cv9XGi9R zFc->NOmHn#HQ+;l;LJ0>$-k`A*HloXr`F#_W5leAXCaymb10g&i0rvkqK9i{=&YeT zh=g(gR$win#^y(D#+LI98UXt1%)T>i^2L}c=AWPmIe#SbMaj=F$&7Cwm z`P-Uk=_6~dKli2+p}sIyz){ikVZ26VO$`4= zb?#7ner>2tFXu{%Ie1+yN=5PG>WTFS)Y=2<0PbFH^8)$9^}5SfGPXwL`AjrE)S*`kqgJ37FkOPW6^ee==F3s48MO-Z!C?yjwsbM zD&KDfodnZ$q0VTs)*T9lq610z?o>1xN@J?Q)`j1!nsgTj=UE+o>&9YBqQtpuFz$)&SBX+{cEjLeS-#Ec^Xc#n4a?4g~y%c)O1K4Rb zgre?6cRXvO^q4`9P1V)TE>{lGlOF>dh#%!4`953WFyHZ7Fy7R1fW4d3!(UP1d4=Se zF?V?`oT!Z_;*mshLwI$6H01H*-C?>5MTWwm)d*nYv~3#c^Lh~h;pKoKPmSEt=ka+U zy%a$JcAz`c{?(n>Ui5`J@x)2s@k)O*&dwtj&t#nkM*)Y;d&=-(f^ozVS8h%&7z26= zDCxoSf;Q)z^8TlTg39>usDmDuAV%7dM3mGUrA38`PW6C1+-mfAs6<^70v${RC>+ax zH3=~gj>Tc0!OWpOVKZhDX{9n=#xxVkKIM5I#@gt~hGu#yDDds`7iCML=SeihWMcaD zlz3zoO02#V56_A`jq<1v^QT&+!RwVbo4?#C%e#P<)$y~5Y66L)Qj^Asl)~ukT28oLE(&gPy@A~ zB0N~NcwL!8pKc0Dfc;Tpd3jbe7_M92hbNM>nV^UA0qE2b(XfF|6jB~oA7?j5)SANM z4y_33H3vLBoft9fU%KeEgW(i5HdZH68K-Z~OU2uIqgcZ`(h)1tVFV)t2w}rFn#zRM zU=P4Z%7x^*yG+}Wll)=a5*cSqI(J77p-e|VI;62NEYA8$?Vy5*1#57|r_W!o=sF1d zDKJzWJFaX)kE73q!mDHJJaot)(vQvvW#@PFz9UW?&mWnkaL~CX6)icH%XdXP)?MbD zk>}ZX?}%4+*)4;DX(nqChiMNZe|Df5CV%7N5VlH8HRa?bx$$z33?Ux24KFjtL*XW6 z?V5nv-o`FvQnp>Irj#ku1U&IdH@g8xZ9KRQgn}k!-ArcTIz&>5RKT-fMWT1GKZ?D5 zxcoo2UllBR;orNHOxM6yzrxxOrw=#@e>5;hRy0Quw+nGi^nK(ubP$& za%oUYXO0pnxh}#sb{t#UaV*XJ(6F2dG3%?nl7caP81{2ZDp8i7+tfdZS)-J0$0GSvC z$DKDzwa+jQJTngW_QN&g)&TFn-j2vJw_9)!j>R08xv(U3NpF8g!Mt@SUb(bg<#gdG zi08CZnPA-HsX&bg<4HjgUsSO9mnS2u#B4)#FBMyXm}|Z|H5Fj1HM%yD+Td|VKRy^+ z7smEy#vkik-iBDkvw(RL@!lAn%yz_XMQUsIkjOhQ8(&`#ejLIci&+AX_UuyiufK(a zEuvsuD7cvZKY&TQpaV;d!P1szv{85Rp}P==4IRLKt#O*&3_Q#QQFdXNeR_>xv2c@0 z&pk!#=x``aPTSZB&Tc^!4Q+MsRL}-KlEGe^pCBzzG0~* zT8?`FreHpX-Sakn=~&OOS-t)*rKMUoJ-7_5PQX-i&kOt=c>J6fJi`#N#H9TsLjw~o z?hbld&@o4Ln`GRFtJw*%V9|RxcC1Tlxm2^9rlgf0%;3lfwv}jn#&GEGay&mIwFg>P zyXC$Mrzx*`2hX6Ea5|%#!3PE9Gfph{^@1l0AId3$ zQZ8GqOtId{O{@+-%3G=tJR(JBMTe5uOpErKd$i77UF!67Y@&@_oGMzV&Rx?^T0uO) zHmD~vGX&Nqb`a|gM>jY(p_G@%4Sdrqaw#%o&W_Q7(O0-DX80wZNptpQMk-W5?txUT z`f0^ff=t*me}Ik;_Tu!_T14-jg-IO0f~GIWZyhH3aauUg8pF7%?*JSGD(gyX^n*OR zSy1JCWrdt)qA(*H(GovzGOXyZ>?D>p;=HvZj#om36K%c~Op*@kFhk;kIo427(fO@F z1Io&@MIW|!-&t8b{~95KlWBZ6r^go8mxE>Jgzku^OY{rNIj94wj&8`0a~3FHne7QW zhgqUrjIni{%e(Tnkc+i97hUV#D-|mg4(d|VVCf3+aSFMO#Ydh^C#t>5`!^87I-w7^ zd1qi(>`Bjf^Gd;ZDJ;V%fhK(;Y6{_}QnSY?v#W_>og>c%hjP#O4?*Gi#&alsT924u zraqQP%hTa?0kjFhXu(8%@BvdvOHqR+)E`?N2}RO_a&1GQi*qoVqgy?q#FR?4E^s`- zi64SF$G~631hrc+4l5W_h$MQW{#c$e4)?h;t%QO(O`R?+h*1t|z#OUx z7sjmI+3c>IuO{Fo-2=X!zM(;-aR1ujTim~*TwTpPtx zF&wYcd!zC&OxFFpe_MAb=@8p;po-F7iJQnHz>JRb9ssIyxCn~IJ%w9fC7!%Su}doa z{+4qF!(&Nx{O+>ohEN3095Mx~X6+~6e^{FfptBJ{cK;(cv&%W)P?re#r!KV3>*&f6 z45?D`mr%uGV6}s#`YpGfV3R#4Pm{~4i z;q_k>yku8z#g@xiLzGX5L-Z8}Zh?7}51K{|#8XNUI!MR1aB zV4N?+YLy&Tv($0a_=}O+`MuFK;lX}9B9I5IaK?(CoYOMoeYp~c^^NOBOv^HyHjR%i zd0@ry(9#?s+Nl&c;{*I!p;j2XiegsoWXU%k?PtujH03z(isq?I7j+;jTRPM8e*i%2 Bl_dZG From bf751cfa438d9d38cf65015f5653128200368f40 Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 29 Mar 2017 16:59:35 -0500 Subject: [PATCH 059/185] update --- .../columnstoreClusterTester.cpp | 1229 +++++++++++++++-- 1 file changed, 1113 insertions(+), 116 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester.cpp b/oamapps/postConfigure/columnstoreClusterTester.cpp index 82a8f5c50..b1d224e96 100644 --- a/oamapps/postConfigure/columnstoreClusterTester.cpp +++ b/oamapps/postConfigure/columnstoreClusterTester.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,24 +46,45 @@ #include #include +#include "liboamcpp.h" +#include "configcpp.h" +#include "alarmmanager.h" + +using namespace std; +using namespace oam; +using namespace config; +using namespace alarmmanager; + +#include "helpers.h" +using namespace installer; using namespace std; -typedef std::vector PrivateIPList; +typedef struct ModuleIP_struct +{ + std::string IPaddress; + std::string status; +} ModuleIP; -string password = "ssh"; -string OS = "centos7"; -string user = "root"; +typedef std::vector ModuleIPList; + +char* pcommand = 0; +string prompt; + +void checkSuccess( bool pass); -char* pcommand1 = 0; -string prompt1; int main(int argc, char *argv[]) { + ModuleIPList moduleiplist; + string IPaddresses = ""; + string OS = ""; + string user = ""; + string password = ""; - for( int i = 1; i < argc; i++ ) - { + for( int i = 1; i < argc; i++ ) + { if( string("-h") == argv[i] || string("--help") == argv[i]) { cout << endl; cout << "This is the MariaDB Columnstore Cluster System Test tool." << endl; @@ -70,37 +92,77 @@ int main(int argc, char *argv[]) cout << "This can be run prior to the install to make sure the servers/nodes" << endl; cout << "are configured properly" << endl; cout << "User will be prompted to provide the server/node IP Addresses, OS" << endl; - cout << "Root/Non-root user install name, and password" << endl; + cout << "Root/Non-root user install name, and password" << endl << endl; cout << "Items that are checked:" << endl; - cout << " Dependent packages installed" << endl; + cout << " Node ping test" << endl; + cout << " Node SSH test" << endl; cout << " OS version" << endl; cout << " Firewall settings" << endl; cout << " Locale settings" << endl; - cout << " Node ping test" << endl; - cout << " Node SSH test" << endl; + cout << " Dependent packages installed" << endl; cout << " ColumnStore Port test" << endl << endl; cout << "Usage: columnstoreClusterTester -h " << endl; cout << " -h Help" << endl; + cout << " -i IP Addresses, starting with local (x.x.x.x,y.y.y.y)" << endl; + cout << " -o OS Version (centos6, centos7, debian8, suse12, ubuntu16)" << endl; + cout << " -u Username (root or 'non-root username')" << endl; + cout << " -p Password (User Password or 'ssh' if using SSH-KEYS)" << endl; + cout << "Dependent package : 'nmap' and 'readline' packages need to be installed locally" << endl; exit (0); } - - cout << endl; - cout << "This is the MariaDB Columnstore Cluster System test tool." << endl; - - cout << endl; - string IPaddresses; - //get Ip Addresses - prompt1 = "Enter List of IP Addresses of each server/node starting with the local first (x.x.x.x,y.y.y.y) > "; - pcommand1 = readline(prompt1.c_str()); - if (pcommand1) { - if (strlen(pcommand1) > 0) IPaddresses = pcommand1; - free(pcommand1); - pcommand1 = 0; + else if( string("-i") == argv[i] ) { + i++; + if (i >= argc ) { + cout << " ERROR: IP Addresses not provided" << endl; + exit (1); + } + IPaddresses = argv[i]; } + else if( string("-o") == argv[i] ) { + i++; + if (i >= argc ) { + cout << " ERROR: OS type not provided" << endl; + exit (1); + } + OS = argv[i]; + } + else if( string("-u") == argv[i] ) { + i++; + if (i >= argc ) { + cout << " ERROR: Username not provided" << endl; + exit (1); + } + user = argv[i]; + } + else if( string("-p") == argv[i] ) { + i++; + if (i >= argc ) { + cout << " ERROR: Password not provided" << endl; + exit (1); + } + password = argv[i]; + } + } + + cout << endl; + cout << "*** This is the MariaDB Columnstore Cluster System test tool ***" << endl << endl; - if ( IPaddresses.empty ) + if ( IPaddresses.empty() ) { - cout << "Error: no IP addresses where entered, exit..." << endl; + cout << endl; + //get Ip Addresses + prompt = "Enter List of IP Addresses of each server/node starting with the local first (x.x.x.x,y.y.y.y) > "; + pcommand = readline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) IPaddresses = pcommand; + free(pcommand); + pcommand = 0; + } + } + + if ( IPaddresses.empty() ) + { + cout << "Error: no IP addresses where entered, exiting..." << endl; exit (1); } else @@ -111,131 +173,1066 @@ int main(int argc, char *argv[]) it != tokens.end(); ++it) { - PrivateIPList.push_back(*it); + ModuleIP moduleip; + moduleip.IPaddress = *it; + if ( it == tokens.begin() ) + moduleip.status = "local"; + else + moduleip.status = "pass"; + moduleiplist.push_back(moduleip); } } - cout << endl; - //get OS - prompt1 = "Enter OS version (centos6, centos7, debian8, suse12, ubuntu16) > "; - pcommand1 = readline(prompt1.c_str()); - if (pcommand1) { - if (strlen(pcommand1) > 0) OS = pcommand1; - free(pcommand1); - pcommand1 = 0; - } - - if ( OS.empty ) + if ( OS.empty() ) { - cout << "Error: no OS Version was entered, exit..." << endl; + cout << endl; + //get OS + prompt = "Enter OS version (centos6, centos7, debian8, suse12, ubuntu16) > "; + pcommand = readline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) OS = pcommand; + free(pcommand); + pcommand = 0; + } + } + + if ( OS.empty() ) + { + cout << "Error: no OS Version was entered, exiting..." << endl; exit (1); } - cout << endl; - //get User - prompt1 = "Enter Install user (root or 'non-root user name') > "; - pcommand1 = readline(prompt1.c_str()); - if (pcommand1) { - if (strlen(pcommand1) > 0) user = pcommand1; - free(pcommand1); - pcommand1 = 0; - } - - if ( user.empty ) + if ( user.empty() ) { - cout << "Error: no User type was entered, exit..." << endl; + cout << endl; + //get User + prompt = "Enter Install user (root or 'non-root username') > "; + pcommand = readline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) user = pcommand; + free(pcommand); + pcommand = 0; + } + } + + if ( user.empty() ) + { + cout << "Error: no User type was entered, exiting..." << endl; exit (1); } - cout << endl; - //get root password - prompt1 = "Enter User Password or 'ssh' if using SSH-KEYS, which is used to access other nodes > "; - pcommand1 = readline(prompt1.c_str()); - if (pcommand1) { - if (strlen(pcommand1) > 0) password = pcommand1; - free(pcommand1); - pcommand1 = 0; - } - //get Elastic IP to module assignments - if ( password.empty ) + if ( password.empty() ) { - cout << "Error: no password or 'ssh' was entered, exit..." << endl; + cout << endl; + //get root password + prompt = "Enter User Password or 'ssh' if using SSH-KEYS, which is used to access other nodes > "; + pcommand = readline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) password = pcommand; + free(pcommand); + pcommand = 0; + } + } + + if ( password.empty() ) + { + cout << "Error: no password or 'ssh' was entered, exiting..." << endl; exit (1); } + // + // ping test + // + cout << "Run Ping access Test" << endl << endl; + string cmdLine = "ping "; + string cmdOption = " -c 1 -w 5 >> /dev/null"; + string cmd; + + bool pass = true; + ModuleIPList::iterator list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + cout << " Testing " + ipAddress + " : "; + + // perform login test + string cmd = "./remote_command.sh " + ipAddress + " " + password + " ls"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + cout << " PASSED" << endl; + else + { + ModuleIP moduleip; + moduleip.IPaddress = ipAddress; + moduleip.status = "failed"; + + moduleiplist.erase(list); + moduleiplist.insert(list, moduleip); + + cout << " FAILED, check connection" << endl; + pass = false; + } + } + + checkSuccess(pass); + + // + // ssh login test + // + cout << endl << "Run Login access Test" << endl << endl; - *********************************************************************************************** + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "local" || status == "failed" ) + continue; + + cout << " Testing " + ipAddress + " : "; + + // perform ping test + cmd = cmdLine + ipAddress + cmdOption; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + cout << " PASSED" << endl; + else + { + cout << " FAILED, check password or ssh-key setup" << endl; + pass = false; + } + } + + checkSuccess(pass); + // + // OS compare + // + cout << endl << "Getting OS versions" << endl << endl; - string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; + string OScmd = "./os_check.sh > /tmp/os_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + if ( status == "local" ) + { + int rtnCode = system(OScmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << "Local OS Version : "; + cout.flush(); + system("cat /tmp/os_check"); + } + else + { + cout << " FAILED, os_check.sh failed, check /tmp/os_check" << endl; + pass = false; + } + } + else + { + cout << "OS version for " << ipAddress << " :"; + // push os_check to remote node + string cmd = "./remote_scp_put.sh " + ipAddress + " " + password + " os_check.sh 1 > /tmp/put_os_check.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "ERROR: failed update of root password on " + module << endl; - cleanupSystem(); - } - - - string cmd = installDir + "/bin/remote_scp_put.sh " + ipAddress + " " + AMIrootPassword + " " + x509Cert + " > /tmp/scp.log_" + instanceName; + if (WEXITSTATUS(rtnCode) == 0) + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " '" + OScmd + "' > /tmp/run_os_check.log"; +cout << cmd << endl; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/os_check 1 > /tmp/get_os_check.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) { - pass = true; - break; - } - - //assign um Instances - std::vector::iterator list = existinguminstance.begin(); - for (; list != existinguminstance.end() ; list++) + if (WEXITSTATUS(rtnCode) == 0) { - string module = "um" + oam.itoa(um); - - cout << "Assigning Instance for " + module; - - string instanceName = *list; + system("cat os_check"); + + //compare with local + int rtnCode = system("diff /tmp/os_check os_check"); + if (WEXITSTATUS(rtnCode) != 0) + { + cout << " FAILED, doesn't match local servers OS version" << endl; + pass = false; + } + + //unlink("os_check"); } + else + { + cout << " FAILED, check /tmp/get_os_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_os_check.log" << endl; + pass = false; + } } + else + { + cout << " FAILED, /tmp/put_os_check.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); + + + // + // Locale compare + // + cout << endl << "Getting Locale" << endl << endl; + + string Localecmd = "./locale | grep 'LANG=' > /tmp/locale_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Getting Locale for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(Localecmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + system("cat /tmp/locale_check"); + else + { + cout << " FAILED, locale command failed, check /tmp/locale_check" << endl; + pass = false; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + Localecmd + " > /tmp/run_locale.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/locale_check > /tmp/get_locale_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + system("cat locale_check"); + + //compare with local + int rtnCode = system("diff /tmp/locale_check locale_check"); + if (WEXITSTATUS(rtnCode) != 0) + { + cout << " FAILED, doesn't match local servers Locale" << endl; + pass = false; + } + + unlink("locale_check"); + } + else + { + cout << " FAILED, check /tmp/get_locale_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_locale.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); -void setRootPassword() -{ - Oam oam; + // + // Check SELINUX + // + cout << "Checking Firewall setting - SELINUX should be disabled" << endl << endl; + + string SELINUXcmd = "cat /etc/selinex/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; + string SELINUXREMOTEcmd = "cat /etc/selinex/config > /tmp/selinux_check 2>&1"; + string SELINUXREMOTECHECKcmd = "cat selinux_check | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; - cout << endl << "--- Updating Root Password on all Instance(s) ---" << endl << endl; - - InstanceList::iterator list1 = uminstancelist.begin(); - for (; list1 != uminstancelist.end() ; list1++) + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) { - string instance = (*list1).instanceName; - string module = (*list1).moduleName; - - //get IP Address of um instance - string ipAddress = oam.getEC2InstanceIpAddress(instance); - - if (ipAddress == "stopped" || ipAddress == "terminated" ) { - cout << "ERROR: Instance " << instance << " failed to get private IP Address" << endl; - cleanupSystem(); + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking SELINUX for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(SELINUXcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; + pass = false; } - - string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; + else + { + cout << " PASSED" << endl; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + SELINUXREMOTEcmd + " > /tmp/run_selinux.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "ERROR: failed update of root password on " + module << endl; - cleanupSystem(); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/selinux_check > /tmp/get_selinux_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(SELINUXREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + + unlink("selinux_check"); + } + else + { + cout << " FAILED, check /tmp/get_selinux_check.log" << endl; + pass = false; + } } + else + { + cout << " FAILED, check /tmp/run_selinux.log" << endl; + pass = false; + } + } } - InstanceList::iterator list2 = pminstancelist.begin(); - for (; list2 != pminstancelist.end() ; list2++) + checkSuccess(pass); + + // + // Check IPTABLES for Centos6 + // + if ( OS == "centos6") { - string instance = (*list2).instanceName; - string module = (*list2).moduleName; + cout << "Checking Firewall setting - IPTABLES should be disabled" << endl << endl; + + string IPTABLEScmd = "chkconfig | grep iptables | grep on > /tmp/iptables_check 2>&1"; + string IPTABLESREMOTEcmd = "chkconfig > /tmp/iptables_check 2>&1"; + string IPTABLESREMOTECHECKcmd = "cat iptables_check | grep iptables | grep on > /tmp/iptables_check 2>&1"; - string cmd = installDir + "/bin/remote_command.sh " + ipAddress + " " + AMIrootPassword + " '/root/updatePassword.sh " + rootPassword + "' > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "ERROR: failed update root of password on " + module << endl; - cleanupSystem(); + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking IPTABLES for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(IPTABLEScmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, iptables is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + IPTABLESREMOTEcmd + " > /tmp/run_iptables.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check > /tmp/get_iptables_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(IPTABLESREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, iptables is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + + unlink("iptables_check"); + } + else + { + cout << " FAILED, check /tmp/get_iptables_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_iptables.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); } + + // + // Check UFW for ubuntu 16 + // + if ( OS == "ubuntu16") + { + cout << "Checking Firewall setting - UFW should be disabled" << endl << endl; + + string UFWcmd = "chkconfig | grep ufw | grep on > /tmp/ufw_check 2>&1"; + string UFWREMOTEcmd = "chkconfig > /tmp/ufw_check 2>&1"; + string UFWREMOTECHECKcmd = "cat ufw_check | grep iptables | grep on > /tmp/ufw_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking UFW for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(UFWcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, ufw is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + UFWREMOTEcmd + " > /tmp/run_ufw.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check > /tmp/get_ufw_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(UFWREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, ufw is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + + unlink("ufw_check"); + } + else + { + cout << " FAILED, check /tmp/get_ufw_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_ufw.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); + } + + // + // Check filewalls for SUSE + // + if ( OS == "suse12") + { + cout << "Checking Firewall setting - rcSuSEfirewall2 should be disabled" << endl << endl; + + string rcSuSEfirewall2cmd = "/sbin/rcSuSEfirewall2 status | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; + string rcSuSEfirewall2REMOTEcmd = "/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1"; + string rcSuSEfirewall2REMOTECHECKcmd = "cat rcSuSEfirewall2_check | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking rcSuSEfirewall2 for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(rcSuSEfirewall2cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, rcSuSEfirewall2 is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + rcSuSEfirewall2REMOTEcmd + " > /tmp/run_rcSuSEfirewall2.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check > /tmp/get_rcSuSEfirewall2_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(rcSuSEfirewall2REMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, rcSuSEfirewall2 is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + + unlink("rcSuSEfirewall2_check"); + } + else + { + cout << " FAILED, check /tmp/rcSuSEfirewall2_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_rcSuSEfirewall2.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); + } + + // + // Check filewalls for non-Centos6 + // + if ( OS != "centos6") + { + cout << "Checking Firewall setting - firewalld should be disabled" << endl << endl; + + string FIREWALLDcmd = "systemctl status firewalld | grep running > /tmp/firewalld_check 2>&1"; + string FIREWALLDREMOTEcmd = "systemctl status firewalld > /tmp/firewalld_check 2>&1"; + string FIREWALLDREMOTECHECKcmd = "cat firewalld_check | grep running > /tmp/firewalld_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking IPTABLES for " + ipAddress + " : "; + + if ( status == "local" ) + { + int rtnCode = system(FIREWALLDcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, firewalld is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + FIREWALLDREMOTEcmd + " > /tmp/run_firewalld.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check > /tmp/get_firewalld_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(FIREWALLDREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, firewalld is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED" << endl; + } + + unlink("firewalld_check"); + } + else + { + cout << " FAILED, check /tmp/firewalld_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_firewalld.log" << endl; + pass = false; + } + } + } + + checkSuccess(pass); + } + + // + // Dependent package install check + // + + bool nmapPass = true; + + //centos + + const std::string centosPgk[] = { + "boost", + "expect", + "perl", + "perl-DBI", + "openssl", + "zlib", + "file", + "sudo", + "perl-DBD-MySQL", + "libaio", + "rsync", + "snappy", + "net-tools", + "" + }; + + if ( OS == "centos6" || OS == "centos7") + { + cout << "Checking Dependent Package installations" << endl << endl; + + string pgkcmd1 = "yum list installed "; + string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; + string pgkREMOTEcmd1 = "yum list installed "; + string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; + string pgkREMOTECHECKcmd = "cat pgk_check | grep Installed > /tmp/pgk_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking Dependent Package Installations for " + ipAddress << endl; + + for( int i = 0;;i++) + { + if ( centosPgk[i] == "" ) + { + // end of section list, check for nmap which is needed for port testing + string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; + + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; + nmapPass = false; + } + + break; + } + + string pkg = centosPgk[i]; + + string pkgCMD = pgkcmd1 + pkg + pgkcmd2; + string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; + + if ( status == "local" ) + { + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(pgkREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + + unlink("pgk_check"); + } + else + { + cout << " FAILED, check /tmp/pgk_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_pgk.log" << endl; + pass = false; + } + } + } + + if (!pass) + cout << " Passed, all dependent packages are installed" << endl << endl; + } + + checkSuccess(pass); + } + + // suse + if ( OS == "suse12" ) + { + cout << "Checking Dependent Package installations" << endl << endl; + + string pgkcmd1 = "zypper list installed "; + string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; + string pgkREMOTEcmd1 = "zypper list installed "; + string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; + string pgkREMOTECHECKcmd = "cat pgk_check | grep Installed > /tmp/pgk_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking Dependent Package Installations for " + ipAddress << endl; + + for( int i = 0;;i++) + { + if ( centosPgk[i] == "" ) + { + // end of section list, check for nmap which is needed for port testing + string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; + + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; + nmapPass = false; + } + + break; + } + + string pkg = centosPgk[i]; + + string pkgCMD = pgkcmd1 + pkg + pgkcmd2; + string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; + + if ( status == "local" ) + { + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(pgkREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + + unlink("pgk_check"); + } + else + { + cout << " FAILED, check /tmp/pgk_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_pgk.log" << endl; + pass = false; + } + } + } + + if (!pass) + cout << " Passed, all dependent packages are installed" << endl << endl; + } + + checkSuccess(pass); + } + + + //ubuntu and debian + + const std::string ubuntuPgk[] = { + "libboost-all-dev", + "expect", + "libdbi-perl", + "perl", + "openssl", + "libreadline-dev", + "file", + "sudo", + "libaio", + "rsync", + "libsnappy1", + "net-tools", + "" + }; + + if ( OS == "ubuntu16" || OS == "debian8" ) + { + cout << "Checking Dependent Package installations" << endl << endl; + + string pgkcmd1 = "dpkg -s "; + string pgkcmd2 = " | grep installed > /tmp/pkg_check 2>&1"; + string pgkREMOTEcmd1 = "dpkg -s "; + string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; + string pgkREMOTECHECKcmd = "cat pgk_check | grep installed > /tmp/pgk_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" ) + continue; + + cout << " Checking Dependent Package Installations for " + ipAddress << endl; + + for( int i = 0;;i++) + { + if ( ubuntuPgk[i] == "" ) + { + // end of section list, check for nmap which is needed for port testing + string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; + + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; + nmapPass = false; + } + + break; + } + + string pkg = ubuntuPgk[i]; + + string pkgCMD = pgkcmd1 + pkg + pgkcmd2; + string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; + + if ( status == "local" ) + { + int rtnCode = system(pkgCMD.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + } + else + { + //run command + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(pgkREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 0 ) + { + cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; + pass = false; + } + + unlink("pgk_check"); + } + else + { + cout << " FAILED, check /tmp/pgk_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_pgk.log" << endl; + pass = false; + } + } + } + + if (!pass) + cout << " Passed, all dependent packages are installed" << endl << endl; + } + + checkSuccess(pass); + } + + // port testing + if (!nmapPass) + { + cout << "Package 'nmap' isn't installed, skipping the port testing" << endl; + exit (0); + } + + cout << "Checking Port availibility that MariaDb ColumnStore will use" << endl << endl; + + string nmapcmd1 = "nmap "; + string nmapcmd2 = " -p 8602 | grep 'closed unknown' > /tmp/nmap_check 2>&1"; + + pass = true; + list = moduleiplist.begin(); + for (; list != moduleiplist.end() ; list++) + { + string ipAddress = (*list).IPaddress; + string status = (*list).status; + if ( status == "failed" || status == "local") + continue; + + cout << " Checking Ports using /nmap' for " + ipAddress + " : "; + + string nmapcmd = nmapcmd1 + ipAddress + nmapcmd2; + + //run command + int rtnCode = system(nmapcmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0 ) + cout << " FAILED, iptables is enabled, please disable" << endl; + else + cout << " PASSED" << endl; + } + + cout << endl << endl << "Finished Validation of the Cluster, correct any failures" << endl; + exit(0); + +} + + +void checkSuccess( bool pass) +{ + if (!pass) + { + cout << endl; + string answer = "y"; + prompt = "Failure Occurred, do you want to continue? (y,n) > "; + pcommand = readline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) answer = pcommand; + free(pcommand); + pcommand = 0; + } + + if ( answer == "n" ) + { + cout << "Exiting..." << endl; + exit (1); + } + } } From 310f8e5a6cffa0c2e086298998382d47653a22a1 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 30 Mar 2017 17:32:55 -0500 Subject: [PATCH 060/185] update --- .../columnstoreClusterTester.cpp | 317 +++++++++++------- 1 file changed, 189 insertions(+), 128 deletions(-) diff --git a/oamapps/postConfigure/columnstoreClusterTester.cpp b/oamapps/postConfigure/columnstoreClusterTester.cpp index b1d224e96..d7a793456 100644 --- a/oamapps/postConfigure/columnstoreClusterTester.cpp +++ b/oamapps/postConfigure/columnstoreClusterTester.cpp @@ -73,6 +73,7 @@ string prompt; void checkSuccess( bool pass); +bool check = true; int main(int argc, char *argv[]) { @@ -101,13 +102,14 @@ int main(int argc, char *argv[]) cout << " Locale settings" << endl; cout << " Dependent packages installed" << endl; cout << " ColumnStore Port test" << endl << endl; - cout << "Usage: columnstoreClusterTester -h " << endl; + cout << "Usage: columnstoreClusterTester -h -i -i -u -p -c" << endl; cout << " -h Help" << endl; cout << " -i IP Addresses, starting with local (x.x.x.x,y.y.y.y)" << endl; cout << " -o OS Version (centos6, centos7, debian8, suse12, ubuntu16)" << endl; cout << " -u Username (root or 'non-root username')" << endl; - cout << " -p Password (User Password or 'ssh' if using SSH-KEYS)" << endl; - cout << "Dependent package : 'nmap' and 'readline' packages need to be installed locally" << endl; + cout << " -p Password (User Password or 'ssh' if using SSH-KEYS)" << endl; + cout << " -c Continue on failures" << endl << endl; + cout << "Dependent package : 'nmap', 'readline', and 'boost' packages need to be installed locally" << endl; exit (0); } else if( string("-i") == argv[i] ) { @@ -142,9 +144,12 @@ int main(int argc, char *argv[]) } password = argv[i]; } + else if( string("-c") == argv[i] ) { + check = false; + } } - cout << endl; + cout << endl << endl; cout << "*** This is the MariaDB Columnstore Cluster System test tool ***" << endl << endl; if ( IPaddresses.empty() ) @@ -244,7 +249,7 @@ int main(int argc, char *argv[]) // // ping test // - cout << "Run Ping access Test" << endl << endl; + cout << endl << "Run Ping access Test" << endl << endl; string cmdLine = "ping "; string cmdOption = " -c 1 -w 5 >> /dev/null"; @@ -256,7 +261,12 @@ int main(int argc, char *argv[]) { string ipAddress = (*list).IPaddress; string status = (*list).status; + + if ( status == "local" ) + continue; + cout << " Testing " + ipAddress + " : "; + cout.flush(); // perform login test string cmd = "./remote_command.sh " + ipAddress + " " + password + " ls"; @@ -294,6 +304,7 @@ int main(int argc, char *argv[]) continue; cout << " Testing " + ipAddress + " : "; + cout.flush(); // perform ping test cmd = cmdLine + ipAddress + cmdOption; @@ -330,7 +341,7 @@ int main(int argc, char *argv[]) int rtnCode = system(OScmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) { - cout << "Local OS Version : "; + cout << " Local OS Version : "; cout.flush(); system("cat /tmp/os_check"); } @@ -342,17 +353,18 @@ int main(int argc, char *argv[]) } else { - cout << "OS version for " << ipAddress << " :"; + cout << " OS version for " << ipAddress << " : "; + cout.flush(); + // push os_check to remote node string cmd = "./remote_scp_put.sh " + ipAddress + " " + password + " os_check.sh 1 > /tmp/put_os_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " '" + OScmd + "' > /tmp/run_os_check.log"; -cout << cmd << endl; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " '" + OScmd + " 1' > /tmp/run_os_check.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/os_check 1 > /tmp/get_os_check.log"; @@ -362,14 +374,14 @@ cout << cmd << endl; system("cat os_check"); //compare with local - int rtnCode = system("diff /tmp/os_check os_check"); + int rtnCode = system("diff /tmp/os_check os_check > /dev/null 2>&1"); if (WEXITSTATUS(rtnCode) != 0) { cout << " FAILED, doesn't match local servers OS version" << endl; pass = false; } - //unlink("os_check"); + unlink("os_check"); } else { @@ -399,7 +411,8 @@ cout << cmd << endl; // cout << endl << "Getting Locale" << endl << endl; - string Localecmd = "./locale | grep 'LANG=' > /tmp/locale_check 2>&1"; + string Localecmd = "locale | grep LANG= > /tmp/locale_check 2>&1"; + string LocaleREMOTEcmd = "'locale | grep LANG= > /tmp/locale_check 2>&1'"; pass = true; list = moduleiplist.begin(); @@ -410,13 +423,15 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Getting Locale for " + ipAddress + " : "; - if ( status == "local" ) { int rtnCode = system(Localecmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " Local Locale Setting : "; + cout.flush(); system("cat /tmp/locale_check"); + } else { cout << " FAILED, locale command failed, check /tmp/locale_check" << endl; @@ -425,20 +440,26 @@ cout << cmd << endl; } else { + cout << " Getting Locale for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + Localecmd + " > /tmp/run_locale.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + LocaleREMOTEcmd + " 1 > /tmp/run_locale.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/locale_check > /tmp/get_locale_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/locale_check 1 > /tmp/get_locale_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { + // get local again + system(Localecmd.c_str()); + system("cat locale_check"); - + //compare with local - int rtnCode = system("diff /tmp/locale_check locale_check"); + int rtnCode = system("diff /tmp/locale_check locale_check > /dev/null 2>&1"); if (WEXITSTATUS(rtnCode) != 0) { cout << " FAILED, doesn't match local servers Locale" << endl; @@ -467,10 +488,10 @@ cout << cmd << endl; // // Check SELINUX // - cout << "Checking Firewall setting - SELINUX should be disabled" << endl << endl; + cout << endl << "Checking Firewall setting - SELINUX should be disabled" << endl << endl; - string SELINUXcmd = "cat /etc/selinex/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; - string SELINUXREMOTEcmd = "cat /etc/selinex/config > /tmp/selinux_check 2>&1"; + string SELINUXcmd = "cat /etc/selinux/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; + string SELINUXREMOTEcmd = "'cat /etc/selinux/config' > /tmp/selinux_check 2>&1"; string SELINUXREMOTECHECKcmd = "cat selinux_check | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; pass = true; @@ -482,56 +503,76 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking SELINUX for " + ipAddress + " : "; - if ( status == "local" ) { - int rtnCode = system(SELINUXcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; - pass = false; - } + cout << " Local SELINUX setting check : "; + cout.flush(); + + //check if config file exist + ifstream oldFile ("/etc/selinex/config"); + if (!oldFile) + cout << " PASSED, is disabled" << endl; else { - cout << " PASSED" << endl; + int rtnCode = system(SELINUXcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED, it is disabled" << endl; + } } } else { + cout << " Checking SELINUX for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + SELINUXREMOTEcmd + " > /tmp/run_selinux.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " 'ls /etc/selinex/config' 1 > /tmp/check_selinux.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 0 ) { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/selinux_check > /tmp/get_selinux_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(SELINUXREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED" << endl; - } - - unlink("selinux_check"); - } - else - { - cout << " FAILED, check /tmp/get_selinux_check.log" << endl; - pass = false; - } + cout << " PASSED, it is disabled" << endl; } else { - cout << " FAILED, check /tmp/run_selinux.log" << endl; - pass = false; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + SELINUXREMOTEcmd + " 1 > /tmp/run_selinux.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 1 ) + { + //get results + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/selinux_check 1 > /tmp/get_selinux_check.log"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + { + int rtnCode = system(SELINUXREMOTECHECKcmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0 ) + { + cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; + pass = false; + } + else + { + cout << " PASSED, it is disabled" << endl; + } + + unlink("selinux_check"); + } + else + { + cout << " FAILED, check /tmp/get_selinux_check.log" << endl; + pass = false; + } + } + else + { + cout << " FAILED, check /tmp/run_selinux.log" << endl; + pass = false; + } } } } @@ -543,7 +584,7 @@ cout << cmd << endl; // if ( OS == "centos6") { - cout << "Checking Firewall setting - IPTABLES should be disabled" << endl << endl; + cout << endl << "Checking Firewall setting - IPTABLES should be disabled" << endl << endl; string IPTABLEScmd = "chkconfig | grep iptables | grep on > /tmp/iptables_check 2>&1"; string IPTABLESREMOTEcmd = "chkconfig > /tmp/iptables_check 2>&1"; @@ -558,10 +599,11 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking IPTABLES for " + ipAddress + " : "; - if ( status == "local" ) { + cout << " Local IPTABLES setting check : "; + cout.flush(); + int rtnCode = system(IPTABLEScmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) { @@ -570,18 +612,21 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } } else { + cout << " Checking IPTABLES for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + IPTABLESREMOTEcmd + " > /tmp/run_iptables.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + IPTABLESREMOTEcmd + " 1 > /tmp/run_iptables.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check > /tmp/get_iptables_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check 1 > /tmp/get_iptables_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -593,7 +638,7 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } unlink("iptables_check"); @@ -620,11 +665,11 @@ cout << cmd << endl; // if ( OS == "ubuntu16") { - cout << "Checking Firewall setting - UFW should be disabled" << endl << endl; + cout << endl << "Checking Firewall setting - UFW should be disabled" << endl << endl; string UFWcmd = "chkconfig | grep ufw | grep on > /tmp/ufw_check 2>&1"; string UFWREMOTEcmd = "chkconfig > /tmp/ufw_check 2>&1"; - string UFWREMOTECHECKcmd = "cat ufw_check | grep iptables | grep on > /tmp/ufw_check 2>&1"; + string UFWREMOTECHECKcmd = "cat ufw_check | grep ufw | grep on > /tmp/ufw_check 2>&1"; pass = true; list = moduleiplist.begin(); @@ -635,10 +680,11 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking UFW for " + ipAddress + " : "; - if ( status == "local" ) { + cout << " Local UFW setting check : "; + cout.flush(); + int rtnCode = system(UFWcmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) { @@ -647,18 +693,21 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } } else { + cout << " Checking UFW for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + UFWREMOTEcmd + " > /tmp/run_ufw.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + UFWREMOTEcmd + " 1 > /tmp/run_ufw.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check > /tmp/get_ufw_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check 1 > /tmp/get_ufw_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -670,7 +719,7 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } unlink("ufw_check"); @@ -697,10 +746,10 @@ cout << cmd << endl; // if ( OS == "suse12") { - cout << "Checking Firewall setting - rcSuSEfirewall2 should be disabled" << endl << endl; + cout << endl << "Checking Firewall setting - rcSuSEfirewall2 should be disabled" << endl << endl; string rcSuSEfirewall2cmd = "/sbin/rcSuSEfirewall2 status | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; - string rcSuSEfirewall2REMOTEcmd = "/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1"; + string rcSuSEfirewall2REMOTEcmd = "'/sbin/rcSuSEfirewall2 status' > /tmp/rcSuSEfirewall2_check 2>&1"; string rcSuSEfirewall2REMOTECHECKcmd = "cat rcSuSEfirewall2_check | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; pass = true; @@ -712,10 +761,11 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking rcSuSEfirewall2 for " + ipAddress + " : "; - if ( status == "local" ) { + cout << " Local rcSuSEfirewall2 setting check : "; + cout.flush(); + int rtnCode = system(rcSuSEfirewall2cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) { @@ -724,18 +774,21 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } } else { + cout << " Checking rcSuSEfirewall2 for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + rcSuSEfirewall2REMOTEcmd + " > /tmp/run_rcSuSEfirewall2.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + rcSuSEfirewall2REMOTEcmd + " 1 > /tmp/run_rcSuSEfirewall2.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check > /tmp/get_rcSuSEfirewall2_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check 1 > /tmp/get_rcSuSEfirewall2_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -747,7 +800,7 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } unlink("rcSuSEfirewall2_check"); @@ -774,10 +827,10 @@ cout << cmd << endl; // if ( OS != "centos6") { - cout << "Checking Firewall setting - firewalld should be disabled" << endl << endl; + cout << endl << "Checking Firewall setting - firewalld should be disabled" << endl << endl; string FIREWALLDcmd = "systemctl status firewalld | grep running > /tmp/firewalld_check 2>&1"; - string FIREWALLDREMOTEcmd = "systemctl status firewalld > /tmp/firewalld_check 2>&1"; + string FIREWALLDREMOTEcmd = "'systemctl status firewalld > /tmp/firewalld_check 2>&1'"; string FIREWALLDREMOTECHECKcmd = "cat firewalld_check | grep running > /tmp/firewalld_check 2>&1"; pass = true; @@ -789,10 +842,11 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking IPTABLES for " + ipAddress + " : "; - if ( status == "local" ) { + cout << " Local firewalld setting check : "; + cout.flush(); + int rtnCode = system(FIREWALLDcmd.c_str()); if (WEXITSTATUS(rtnCode) == 0 ) { @@ -801,18 +855,21 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } } else { + cout << " Checking firewalld for " + ipAddress + " : "; + cout.flush(); + //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + FIREWALLDREMOTEcmd + " > /tmp/run_firewalld.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + FIREWALLDREMOTEcmd + " 1 > /tmp/run_firewalld.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check > /tmp/get_firewalld_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check 1 > /tmp/get_firewalld_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -824,14 +881,14 @@ cout << cmd << endl; } else { - cout << " PASSED" << endl; + cout << " PASSED, it is disabled" << endl; } unlink("firewalld_check"); } else { - cout << " FAILED, check /tmp/firewalld_check.log" << endl; + cout << " FAILED, check /tmp/get_firewalld_check.log" << endl; pass = false; } } @@ -873,13 +930,13 @@ cout << cmd << endl; if ( OS == "centos6" || OS == "centos7") { - cout << "Checking Dependent Package installations" << endl << endl; + cout << endl << "Checking Dependent Package installations" << endl << endl; string pgkcmd1 = "yum list installed "; string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; - string pgkREMOTEcmd1 = "yum list installed "; - string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; - string pgkREMOTECHECKcmd = "cat pgk_check | grep Installed > /tmp/pgk_check 2>&1"; + string pgkREMOTEcmd1 = "'yum list installed "; + string pgkREMOTEcmd2 = " > /tmp/pkg_check 2>&1'"; + string pgkREMOTECHECKcmd = "cat pkg_check | grep Installed > /tmp/pkg_check 2>&1"; pass = true; list = moduleiplist.begin(); @@ -890,8 +947,11 @@ cout << cmd << endl; if ( status == "failed" ) continue; - cout << " Checking Dependent Package Installations for " + ipAddress << endl; - + if ( status == "local" ) + cout << " Local Dependent Package Installations checking" << endl; + else + cout << " Checking Dependent Package Installations for " + ipAddress << endl; + for( int i = 0;;i++) { if ( centosPgk[i] == "" ) @@ -915,7 +975,7 @@ cout << cmd << endl; string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; if ( status == "local" ) - { + { int rtnCode = system(pkgCMD.c_str()); if (WEXITSTATUS(rtnCode) != 0 ) { @@ -926,12 +986,12 @@ cout << cmd << endl; else { //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pkg.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pkg_check 1 > /tmp/get_pkg_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -943,24 +1003,24 @@ cout << cmd << endl; pass = false; } - unlink("pgk_check"); + unlink("pkg_check"); } else { - cout << " FAILED, check /tmp/pgk_check.log" << endl; + cout << " FAILED, check /tmp/get_pkg_check.log" << endl; pass = false; } } else { - cout << " FAILED, check /tmp/run_pgk.log" << endl; + cout << " FAILED, check /tmp/run_pkg.log" << endl; pass = false; } } } - if (!pass) - cout << " Passed, all dependent packages are installed" << endl << endl; + if (pass) + cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; } checkSuccess(pass); @@ -969,7 +1029,7 @@ cout << cmd << endl; // suse if ( OS == "suse12" ) { - cout << "Checking Dependent Package installations" << endl << endl; + cout << endl << "Checking Dependent Package installations" << endl << endl; string pgkcmd1 = "zypper list installed "; string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; @@ -1022,12 +1082,12 @@ cout << cmd << endl; else { //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pgk.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check 1 > /tmp/get_pgk_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -1055,8 +1115,8 @@ cout << cmd << endl; } } - if (!pass) - cout << " Passed, all dependent packages are installed" << endl << endl; + if (pass) + cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; } checkSuccess(pass); @@ -1083,7 +1143,7 @@ cout << cmd << endl; if ( OS == "ubuntu16" || OS == "debian8" ) { - cout << "Checking Dependent Package installations" << endl << endl; + cout << endl << "Checking Dependent Package installations" << endl << endl; string pgkcmd1 = "dpkg -s "; string pgkcmd2 = " | grep installed > /tmp/pkg_check 2>&1"; @@ -1136,12 +1196,12 @@ cout << cmd << endl; else { //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " > /tmp/run_pgk.log"; + string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pgk.log"; int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) + if (WEXITSTATUS(rtnCode) != 1 ) { //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check > /tmp/get_pgk_check.log"; + string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check 1 > /tmp/get_pgk_check.log"; int rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 0) { @@ -1169,8 +1229,8 @@ cout << cmd << endl; } } - if (!pass) - cout << " Passed, all dependent packages are installed" << endl << endl; + if (pass) + cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; } checkSuccess(pass); @@ -1179,11 +1239,11 @@ cout << cmd << endl; // port testing if (!nmapPass) { - cout << "Package 'nmap' isn't installed, skipping the port testing" << endl; + cout << endl << "Package 'nmap' isn't installed, skipping the port testing" << endl; exit (0); } - cout << "Checking Port availibility that MariaDb ColumnStore will use" << endl << endl; + cout << endl << "Checking MariaDb ColumnStore Port availibility" << endl << endl; string nmapcmd1 = "nmap "; string nmapcmd2 = " -p 8602 | grep 'closed unknown' > /tmp/nmap_check 2>&1"; @@ -1197,7 +1257,8 @@ cout << cmd << endl; if ( status == "failed" || status == "local") continue; - cout << " Checking Ports using /nmap' for " + ipAddress + " : "; + cout << " Checking Port (8602) using 'nmap' for " + ipAddress + " : "; + cout.flush(); string nmapcmd = nmapcmd1 + ipAddress + nmapcmd2; @@ -1209,7 +1270,7 @@ cout << cmd << endl; cout << " PASSED" << endl; } - cout << endl << endl << "Finished Validation of the Cluster, correct any failures" << endl; + cout << endl << endl << "Finished Validation of the Cluster, correct any failures" << endl << endl; exit(0); } @@ -1217,11 +1278,11 @@ cout << cmd << endl; void checkSuccess( bool pass) { - if (!pass) + if (!pass && check) { cout << endl; string answer = "y"; - prompt = "Failure Occurred, do you want to continue? (y,n) > "; + prompt = "Failure occurred, do you want to continue? (y,n) > "; pcommand = readline(prompt.c_str()); if (pcommand) { if (strlen(pcommand) > 0) answer = pcommand; From b60c45a9686c5b12c537614bb47b568247e2e320 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 31 Mar 2017 21:47:12 +0100 Subject: [PATCH 061/185] MCOL-653 Revert SUM(1) behaviour SUM(1) behaviour was changed as part of MCOL-301. But the original behaviour was correct. --- dbcon/mysql/ha_calpont_execplan.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 22aa4742b..c579cf7ec 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -3563,10 +3563,6 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) if (ac->aggOp() == AggregateColumn::COUNT) ac->aggOp(AggregateColumn::COUNT_ASTERISK); - // MCOL-301: treat SUM(1) as MAX(1) to get constant result - if (ac->aggOp() == AggregateColumn::SUM) - ac->aggOp(AggregateColumn::MAX); - ac->constCol(SRCP(buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError))); break; } @@ -3605,10 +3601,6 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) ReturnedColumn* rc = buildReturnedColumn(sfitemp, gwi, gwi.fatalParseError); if (dynamic_cast(rc)) { - // MCOL-301: treat SUM(1) as MAX(1) to get constant result - if (ac->aggOp() == AggregateColumn::SUM) - ac->aggOp(AggregateColumn::MAX); - //@bug5229. handle constant function on aggregate argument ac->constCol(SRCP(rc)); break; From f64dd0d602efa499013e1d177972b8cc767eaf76 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 14 Apr 2017 14:13:15 +0100 Subject: [PATCH 062/185] MCOL-529 Pool DBRM connections DBRM connections are reused so that we don't have a huge amount of TIME_WAIT sockets when there are large amounts of DML. Also applied to i_s.columnstore_files --- dbcon/mysql/is_columnstore_files.cpp | 51 ++---- utils/messageqcpp/CMakeLists.txt | 1 + utils/messageqcpp/inetstreamsocket.cpp | 40 +++++ utils/messageqcpp/inetstreamsocket.h | 7 + utils/messageqcpp/iosocket.h | 6 +- utils/messageqcpp/messagequeue.h | 3 + utils/messageqcpp/messagequeuepool.cpp | 205 +++++++++++++++++++++++++ utils/messageqcpp/messagequeuepool.h | 57 +++++++ utils/messageqcpp/socket.h | 3 + versioning/BRM/dbrm.cpp | 16 +- versioning/BRM/masterdbrmnode.cpp | 16 +- 11 files changed, 349 insertions(+), 56 deletions(-) create mode 100644 utils/messageqcpp/messagequeuepool.cpp create mode 100644 utils/messageqcpp/messagequeuepool.h diff --git a/dbcon/mysql/is_columnstore_files.cpp b/dbcon/mysql/is_columnstore_files.cpp index 2ddb393fe..e9479e254 100644 --- a/dbcon/mysql/is_columnstore_files.cpp +++ b/dbcon/mysql/is_columnstore_files.cpp @@ -33,6 +33,7 @@ #include "bytestream.h" #include "liboamcpp.h" #include "messagequeue.h" +#include "messagequeuepool.h" #include "we_messages.h" // Required declaration as it isn't in a MairaDB include @@ -81,15 +82,6 @@ static bool get_file_sizes(messageqcpp::MessageQueueClient *msgQueueClient, cons } } -static void cleanup(std::map &clients) -{ - for(std::map::iterator itr = clients.begin(); itr != clients.end(); itr++) - { - delete itr->second; - } -} - - static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) { BRM::DBRM *emp = new BRM::DBRM(); @@ -105,7 +97,6 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) off_t fileSize = 0; off_t compressedFileSize = 0; we_config.initConfigCache(); - std::map clients; messageqcpp::MessageQueueClient *msgQueueClient; oam::Oam oam_instance; int pmId = 0; @@ -143,37 +134,15 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) std::string DbRootPath = config->getConfig("SystemConfig", DbRootName.str()); fileSize = compressedFileSize = 0; snprintf(fullFileName, WriteEngine::FILE_NAME_SIZE, "%s/%s", DbRootPath.c_str(), oidDirName); - try - { - msgQueueClient = clients.at(iter->dbRoot); - } - catch (...) - { - msgQueueClient = NULL; - } - if (!msgQueueClient) - { - oam_instance.getDbrootPmConfig(iter->dbRoot, pmId); - std::ostringstream oss; - oss << "pm" << pmId << "_WriteEngineServer"; - try - { - msgQueueClient = new messageqcpp::MessageQueueClient(oss.str()); - } - catch (...) - { - delete msgQueueClient; - cleanup(clients); - delete emp; - return 1; - } - clients[iter->dbRoot] = msgQueueClient; - } - - + oam_instance.getDbrootPmConfig(iter->dbRoot, pmId); + std::ostringstream oss; + oss << "pm" << pmId << "_WriteEngineServer"; + std::string client = oss.str(); + msgQueueClient = messageqcpp::MessageQueueClientPool::getInstance(oss.str()); + if (!get_file_sizes(msgQueueClient, fullFileName, &fileSize, &compressedFileSize)) { - cleanup(clients); + messageqcpp::MessageQueueClientPool::releaseInstance(msgQueueClient); delete emp; return 1; } @@ -201,11 +170,13 @@ static int is_columnstore_files_fill(THD *thd, TABLE_LIST *tables, COND *cond) if (schema_table_store_record(thd, table)) { - cleanup(clients); + messageqcpp::MessageQueueClientPool::releaseInstance(msgQueueClient); delete emp; return 1; } iter++; + messageqcpp::MessageQueueClientPool::releaseInstance(msgQueueClient); + msgQueueClient = NULL; } } delete emp; diff --git a/utils/messageqcpp/CMakeLists.txt b/utils/messageqcpp/CMakeLists.txt index 25c3fa251..5fc8a39ab 100644 --- a/utils/messageqcpp/CMakeLists.txt +++ b/utils/messageqcpp/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ) set(messageqcpp_LIB_SRCS messagequeue.cpp + messagequeuepool.cpp bytestream.cpp socketparms.cpp inetstreamsocket.cpp diff --git a/utils/messageqcpp/inetstreamsocket.cpp b/utils/messageqcpp/inetstreamsocket.cpp index bfbb291b3..e03cfe109 100644 --- a/utils/messageqcpp/inetstreamsocket.cpp +++ b/utils/messageqcpp/inetstreamsocket.cpp @@ -70,6 +70,7 @@ either expressed or implied, of the FreeBSD Project. #include #include #include +#include #endif #include #include @@ -1070,5 +1071,44 @@ int InetStreamSocket::ping(const std::string& ipaddr, const struct timespec* tim return 0; } +bool InetStreamSocket::isConnected() const +{ + int error = 0; + socklen_t len = sizeof(error); + int retval = getsockopt(fSocketParms.sd(), SOL_SOCKET, SO_ERROR, &error, &len); + + if (error || retval) + return false; + + struct pollfd pfd[1]; + pfd[0].fd = fSocketParms.sd(); + pfd[0].events = POLLIN; + pfd[0].revents = 0; + + error = poll(pfd, 1, 0); + if ((error < 0) || (pfd[0].revents & (POLLHUP | POLLNVAL | POLLERR))) { + return false; + } + + return true; +} + +bool InetStreamSocket::hasData() const +{ + int count; + char buf[1]; + ssize_t retval; + ioctl(fSocketParms.sd(), FIONREAD, &count); + if (count) + return true; + + // EAGAIN | EWOULDBLOCK means the socket is clear. Anything else is data or error + retval = recv(fSocketParms.sd(), buf, 1, MSG_DONTWAIT); + if (retval & (EAGAIN | EWOULDBLOCK)) + return false; + + return true; +} + } //namespace messageqcpp diff --git a/utils/messageqcpp/inetstreamsocket.h b/utils/messageqcpp/inetstreamsocket.h index 1080bde46..4029a1fb1 100644 --- a/utils/messageqcpp/inetstreamsocket.h +++ b/utils/messageqcpp/inetstreamsocket.h @@ -196,6 +196,13 @@ public: */ EXPORT static int ping(const std::string& ipaddr, const struct timespec* timeout=0); + // Check if we are still connected + virtual bool isConnected() const; + + // Check if the socket still has data pending + + virtual bool hasData() const; + /* * allow test suite access to private data for OOB test */ diff --git a/utils/messageqcpp/iosocket.h b/utils/messageqcpp/iosocket.h index a2a8a85d8..0e937e404 100644 --- a/utils/messageqcpp/iosocket.h +++ b/utils/messageqcpp/iosocket.h @@ -174,7 +174,9 @@ public: */ virtual void connectionTimeout(const struct timespec* timeout) { fSocket->connectionTimeout(timeout); } - + inline virtual bool isConnected() const; + inline virtual bool hasData() const; + friend class ::MessageQTestSuite; protected: @@ -208,6 +210,8 @@ inline const SocketParms IOSocket::socketParms() const { idbassert(fSocket); ret inline void IOSocket::socketParms(const SocketParms& socketParms) { idbassert(fSocket); fSocket->socketParms(socketParms); } inline void IOSocket::setSocketImpl(Socket* socket) { delete fSocket; fSocket = socket; } inline const int IOSocket::getConnectionNum() const { return fSocket->getConnectionNum(); } +inline bool IOSocket::isConnected() const { return fSocket->isConnected(); } +inline bool IOSocket::hasData() const { return fSocket->hasData(); } /** * stream an IOSocket rep to any ostream diff --git a/utils/messageqcpp/messagequeue.h b/utils/messageqcpp/messagequeue.h index a52d69883..8de4df398 100644 --- a/utils/messageqcpp/messagequeue.h +++ b/utils/messageqcpp/messagequeue.h @@ -249,6 +249,9 @@ public: */ inline const bool isSameAddr(const MessageQueueClient& rhs) const; + bool isConnected() { return fClientSock.isConnected(); } + + bool hasData() { return fClientSock.hasData(); } /* * allow test suite access to private data for OOB test */ diff --git a/utils/messageqcpp/messagequeuepool.cpp b/utils/messageqcpp/messagequeuepool.cpp new file mode 100644 index 000000000..5b8c9862c --- /dev/null +++ b/utils/messageqcpp/messagequeuepool.cpp @@ -0,0 +1,205 @@ +/* Copyright (C) 2017 MariaDB Corporaton + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include +#include +#include +#include +#include "messagequeuepool.h" +#include "messagequeue.h" + +namespace messageqcpp { + +boost::mutex queueMutex; +// Make linker happy +std::multimap MessageQueueClientPool::clientMap; + +// 300 seconds idle until cleanup +#define MAX_IDLE_TIME 300 + +static uint64_t TimeSpecToSeconds(struct timespec* ts) +{ + return (uint64_t)ts->tv_sec + (uint64_t)ts->tv_nsec / 1000000000; +} + +MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &ip, uint64_t port) +{ + boost::mutex::scoped_lock lock(queueMutex); + + std::ostringstream oss; + oss << ip << "_" << port; + std::string searchString = oss.str(); + + MessageQueueClient *returnClient = MessageQueueClientPool::findInPool(searchString); + + // We found one, return it + if (returnClient != NULL) + { + return returnClient; + } + + // We didn't find one, create new one + ClientObject *newClientObject = new ClientObject(); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t nowSeconds = TimeSpecToSeconds(&now); + + newClientObject->client = new MessageQueueClient(ip, port); + newClientObject->inUse = true; + newClientObject->lastUsed = nowSeconds; + clientMap.insert(std::pair(searchString, newClientObject)); + return newClientObject->client; +} + +MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &module) +{ + boost::mutex::scoped_lock lock(queueMutex); + + MessageQueueClient *returnClient = MessageQueueClientPool::findInPool(module); + + // We found one, return it + if (returnClient != NULL) + { + return returnClient; + } + + // We didn't find one, create new one + ClientObject *newClientObject = new ClientObject(); + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t nowSeconds = TimeSpecToSeconds(&now); + + newClientObject->client = new MessageQueueClient(module); + newClientObject->inUse = true; + newClientObject->lastUsed = nowSeconds; + clientMap.insert(std::pair(module, newClientObject)); + return newClientObject->client; +} + +MessageQueueClient *MessageQueueClientPool::findInPool(const std::string &search) +{ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t nowSeconds = TimeSpecToSeconds(&now); + MessageQueueClient *returnClient = NULL; + + std::multimap::iterator it=clientMap.begin(); + + // Scan pool + while (it!=clientMap.end()) + { + ClientObject *clientObject = it->second; + uint64_t elapsedTime = nowSeconds - clientObject->lastUsed; + + // If connection hasn't been used for MAX_IDLE_TIME we probably don't need it so drop it + // Don't drop in use connections that have been in use a long time + if ((elapsedTime >= MAX_IDLE_TIME) && (!clientObject->inUse)) + { + delete clientObject->client; + delete clientObject; + // Do this so we don't invalidate current interator + std::multimap::iterator toDelete = it; + it++; + clientMap.erase(toDelete); + continue; + } + + if (!clientObject->inUse) + { + MessageQueueClient *client = clientObject->client; + + // If the unused socket isn't connected or has data pending read, destroy it + if (!client->isConnected() || client->hasData()) + { + delete client; + delete clientObject; + // Do this so we don't invalidate current interator + std::multimap::iterator toDelete = it; + it++; + clientMap.erase(toDelete); + continue; + } + + } + + // If connection matches store it for later, but keep scanning the pool for more timeout prunes + if (it->first.compare(search) == 0) + { + if ((returnClient == NULL) && (!clientObject->inUse)) + { + returnClient = clientObject->client; + clientObject->inUse = true; + return returnClient; + } + } + it++; + } + return NULL; +} + +void MessageQueueClientPool::releaseInstance(MessageQueueClient * client) +{ + // Scan pool for pointer and release + // Set the last used and mark as not in use + + if (client == NULL) + return; + + boost::mutex::scoped_lock lock(queueMutex); + std::multimap::iterator it=clientMap.begin(); + + while (it!=clientMap.end()) + { + if (it->second->client == client) + { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + uint64_t nowSeconds = TimeSpecToSeconds(&now); + it->second->inUse = false; + it->second->lastUsed = nowSeconds; + return; + } + it++; + } +} + +// WriteEngine needs this as it forces connections closed and can't reuse. Also good for connection errors +void MessageQueueClientPool::deleteInstance(MessageQueueClient * client) +{ + // Scan pool for pointer and delete + // Set the last used and mark as not in use + + if (client == NULL) + return; + + boost::mutex::scoped_lock lock(queueMutex); + std::multimap::iterator it=clientMap.begin(); + + while (it!=clientMap.end()) + { + if (it->second->client == client) + { + delete it->second->client; + delete it->second; + clientMap.erase(it); + return; + } + it++; + } + +} +} diff --git a/utils/messageqcpp/messagequeuepool.h b/utils/messageqcpp/messagequeuepool.h new file mode 100644 index 000000000..fc5576203 --- /dev/null +++ b/utils/messageqcpp/messagequeuepool.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2017 MariaDB Corporaton + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#ifndef MESSAGEQCPP_MESSAGEQUEUECLIENT_H +#define MESSAGEQCPP_MESSAGEQUEUECLIENT_H + +#include +#include "messagequeue.h" + +namespace messageqcpp { + + +struct ClientObject +{ + MessageQueueClient *client; + uint64_t lastUsed; + bool inUse; + + ClientObject() : + client(NULL), + lastUsed(0), + inUse(false) + {} +}; + +class MessageQueueClientPool +{ + public: + static MessageQueueClient *getInstance(const std::string &module); + static MessageQueueClient *getInstance(const std::string &ip, uint64_t port); + static void releaseInstance(MessageQueueClient * client); + static void deleteInstance(MessageQueueClient * client); + static MessageQueueClient *findInPool(const std::string &search); + + private: + MessageQueueClientPool() { }; + ~MessageQueueClientPool() { }; + + static std::multimap clientMap; +}; + +} +#endif //MESSAGEQCPP_MESSAGEQUEUECLIENT_H diff --git a/utils/messageqcpp/socket.h b/utils/messageqcpp/socket.h index f77304fc9..2c553c05b 100644 --- a/utils/messageqcpp/socket.h +++ b/utils/messageqcpp/socket.h @@ -158,6 +158,9 @@ public: */ virtual const bool isSameAddr(const Socket* rhs) const = 0; + virtual bool isConnected() const = 0; + virtual bool hasData() const = 0; + /* * allow test suite access to private data for OOB test */ diff --git a/versioning/BRM/dbrm.cpp b/versioning/BRM/dbrm.cpp index 47f02dd62..aa452d39f 100644 --- a/versioning/BRM/dbrm.cpp +++ b/versioning/BRM/dbrm.cpp @@ -40,6 +40,7 @@ #include "socketclosed.h" #include "configcpp.h" #include "sessionmanagerserver.h" +#include "messagequeuepool.h" #define DBRM_DLLEXPORT #include "dbrm.h" #undef DBRM_DLLEXPORT @@ -53,7 +54,7 @@ #endif #define DO_ERR_NETWORK \ - delete msgClient; \ + MessageQueueClientPool::releaseInstance(msgClient); \ msgClient = NULL; \ mutex.unlock(); \ return ERR_NETWORK; @@ -97,8 +98,7 @@ DBRM::DBRM(const DBRM& brm) DBRM::~DBRM() throw() { if (msgClient != NULL) - msgClient->shutdown(); - delete msgClient; + MessageQueueClientPool::releaseInstance(msgClient); } DBRM& DBRM::operator=(const DBRM& brm) @@ -742,7 +742,7 @@ reconnect: if (msgClient == NULL) try { - msgClient = new MessageQueueClient(masterName); + msgClient = MessageQueueClientPool::getInstance(masterName); } catch(exception &e) { cerr << "class DBRM failed to create a MessageQueueClient: " << @@ -766,7 +766,7 @@ reconnect: cerr << "DBRM::send_recv caught: " << e.what() << endl; if (firstAttempt) { firstAttempt = false; - delete msgClient; + MessageQueueClientPool::releaseInstance(msgClient); msgClient = NULL; goto reconnect; } @@ -776,7 +776,7 @@ reconnect: cerr << "DBRM::send_recv: controller node closed the connection" << endl; if (firstAttempt) { firstAttempt = false; - delete msgClient; + MessageQueueClientPool::releaseInstance(msgClient); msgClient = NULL; sleep(10); goto reconnect; @@ -3222,7 +3222,7 @@ bool DBRM::isDBRMReady() throw() { if (msgClient == NULL) { - msgClient = new MessageQueueClient(masterName); + msgClient = MessageQueueClientPool::getInstance(masterName); } if (msgClient->connect()) { @@ -3232,7 +3232,7 @@ bool DBRM::isDBRMReady() throw() catch (...) { } - delete msgClient; + MessageQueueClientPool::releaseInstance(msgClient); msgClient = NULL; sleep(1); } diff --git a/versioning/BRM/masterdbrmnode.cpp b/versioning/BRM/masterdbrmnode.cpp index 72900ee0a..46f49906f 100644 --- a/versioning/BRM/masterdbrmnode.cpp +++ b/versioning/BRM/masterdbrmnode.cpp @@ -32,7 +32,7 @@ #include "liboamcpp.h" #include "stopwatch.h" #include "masterdbrmnode.h" - +#include "messagequeuepool.h" // #define BRM_VERBOSE // minor improvement to code clarity... @@ -163,7 +163,8 @@ void MasterDBRMNode::initMsgQueues(config::Config *config) serverLock.unlock(); for (i = 1; i <= NumWorkers; i++) { snprintf(ctmp, 50, "DBRM_Worker%d", i); - slaves.push_back(new MessageQueueClient(ctmp, config)); + std::string module(ctmp); + slaves.push_back(MessageQueueClientPool::getInstance(module)); } } @@ -882,8 +883,8 @@ void MasterDBRMNode::finalCleanup() cerr << "Closing connections" << endl; #endif for (sIt = slaves.begin(); sIt != slaves.end(); sIt++) { - (*sIt)->shutdown(); - delete *sIt; + MessageQueueClientPool::releaseInstance(*sIt); + *sIt = NULL; } slaves.clear(); @@ -1036,8 +1037,8 @@ void MasterDBRMNode::doReload(messageqcpp::IOSocket *sock) } for (i = 0; i < (int) slaves.size(); i++) { - slaves[i]->shutdown(); - delete slaves[i]; + MessageQueueClientPool::releaseInstance(slaves[i]); + slaves[i] = NULL; } slaves.clear(); @@ -1045,7 +1046,8 @@ void MasterDBRMNode::doReload(messageqcpp::IOSocket *sock) for (i = 1; i <= NumWorkers; i++) { snprintf(ctmp, 50, "DBRM_Worker%d", i); - slaves.push_back(new MessageQueueClient(ctmp, config)); + std::string module(ctmp); + slaves.push_back(MessageQueueClientPool::getInstance(module)); } iSlave = slaves.end(); From 00fc9bc11682105f9b3d57bc440cb931816570b5 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 18 Apr 2017 09:57:12 +0100 Subject: [PATCH 063/185] MCOL-655 Enable debug symbols on releases Makes it easier to debug user core files --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2062f9aaf..df20c3e1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,8 +98,8 @@ endif() FOREACH(BUILD_TYPE RELEASE RELWITHDEBINFO MINSIZEREL) - SET(CMAKE_CXX_FLAGS_${BUILD_TYPE} "-g0 -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") - SET(CMAKE_C_FLAGS_${BUILD_TYPE} "-g0 -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") + SET(CMAKE_CXX_FLAGS_${BUILD_TYPE} "-g -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") + SET(CMAKE_C_FLAGS_${BUILD_TYPE} "-g -O3 -fno-strict-aliasing -Wall -fno-tree-vectorize -DDBUG_OFF -DHAVE_CONFIG_H") ENDFOREACH() SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3 -fno-tree-vectorize -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D_DEBUG -DHAVE_CONFIG_H") From 662e647e3658e2b3befd1be9cf981c23ba8d4c06 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 18 Apr 2017 10:02:33 -0500 Subject: [PATCH 064/185] remove columnstore tester --- .../postConfigure/columnstoreClusterTester | Bin 133248 -> 0 bytes .../columnstoreClusterTester.cpp | 1299 ----------------- 2 files changed, 1299 deletions(-) delete mode 100755 oamapps/postConfigure/columnstoreClusterTester delete mode 100644 oamapps/postConfigure/columnstoreClusterTester.cpp diff --git a/oamapps/postConfigure/columnstoreClusterTester b/oamapps/postConfigure/columnstoreClusterTester deleted file mode 100755 index 0dd69aad8c010dc8cf68084f55d9925af4386927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133248 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 WG?g%ia&|#eRHm!io0TmI{(k_e0!Bgr diff --git a/oamapps/postConfigure/columnstoreClusterTester.cpp b/oamapps/postConfigure/columnstoreClusterTester.cpp deleted file mode 100644 index d7a793456..000000000 --- a/oamapps/postConfigure/columnstoreClusterTester.cpp +++ /dev/null @@ -1,1299 +0,0 @@ -/* Copyright (C) 2016 MariaDB Corporaton - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; version 2 of - the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/****************************************************************************************** -* $Id: columnstoreClusterTester.cpp 64 2006-10-12 22:21:51Z dhill $ -* -* -******************************************************************************************/ -/** - * @file - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "liboamcpp.h" -#include "configcpp.h" -#include "alarmmanager.h" - -using namespace std; -using namespace oam; -using namespace config; -using namespace alarmmanager; - -#include "helpers.h" -using namespace installer; - -using namespace std; - -typedef struct ModuleIP_struct -{ - std::string IPaddress; - std::string status; -} ModuleIP; - -typedef std::vector ModuleIPList; - -char* pcommand = 0; -string prompt; - -void checkSuccess( bool pass); - -bool check = true; - -int main(int argc, char *argv[]) -{ - ModuleIPList moduleiplist; - - string IPaddresses = ""; - string OS = ""; - string user = ""; - string password = ""; - - for( int i = 1; i < argc; i++ ) - { - if( string("-h") == argv[i] || string("--help") == argv[i]) { - cout << endl; - cout << "This is the MariaDB Columnstore Cluster System Test tool." << endl; - cout << "It will run a set of test to check the checkup of the system." << endl; - cout << "This can be run prior to the install to make sure the servers/nodes" << endl; - cout << "are configured properly" << endl; - cout << "User will be prompted to provide the server/node IP Addresses, OS" << endl; - cout << "Root/Non-root user install name, and password" << endl << endl; - cout << "Items that are checked:" << endl; - cout << " Node ping test" << endl; - cout << " Node SSH test" << endl; - cout << " OS version" << endl; - cout << " Firewall settings" << endl; - cout << " Locale settings" << endl; - cout << " Dependent packages installed" << endl; - cout << " ColumnStore Port test" << endl << endl; - cout << "Usage: columnstoreClusterTester -h -i -i -u -p -c" << endl; - cout << " -h Help" << endl; - cout << " -i IP Addresses, starting with local (x.x.x.x,y.y.y.y)" << endl; - cout << " -o OS Version (centos6, centos7, debian8, suse12, ubuntu16)" << endl; - cout << " -u Username (root or 'non-root username')" << endl; - cout << " -p Password (User Password or 'ssh' if using SSH-KEYS)" << endl; - cout << " -c Continue on failures" << endl << endl; - cout << "Dependent package : 'nmap', 'readline', and 'boost' packages need to be installed locally" << endl; - exit (0); - } - else if( string("-i") == argv[i] ) { - i++; - if (i >= argc ) { - cout << " ERROR: IP Addresses not provided" << endl; - exit (1); - } - IPaddresses = argv[i]; - } - else if( string("-o") == argv[i] ) { - i++; - if (i >= argc ) { - cout << " ERROR: OS type not provided" << endl; - exit (1); - } - OS = argv[i]; - } - else if( string("-u") == argv[i] ) { - i++; - if (i >= argc ) { - cout << " ERROR: Username not provided" << endl; - exit (1); - } - user = argv[i]; - } - else if( string("-p") == argv[i] ) { - i++; - if (i >= argc ) { - cout << " ERROR: Password not provided" << endl; - exit (1); - } - password = argv[i]; - } - else if( string("-c") == argv[i] ) { - check = false; - } - } - - cout << endl << endl; - cout << "*** This is the MariaDB Columnstore Cluster System test tool ***" << endl << endl; - - if ( IPaddresses.empty() ) - { - cout << endl; - //get Ip Addresses - prompt = "Enter List of IP Addresses of each server/node starting with the local first (x.x.x.x,y.y.y.y) > "; - pcommand = readline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) IPaddresses = pcommand; - free(pcommand); - pcommand = 0; - } - } - - if ( IPaddresses.empty() ) - { - cout << "Error: no IP addresses where entered, exiting..." << endl; - exit (1); - } - else - { - boost::char_separator sep(",:"); - boost::tokenizer< boost::char_separator > tokens(IPaddresses, sep); - for ( boost::tokenizer< boost::char_separator >::iterator it = tokens.begin(); - it != tokens.end(); - ++it) - { - ModuleIP moduleip; - moduleip.IPaddress = *it; - if ( it == tokens.begin() ) - moduleip.status = "local"; - else - moduleip.status = "pass"; - moduleiplist.push_back(moduleip); - } - } - - if ( OS.empty() ) - { - cout << endl; - //get OS - prompt = "Enter OS version (centos6, centos7, debian8, suse12, ubuntu16) > "; - pcommand = readline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) OS = pcommand; - free(pcommand); - pcommand = 0; - } - } - - if ( OS.empty() ) - { - cout << "Error: no OS Version was entered, exiting..." << endl; - exit (1); - } - - if ( user.empty() ) - { - cout << endl; - //get User - prompt = "Enter Install user (root or 'non-root username') > "; - pcommand = readline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) user = pcommand; - free(pcommand); - pcommand = 0; - } - } - - if ( user.empty() ) - { - cout << "Error: no User type was entered, exiting..." << endl; - exit (1); - } - - - if ( password.empty() ) - { - cout << endl; - //get root password - prompt = "Enter User Password or 'ssh' if using SSH-KEYS, which is used to access other nodes > "; - pcommand = readline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) password = pcommand; - free(pcommand); - pcommand = 0; - } - } - - if ( password.empty() ) - { - cout << "Error: no password or 'ssh' was entered, exiting..." << endl; - exit (1); - } - - // - // ping test - // - cout << endl << "Run Ping access Test" << endl << endl; - - string cmdLine = "ping "; - string cmdOption = " -c 1 -w 5 >> /dev/null"; - string cmd; - - bool pass = true; - ModuleIPList::iterator list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - - if ( status == "local" ) - continue; - - cout << " Testing " + ipAddress + " : "; - cout.flush(); - - // perform login test - string cmd = "./remote_command.sh " + ipAddress + " " + password + " ls"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - cout << " PASSED" << endl; - else - { - ModuleIP moduleip; - moduleip.IPaddress = ipAddress; - moduleip.status = "failed"; - - moduleiplist.erase(list); - moduleiplist.insert(list, moduleip); - - cout << " FAILED, check connection" << endl; - pass = false; - } - } - - checkSuccess(pass); - - // - // ssh login test - // - cout << endl << "Run Login access Test" << endl << endl; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "local" || status == "failed" ) - continue; - - cout << " Testing " + ipAddress + " : "; - cout.flush(); - - // perform ping test - cmd = cmdLine + ipAddress + cmdOption; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - cout << " PASSED" << endl; - else - { - cout << " FAILED, check password or ssh-key setup" << endl; - pass = false; - } - } - - checkSuccess(pass); - - // - // OS compare - // - cout << endl << "Getting OS versions" << endl << endl; - - string OScmd = "./os_check.sh > /tmp/os_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - int rtnCode = system(OScmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " Local OS Version : "; - cout.flush(); - system("cat /tmp/os_check"); - } - else - { - cout << " FAILED, os_check.sh failed, check /tmp/os_check" << endl; - pass = false; - } - } - else - { - cout << " OS version for " << ipAddress << " : "; - cout.flush(); - - // push os_check to remote node - string cmd = "./remote_scp_put.sh " + ipAddress + " " + password + " os_check.sh 1 > /tmp/put_os_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " '" + OScmd + " 1' > /tmp/run_os_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/os_check 1 > /tmp/get_os_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - system("cat os_check"); - - //compare with local - int rtnCode = system("diff /tmp/os_check os_check > /dev/null 2>&1"); - if (WEXITSTATUS(rtnCode) != 0) - { - cout << " FAILED, doesn't match local servers OS version" << endl; - pass = false; - } - - unlink("os_check"); - } - else - { - cout << " FAILED, check /tmp/get_os_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_os_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, /tmp/put_os_check.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - - - // - // Locale compare - // - cout << endl << "Getting Locale" << endl << endl; - - string Localecmd = "locale | grep LANG= > /tmp/locale_check 2>&1"; - string LocaleREMOTEcmd = "'locale | grep LANG= > /tmp/locale_check 2>&1'"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - int rtnCode = system(Localecmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " Local Locale Setting : "; - cout.flush(); - system("cat /tmp/locale_check"); - } - else - { - cout << " FAILED, locale command failed, check /tmp/locale_check" << endl; - pass = false; - } - } - else - { - cout << " Getting Locale for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + LocaleREMOTEcmd + " 1 > /tmp/run_locale.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/locale_check 1 > /tmp/get_locale_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - // get local again - system(Localecmd.c_str()); - - system("cat locale_check"); - - //compare with local - int rtnCode = system("diff /tmp/locale_check locale_check > /dev/null 2>&1"); - if (WEXITSTATUS(rtnCode) != 0) - { - cout << " FAILED, doesn't match local servers Locale" << endl; - pass = false; - } - - unlink("locale_check"); - } - else - { - cout << " FAILED, check /tmp/get_locale_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_locale.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - - - // - // Check SELINUX - // - cout << endl << "Checking Firewall setting - SELINUX should be disabled" << endl << endl; - - string SELINUXcmd = "cat /etc/selinux/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; - string SELINUXREMOTEcmd = "'cat /etc/selinux/config' > /tmp/selinux_check 2>&1"; - string SELINUXREMOTECHECKcmd = "cat selinux_check | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - cout << " Local SELINUX setting check : "; - cout.flush(); - - //check if config file exist - ifstream oldFile ("/etc/selinex/config"); - if (!oldFile) - cout << " PASSED, is disabled" << endl; - else - { - int rtnCode = system(SELINUXcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - } - } - else - { - cout << " Checking SELINUX for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " 'ls /etc/selinex/config' 1 > /tmp/check_selinux.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " PASSED, it is disabled" << endl; - } - else - { - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + SELINUXREMOTEcmd + " 1 > /tmp/run_selinux.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/selinux_check 1 > /tmp/get_selinux_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(SELINUXREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, /etc/selinex/config is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - - unlink("selinux_check"); - } - else - { - cout << " FAILED, check /tmp/get_selinux_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_selinux.log" << endl; - pass = false; - } - } - } - } - - checkSuccess(pass); - - // - // Check IPTABLES for Centos6 - // - if ( OS == "centos6") - { - cout << endl << "Checking Firewall setting - IPTABLES should be disabled" << endl << endl; - - string IPTABLEScmd = "chkconfig | grep iptables | grep on > /tmp/iptables_check 2>&1"; - string IPTABLESREMOTEcmd = "chkconfig > /tmp/iptables_check 2>&1"; - string IPTABLESREMOTECHECKcmd = "cat iptables_check | grep iptables | grep on > /tmp/iptables_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - cout << " Local IPTABLES setting check : "; - cout.flush(); - - int rtnCode = system(IPTABLEScmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, iptables is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - } - else - { - cout << " Checking IPTABLES for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + IPTABLESREMOTEcmd + " 1 > /tmp/run_iptables.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check 1 > /tmp/get_iptables_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(IPTABLESREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, iptables is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - - unlink("iptables_check"); - } - else - { - cout << " FAILED, check /tmp/get_iptables_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_iptables.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - } - - // - // Check UFW for ubuntu 16 - // - if ( OS == "ubuntu16") - { - cout << endl << "Checking Firewall setting - UFW should be disabled" << endl << endl; - - string UFWcmd = "chkconfig | grep ufw | grep on > /tmp/ufw_check 2>&1"; - string UFWREMOTEcmd = "chkconfig > /tmp/ufw_check 2>&1"; - string UFWREMOTECHECKcmd = "cat ufw_check | grep ufw | grep on > /tmp/ufw_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - cout << " Local UFW setting check : "; - cout.flush(); - - int rtnCode = system(UFWcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, ufw is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - } - else - { - cout << " Checking UFW for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + UFWREMOTEcmd + " 1 > /tmp/run_ufw.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/iptables_check 1 > /tmp/get_ufw_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(UFWREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, ufw is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - - unlink("ufw_check"); - } - else - { - cout << " FAILED, check /tmp/get_ufw_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_ufw.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - } - - // - // Check filewalls for SUSE - // - if ( OS == "suse12") - { - cout << endl << "Checking Firewall setting - rcSuSEfirewall2 should be disabled" << endl << endl; - - string rcSuSEfirewall2cmd = "/sbin/rcSuSEfirewall2 status | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; - string rcSuSEfirewall2REMOTEcmd = "'/sbin/rcSuSEfirewall2 status' > /tmp/rcSuSEfirewall2_check 2>&1"; - string rcSuSEfirewall2REMOTECHECKcmd = "cat rcSuSEfirewall2_check | grep active > /tmp/rcSuSEfirewall2_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - cout << " Local rcSuSEfirewall2 setting check : "; - cout.flush(); - - int rtnCode = system(rcSuSEfirewall2cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, rcSuSEfirewall2 is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - } - else - { - cout << " Checking rcSuSEfirewall2 for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + rcSuSEfirewall2REMOTEcmd + " 1 > /tmp/run_rcSuSEfirewall2.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check 1 > /tmp/get_rcSuSEfirewall2_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(rcSuSEfirewall2REMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, rcSuSEfirewall2 is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - - unlink("rcSuSEfirewall2_check"); - } - else - { - cout << " FAILED, check /tmp/rcSuSEfirewall2_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_rcSuSEfirewall2.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - } - - // - // Check filewalls for non-Centos6 - // - if ( OS != "centos6") - { - cout << endl << "Checking Firewall setting - firewalld should be disabled" << endl << endl; - - string FIREWALLDcmd = "systemctl status firewalld | grep running > /tmp/firewalld_check 2>&1"; - string FIREWALLDREMOTEcmd = "'systemctl status firewalld > /tmp/firewalld_check 2>&1'"; - string FIREWALLDREMOTECHECKcmd = "cat firewalld_check | grep running > /tmp/firewalld_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - { - cout << " Local firewalld setting check : "; - cout.flush(); - - int rtnCode = system(FIREWALLDcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, firewalld is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - } - else - { - cout << " Checking firewalld for " + ipAddress + " : "; - cout.flush(); - - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + FIREWALLDREMOTEcmd + " 1 > /tmp/run_firewalld.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/firewalld_check 1 > /tmp/get_firewalld_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(FIREWALLDREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - { - cout << " FAILED, firewalld is enabled, please disable" << endl; - pass = false; - } - else - { - cout << " PASSED, it is disabled" << endl; - } - - unlink("firewalld_check"); - } - else - { - cout << " FAILED, check /tmp/get_firewalld_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_firewalld.log" << endl; - pass = false; - } - } - } - - checkSuccess(pass); - } - - // - // Dependent package install check - // - - bool nmapPass = true; - - //centos - - const std::string centosPgk[] = { - "boost", - "expect", - "perl", - "perl-DBI", - "openssl", - "zlib", - "file", - "sudo", - "perl-DBD-MySQL", - "libaio", - "rsync", - "snappy", - "net-tools", - "" - }; - - if ( OS == "centos6" || OS == "centos7") - { - cout << endl << "Checking Dependent Package installations" << endl << endl; - - string pgkcmd1 = "yum list installed "; - string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; - string pgkREMOTEcmd1 = "'yum list installed "; - string pgkREMOTEcmd2 = " > /tmp/pkg_check 2>&1'"; - string pgkREMOTECHECKcmd = "cat pkg_check | grep Installed > /tmp/pkg_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - if ( status == "local" ) - cout << " Local Dependent Package Installations checking" << endl; - else - cout << " Checking Dependent Package Installations for " + ipAddress << endl; - - for( int i = 0;;i++) - { - if ( centosPgk[i] == "" ) - { - // end of section list, check for nmap which is needed for port testing - string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; - - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; - nmapPass = false; - } - - break; - } - - string pkg = centosPgk[i]; - - string pkgCMD = pgkcmd1 + pkg + pgkcmd2; - string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; - - if ( status == "local" ) - { - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - } - else - { - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pkg.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pkg_check 1 > /tmp/get_pkg_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(pgkREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - - unlink("pkg_check"); - } - else - { - cout << " FAILED, check /tmp/get_pkg_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_pkg.log" << endl; - pass = false; - } - } - } - - if (pass) - cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; - } - - checkSuccess(pass); - } - - // suse - if ( OS == "suse12" ) - { - cout << endl << "Checking Dependent Package installations" << endl << endl; - - string pgkcmd1 = "zypper list installed "; - string pgkcmd2 = " | grep Installed > /tmp/pkg_check 2>&1"; - string pgkREMOTEcmd1 = "zypper list installed "; - string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; - string pgkREMOTECHECKcmd = "cat pgk_check | grep Installed > /tmp/pgk_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - cout << " Checking Dependent Package Installations for " + ipAddress << endl; - - for( int i = 0;;i++) - { - if ( centosPgk[i] == "" ) - { - // end of section list, check for nmap which is needed for port testing - string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; - - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; - nmapPass = false; - } - - break; - } - - string pkg = centosPgk[i]; - - string pkgCMD = pgkcmd1 + pkg + pgkcmd2; - string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; - - if ( status == "local" ) - { - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - } - else - { - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pgk.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check 1 > /tmp/get_pgk_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(pgkREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - - unlink("pgk_check"); - } - else - { - cout << " FAILED, check /tmp/pgk_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_pgk.log" << endl; - pass = false; - } - } - } - - if (pass) - cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; - } - - checkSuccess(pass); - } - - - //ubuntu and debian - - const std::string ubuntuPgk[] = { - "libboost-all-dev", - "expect", - "libdbi-perl", - "perl", - "openssl", - "libreadline-dev", - "file", - "sudo", - "libaio", - "rsync", - "libsnappy1", - "net-tools", - "" - }; - - if ( OS == "ubuntu16" || OS == "debian8" ) - { - cout << endl << "Checking Dependent Package installations" << endl << endl; - - string pgkcmd1 = "dpkg -s "; - string pgkcmd2 = " | grep installed > /tmp/pkg_check 2>&1"; - string pgkREMOTEcmd1 = "dpkg -s "; - string pgkREMOTEcmd2 = " > /tmp/pgk_check 2>&1"; - string pgkREMOTECHECKcmd = "cat pgk_check | grep installed > /tmp/pgk_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" ) - continue; - - cout << " Checking Dependent Package Installations for " + ipAddress << endl; - - for( int i = 0;;i++) - { - if ( ubuntuPgk[i] == "" ) - { - // end of section list, check for nmap which is needed for port testing - string pkgCMD = pgkcmd1 + "nmap" + pgkcmd2; - - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package 'nmap' isn't installed, please install for port testing" << endl; - nmapPass = false; - } - - break; - } - - string pkg = ubuntuPgk[i]; - - string pkgCMD = pgkcmd1 + pkg + pgkcmd2; - string pkgREMOTECMD = pgkREMOTEcmd1 + pkg + pgkREMOTEcmd2; - - if ( status == "local" ) - { - int rtnCode = system(pkgCMD.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - } - else - { - //run command - string cmd = "./remote_command.sh " + ipAddress + " " + password + " " + pkgREMOTECMD + " 1 > /tmp/run_pgk.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 1 ) - { - //get results - string cmd = "./remote_scp_get.sh " + ipAddress + " " + password + " /tmp/pgk_check 1 > /tmp/get_pgk_check.log"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - { - int rtnCode = system(pgkREMOTECHECKcmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0 ) - if (WEXITSTATUS(rtnCode) != 0 ) - { - cout << " FAILED, Package " + pkg + " isn't installed, please install" << endl; - pass = false; - } - - unlink("pgk_check"); - } - else - { - cout << " FAILED, check /tmp/pgk_check.log" << endl; - pass = false; - } - } - else - { - cout << " FAILED, check /tmp/run_pgk.log" << endl; - pass = false; - } - } - } - - if (pass) - cout << " Passed, all MariaDB Columnstore dependent packages are installed" << endl << endl; - } - - checkSuccess(pass); - } - - // port testing - if (!nmapPass) - { - cout << endl << "Package 'nmap' isn't installed, skipping the port testing" << endl; - exit (0); - } - - cout << endl << "Checking MariaDb ColumnStore Port availibility" << endl << endl; - - string nmapcmd1 = "nmap "; - string nmapcmd2 = " -p 8602 | grep 'closed unknown' > /tmp/nmap_check 2>&1"; - - pass = true; - list = moduleiplist.begin(); - for (; list != moduleiplist.end() ; list++) - { - string ipAddress = (*list).IPaddress; - string status = (*list).status; - if ( status == "failed" || status == "local") - continue; - - cout << " Checking Port (8602) using 'nmap' for " + ipAddress + " : "; - cout.flush(); - - string nmapcmd = nmapcmd1 + ipAddress + nmapcmd2; - - //run command - int rtnCode = system(nmapcmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0 ) - cout << " FAILED, iptables is enabled, please disable" << endl; - else - cout << " PASSED" << endl; - } - - cout << endl << endl << "Finished Validation of the Cluster, correct any failures" << endl << endl; - exit(0); - -} - - -void checkSuccess( bool pass) -{ - if (!pass && check) - { - cout << endl; - string answer = "y"; - prompt = "Failure occurred, do you want to continue? (y,n) > "; - pcommand = readline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) answer = pcommand; - free(pcommand); - pcommand = 0; - } - - if ( answer == "n" ) - { - cout << "Exiting..." << endl; - exit (1); - } - } -} From b0902e4721593acf2c20f37b64459c5b553142ea Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 18 Apr 2017 10:03:41 -0500 Subject: [PATCH 065/185] removed columnstore tester --- oamapps/postConfigure/CMakeLists.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/oamapps/postConfigure/CMakeLists.txt b/oamapps/postConfigure/CMakeLists.txt index 095f24c5e..ee8e835aa 100644 --- a/oamapps/postConfigure/CMakeLists.txt +++ b/oamapps/postConfigure/CMakeLists.txt @@ -56,14 +56,5 @@ target_link_libraries(mycnfUpgrade ${ENGINE_LDFLAGS} readline ncurses ${ENGINE_ install(TARGETS mycnfUpgrade DESTINATION ${ENGINE_BINDIR} COMPONENT platform) -########### next target ############### - -set(columnstoreClusterTester_SRCS columnstoreClusterTester.cpp) - -add_executable(columnstoreClusterTester ${columnstoreClusterTester_SRCS}) - -target_link_libraries(columnstoreClusterTester ${ENGINE_LDFLAGS} readline ncurses ${SNMP_LIBRARIES} ${ENGINE_EXEC_LIBS}) - -install(TARGETS columnstoreClusterTester DESTINATION ${ENGINE_BINDIR} COMPONENT platform) From f5881ce6ddcf47db223138e5b38d3ab800986838 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 25 Apr 2017 23:40:39 +0100 Subject: [PATCH 066/185] MCOL-683 Fix nested ADDDATE and DATE_FORMAT MariaDB sends us a UTF8 length which we shortern because we think this is a microsecond length. We need to keep this length. --- dbcon/mysql/ha_calpont_impl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index f86a8a73c..de6cae449 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -457,7 +457,8 @@ int fetchNextRow(uchar *buf, cal_table_info& ti, cal_connection_info* ci) * At a later date we should set this more intelligently * based on the result set. */ - if ((*f)->field_length > 19) + /* MCOL-683: UTF-8 datetime no msecs is 57, this sometimes happens! */ + if (((*f)->field_length > 19) && ((*f)->field_length != 57)) (*f)->field_length = strlen(tmp); Field_varstring* f2 = (Field_varstring*)*f; From dc4f38a877ba971298065c3a25760a9647ca1128 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 27 Apr 2017 17:32:19 +0100 Subject: [PATCH 067/185] MCOL-686 Fix BETWEEN performance BETWEEN was executing as a function on each row which meant that extent elimination couldn't happen. We now execute as a predicate function instead. --- dbcon/mysql/ha_calpont_execplan.cpp | 44 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index c579cf7ec..9edb74866 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -1121,40 +1121,37 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->rcWorkStack.pop(); ReturnedColumn* lhs = gwip->rcWorkStack.top(); gwip->rcWorkStack.pop(); + ReturnedColumn* filterCol = gwip->rcWorkStack.top(); gwip->rcWorkStack.pop(); // pop gwip->scsp; Item_func_opt_neg* inp = (Item_func_opt_neg*)ifp; - ConstantFilter* cf = 0; + SimpleFilter* sfr = 0; + SimpleFilter* sfl = 0; if (inp->negated) { sop.reset(new PredicateOperator(">")); - sop->setOpType(gwip->scsp->resultType(), rhs->resultType()); - cf = new ConstantFilter(sop, gwip->scsp->clone(), rhs); - sop.reset(new LogicOperator("or")); - cf->op(sop); + sop->setOpType(filterCol->resultType(), rhs->resultType()); + sfr = new SimpleFilter(sop, filterCol, rhs); sop.reset(new PredicateOperator("<")); - sop->setOpType(gwip->scsp->resultType(), rhs->resultType()); + sop->setOpType(filterCol->resultType(), lhs->resultType()); + sfl = new SimpleFilter(sop, filterCol->clone(), lhs); + ParseTree* ptp = new ParseTree(new LogicOperator("or")); + ptp->left(sfr); + ptp->right(sfl); + gwip->ptWorkStack.push(ptp); } else { sop.reset(new PredicateOperator("<=")); - sop->setOpType(gwip->scsp->resultType(), rhs->resultType()); - cf = new ConstantFilter(sop, gwip->scsp->clone(), rhs); - sop.reset(new LogicOperator("and")); - cf->op(sop); + sop->setOpType(filterCol->resultType(), rhs->resultType()); + sfr = new SimpleFilter(sop, filterCol, rhs); sop.reset(new PredicateOperator(">=")); - sop->setOpType(gwip->scsp->resultType(), rhs->resultType()); + sop->setOpType(filterCol->resultType(), lhs->resultType()); + sfl = new SimpleFilter(sop, filterCol->clone(), lhs); + ParseTree* ptp = new ParseTree(new LogicOperator("and")); + ptp->left(sfr); + ptp->right(sfl); + gwip->ptWorkStack.push(ptp); } - cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs)); - cf->functionName(gwip->funcName); - String str; - // @bug5811. This filter string is for cross engine to use. - // Use real table name. - ifp->print(&str, QT_INFINIDB_DERIVED); - //IDEBUG(cout << str.c_ptr() << endl); - if (str.ptr()) - cf->data(str.c_ptr()); - ParseTree* ptp = new ParseTree(cf); - gwip->ptWorkStack.push(ptp); return true; } else if (ifp->functype() == Item_func::IN_FUNC) @@ -2721,7 +2718,8 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non else if ((functor = funcExp->getFunctor(funcName))) { // where clause isnull still treated as predicate operator - if ((funcName == "isnull" || funcName == "isnotnull") && + // MCOL-686: between also a predicate operator so that extent elimination can happen + if ((funcName == "isnull" || funcName == "isnotnull" || funcName == "between") && (gwi.clauseType == WHERE || gwi.clauseType == HAVING)) return NULL; if (funcName == "in" || funcName == " IN " || funcName == "between") From dc9e812ac2c2f51815f3bca3eb0db8d3d020ead0 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 8 May 2017 15:37:19 -0500 Subject: [PATCH 068/185] add startup script for buildbot --- build/columnstore_startup.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 build/columnstore_startup.sh diff --git a/build/columnstore_startup.sh b/build/columnstore_startup.sh new file mode 100755 index 000000000..0c2b6b903 --- /dev/null +++ b/build/columnstore_startup.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# $Id: columnstore_startup.sh 3705 2013-08-07 19:47:20Z dhill $ +# +# columnstore_startup.sh steps for columnstore single server startup after install + +prefix=/usr/local +installdir=$prefix/mariadb/columnstore + +quiet=0 + +for arg in "$@"; do + if [ `expr -- "$arg" : '--prefix='` -eq 9 ]; then + prefix="`echo $arg | awk -F= '{print $2}'`" + installdir=$prefix/mariadb/columnstore + elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then + installdir="`echo $arg | awk -F= '{print $2}'`" + prefix=`dirname $installdir` + else + echo "columnstore_startup.sh: ignoring unknown argument: $arg" 1>&2 + fi +done + +$installdir/bin/post-install --installdir=/usr/local/mariadb/columnstore +echo -e "1\n1\n1\n1\n1\n1\n" | $installdir/bin/postConfigure -i $installdir +exit 0 From 122dbdcbb117d8a017d0b780de847eb318759b72 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 9 May 2017 10:23:20 +0100 Subject: [PATCH 069/185] MCOL-656 Fix LIKE on non-dict CHAR/VARCHAR The LIKE part of the query for non-dict CHAR/VARCHAR was converted to an INT based on the length of the column. So on a 2 byte CHAR a LIKE of '%05%' was truncated to '%0' which is a very different query. We should not cast this to INT because we could use a LIKE of > 8 bytes on a non-dict column. This patch turns LIKE into an expressionStep which cater for longer strings rather than a simpleFilter. --- dbcon/joblist/jlf_execplantojoblist.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dbcon/joblist/jlf_execplantojoblist.cpp b/dbcon/joblist/jlf_execplantojoblist.cpp index bd0ad322c..108ebc978 100644 --- a/dbcon/joblist/jlf_execplantojoblist.cpp +++ b/dbcon/joblist/jlf_execplantojoblist.cpp @@ -1663,10 +1663,7 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) jsv.push_back(sjstep); } } - else if ( CalpontSystemCatalog::CHAR != ct.colDataType && - CalpontSystemCatalog::VARCHAR != ct.colDataType && - CalpontSystemCatalog::VARBINARY != ct.colDataType && - ConstantColumn::NULLDATA != cc->type() && + else if ( ConstantColumn::NULLDATA != cc->type() && (cop & COMPARE_LIKE) ) // both like and not like { return doExpressionFilter(sf, jobInfo); From 4f3968fb36640eee5123f57c8fa756f470625c70 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 9 May 2017 11:57:28 +0100 Subject: [PATCH 070/185] MCOL-657 Support the <=> operator This converts <=> into "a = b OR (a IS NULL AND b IS NULL)" --- dbcon/mysql/ha_calpont_execplan.cpp | 41 ++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 9edb74866..2a8c590e0 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -1392,6 +1392,44 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->ptWorkStack.push(pt); #endif } + else if (ifp->functype() == Item_func::EQUAL_FUNC) + { + // a = b OR (a IS NULL AND b IS NULL) + idbassert (gwip->rcWorkStack.size() >= 2); + ReturnedColumn* rhs = gwip->rcWorkStack.top(); + gwip->rcWorkStack.pop(); + ReturnedColumn* lhs = gwip->rcWorkStack.top(); + gwip->rcWorkStack.pop(); + SimpleFilter* sfn1 = 0; + SimpleFilter* sfn2 = 0; + SimpleFilter* sfo = 0; + // b IS NULL + ConstantColumn *nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA); + sop.reset(new PredicateOperator("isnull")); + sop->setOpType(lhs->resultType(), rhs->resultType()); + sfn1 = new SimpleFilter(sop, rhs, nlhs1); + ParseTree* ptpl = new ParseTree(sfn1); + // a IS NULL + ConstantColumn *nlhs2 = new ConstantColumn("", ConstantColumn::NULLDATA); + sop.reset(new PredicateOperator("isnull")); + sop->setOpType(lhs->resultType(), rhs->resultType()); + sfn2 = new SimpleFilter(sop, lhs, nlhs2); + ParseTree* ptpr = new ParseTree(sfn2); + // AND them both + ParseTree* ptpn = new ParseTree(new LogicOperator("and")); + ptpn->left(ptpl); + ptpn->right(ptpr); + // a = b + sop.reset(new PredicateOperator("=")); + sop->setOpType(lhs->resultType(), lhs->resultType()); + sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone()); + // OR with the NULL comparison tree + ParseTree* ptp = new ParseTree(new LogicOperator("or")); + ptp->left(sfo); + ptp->right(ptpn); + gwip->ptWorkStack.push(ptp); + return true; + } else //std rel ops (incl "like") { if (gwip->rcWorkStack.size() < 2) @@ -3035,7 +3073,8 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non ifp->functype() == Item_func::IN_FUNC || ifp->functype() == Item_func::ISNULL_FUNC || ifp->functype() == Item_func::ISNOTNULL_FUNC || - ifp->functype() == Item_func::NOT_FUNC) + ifp->functype() == Item_func::NOT_FUNC || + ifp->functype() == Item_func::EQUAL_FUNC) { return NULL; } From 64e86242c20e6e529a005573194c9043a17e47d9 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 9 May 2017 14:47:46 -0500 Subject: [PATCH 071/185] MCOL-709 changes --- build/columnstore_startup.sh | 6 +++++- oam/install_scripts/post-install | 13 +++++++++---- oam/install_scripts/post-mysql-install | 4 ++-- oamapps/postConfigure/postConfigure.cpp | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/build/columnstore_startup.sh b/build/columnstore_startup.sh index 0c2b6b903..76d2f3b48 100755 --- a/build/columnstore_startup.sh +++ b/build/columnstore_startup.sh @@ -23,4 +23,8 @@ done $installdir/bin/post-install --installdir=/usr/local/mariadb/columnstore echo -e "1\n1\n1\n1\n1\n1\n" | $installdir/bin/postConfigure -i $installdir -exit 0 +if [ $? -eq 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 9df86005c..c09e7d58a 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -25,6 +25,7 @@ for arg in "$@"; do elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then installdir="`echo $arg | awk -F= '{print $2}'`" prefix=`dirname $installdir` + prefix=`dirname $prefix` elif [ `expr -- "$arg" : '--user='` -eq 7 ]; then user="`echo $arg | awk -F= '{print $2}'`" elif [ `expr -- "$arg" : '--quiet'` -eq 7 ]; then @@ -36,13 +37,17 @@ for arg in "$@"; do fi done -if [ $installdir != "/usr/local/mariadb/columnstore" ]; then +echo $installdir +echo $prefix +exit 0 + +if [ $user != "root" ]; then export COLUMNSTORE_INSTALL_DIR=$installdir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$installdir/lib else # add library config file - /bin/cp -f $installdir/bin/columnstore.conf /etc/ld.so.conf.d/. - ldconfig + /bin/cp -f $installdir/bin/columnstore.conf /etc/ld.so.conf.d/. >/dev/null 2>&1 + ldconfig >/dev/null 2>&1 fi #check 64-bit OS compatiable @@ -224,7 +229,7 @@ else sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore - sed -i -e s@prefix=/usr/local@prefix=$HOME@g $installdir/bin/* + sed -i -e s@prefix=/usr/local@prefix=$prefix@g $installdir/bin/* fi #check if MariaDB Columnstore system logging was setup diff --git a/oam/install_scripts/post-mysql-install b/oam/install_scripts/post-mysql-install index dc9b7ca67..8183ff5fb 100755 --- a/oam/install_scripts/post-mysql-install +++ b/oam/install_scripts/post-mysql-install @@ -79,8 +79,8 @@ for arg in "$@"; do fi done -if [ $installdir != "/usr/local/mariadb/columnstore" ]; then - sudo ldconfig +if [ $USER != "root" ]; then + sudo ldconfig >/dev/null 2>&1 export COLUMNSTORE_INSTALL_DIR=$installdir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$COLUMNSTORE_INSTALL_DIR/lib:$COLUMNSTORE_INSTALL_DIR/mysql/lib/mysql else diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 2d2115ce0..f96f210e0 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -408,7 +408,7 @@ int main(int argc, char *argv[]) //check if MariaDB ColumnStore is up and running if (oam.checkSystemRunning()) { cout << "MariaDB ColumnStore is running, can't run postConfigure while MariaDB ColumnStore is running. Exiting.." << endl; - exit (0); + exit (1); } //if InitialInstallFlag is set, then an install has been done From e125db220d76c66d2a5b58de6decdaf1d8b7b4e9 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 10 May 2017 09:53:32 -0500 Subject: [PATCH 072/185] removed echo and early exit commands --- oam/install_scripts/post-install | 4 ---- 1 file changed, 4 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index c09e7d58a..6831724f5 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -37,10 +37,6 @@ for arg in "$@"; do fi done -echo $installdir -echo $prefix -exit 0 - if [ $user != "root" ]; then export COLUMNSTORE_INSTALL_DIR=$installdir export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$installdir/lib From fc07ee29f3c33835488cb8b49bffdc6fc97b5b5e Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 10 May 2017 11:45:31 +0100 Subject: [PATCH 073/185] MCOL-707 Fix ExeMgr's memory accounting ExeMgr uses ResourceManager to count memory usage. If a usage exceeded error occurs the counting wasn't reset and subsequent usage attempts in the same ExeMgr thread would error. This patch moves the in-class accounting for GroupConcat and others so that it happens before the error is detected. The memory usage counter is then decremented correctly on the class destructor. --- dbcon/joblist/groupconcat.cpp | 6 +++--- dbcon/joblist/limitedorderby.cpp | 6 +++--- dbcon/joblist/windowfunctionstep.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dbcon/joblist/groupconcat.cpp b/dbcon/joblist/groupconcat.cpp index 2d93d0f96..831200110 100644 --- a/dbcon/joblist/groupconcat.cpp +++ b/dbcon/joblist/groupconcat.cpp @@ -712,13 +712,13 @@ void GroupConcatOrderBy::processRow(const rowgroup::Row& row) fDataQueue.push(fData); uint64_t newSize = fRowsPerRG * fRowGroup.getRowSize(); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fData.reinit(fRowGroup, fRowsPerRG); fRowGroup.setData(&fData); @@ -911,6 +911,7 @@ void GroupConcatNoOrder::initialize(const rowgroup::SP_GroupConcat& gcc) fConcatColumns.push_back((*(i++)).second); uint64_t newSize = fRowsPerRG * fRowGroup.getRowSize(); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) @@ -918,7 +919,6 @@ void GroupConcatNoOrder::initialize(const rowgroup::SP_GroupConcat& gcc) throw IDBExcept(fErrorCode); } - fMemSize += newSize; //fData.reset(new uint8_t[fRowGroup.getDataSize(fRowsPerRG)]); fData.reinit(fRowGroup, fRowsPerRG); fRowGroup.setData(&fData); @@ -947,13 +947,13 @@ void GroupConcatNoOrder::processRow(const rowgroup::Row& row) { uint64_t newSize = fRowsPerRG * fRowGroup.getRowSize(); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fDataQueue.push(fData); fData.reinit(fRowGroup, fRowsPerRG); diff --git a/dbcon/joblist/limitedorderby.cpp b/dbcon/joblist/limitedorderby.cpp index 1b85c4b36..a87dc5335 100644 --- a/dbcon/joblist/limitedorderby.cpp +++ b/dbcon/joblist/limitedorderby.cpp @@ -124,13 +124,13 @@ void LimitedOrderBy::processRow(const rowgroup::Row& row) { fDataQueue.push(fData); uint64_t newSize = fRowsPerRG * fRowGroup.getRowSize(); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fData.reinit(fRowGroup, fRowsPerRG); fRowGroup.setData(&fData); fRowGroup.resetRowGroup(0); @@ -170,13 +170,13 @@ void LimitedOrderBy::finalize() if (fStart != 0) { uint64_t newSize = fRowsPerRG * fRowGroup.getRowSize(); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fData.reinit(fRowGroup, fRowsPerRG); fRowGroup.setData(&fData); fRowGroup.resetRowGroup(0); @@ -196,13 +196,13 @@ void LimitedOrderBy::finalize() if (fRowGroup.getRowCount() >= fRowsPerRG) { tempQueue.push(fData); + fMemSize += newSize; if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fData.reinit(fRowGroup, fRowsPerRG); //fData.reset(new uint8_t[fRowGroup.getDataSize(fRowsPerRG)]); fRowGroup.setData(&fData); diff --git a/dbcon/joblist/windowfunctionstep.cpp b/dbcon/joblist/windowfunctionstep.cpp index 4d56b6cc8..76fce7179 100644 --- a/dbcon/joblist/windowfunctionstep.cpp +++ b/dbcon/joblist/windowfunctionstep.cpp @@ -782,9 +782,9 @@ void WindowFunctionStep::execute() { fInRowGroupData.push_back(rgData); uint64_t memAdd = fRowGroupIn.getSizeWithStrings() + rowCnt * sizeof(RowPosition); + fMemUsage += memAdd; if (fRm.getMemory(memAdd, fSessionMemLimit) == false) throw IDBExcept(ERR_WF_DATA_SET_TOO_BIG); - fMemUsage += memAdd; for (uint64_t j = 0; j < rowCnt; ++j) { @@ -917,9 +917,9 @@ void WindowFunctionStep::doFunction() while (((i = nextFunctionIndex()) < fFunctionCount) && !cancelled()) { uint64_t memAdd = fRows.size() * sizeof(RowPosition); + fMemUsage += memAdd; if (fRm.getMemory(memAdd, fSessionMemLimit) == false) throw IDBExcept(ERR_WF_DATA_SET_TOO_BIG); - fMemUsage += memAdd; fFunctions[i]->setCallback(this, i); (*fFunctions[i].get())(); } From 50e36147305f46588c786dd227fcafbecaf1d49d Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 10 May 2017 22:59:52 +0100 Subject: [PATCH 074/185] MCOL-707 Fix memory accounting for ORDER BY Missed off window function order by memory accounting in my first commit for MCOL-707. Fixed in the same way --- utils/windowfunction/idborderby.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index 2add7c7f2..1375af542 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -339,13 +339,13 @@ void IdbOrderBy::initialize(const RowGroup& rg) IdbCompare::initialize(rg); uint64_t newSize = fRowsPerRG * rg.getRowSize(); - if (!fRm->getMemory(newSize, fSessionMemLimit)) + fMemSize += newSize; + if (!fRm->getMemory(newSize, fSessionMemLimit)) { cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__; throw IDBExcept(fErrorCode); } - fMemSize += newSize; fData.reinit(fRowGroup, fRowsPerRG); fRowGroup.setData(&fData); fRowGroup.resetRowGroup(0); From 0e68d90318a35b5f4d7d7596d96361ce684ab3d0 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 12 May 2017 08:52:20 -0500 Subject: [PATCH 075/185] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b30bf9338..2546d3801 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.0.8 -MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely +#MariaDB ColumnStore Storage/Execution engine 1.0.9 +MariaDB ColumnStore 1.0.9 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.22 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.0.8 is an GA release. +#MariaDB ColumnStore 1.0.9 is an GA release. This is the first MariaDB ColumnStore release. #Building From d4509f14ea69a8caeb932a8c9472ae4bbd5c0bcc Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 12 May 2017 08:52:55 -0500 Subject: [PATCH 076/185] Update README --- README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index b5545b633..15a0bc7d9 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.0.8 -MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely +This is MariaDB ColumnStore 1.0.9 +MariaDB ColumnStore 1.0.9 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.22 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.0.8 is an GA release. This is the first MariaDB +MariaDB ColumnStore 1.0.9 is an GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. From d5078663c8f9c7fb80ff7a4be2bcc4082df74444 Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 15 May 2017 10:15:16 -0500 Subject: [PATCH 077/185] MCOL-699 - fix getdisks output --- oamapps/mcsadmin/mcsadmin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index 8e304cc6e..375b21c96 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -8342,7 +8342,11 @@ void printModuleDisk(ModuleDisk moduledisk) moduledisk.diskusage[i].DeviceName.find(etcdir, 0) == string::npos ) { cout.setf(ios::left); cout.width(31); - cout << moduledisk.diskusage[i].DeviceName; + if (moduledisk.diskusage[i].DeviceName.length() > 29) { + cout << "..." + moduledisk.diskusage[i].DeviceName.substr(moduledisk.diskusage[i].DeviceName.length()-26); + } else { + cout << moduledisk.diskusage[i].DeviceName; + } cout.width(14); cout << moduledisk.diskusage[i].TotalBlocks; cout.width(17); From ed5f51b5934b2545f31a150317d19b46cbf2b018 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 17 May 2017 10:35:50 +0100 Subject: [PATCH 078/185] MCOL-719 Add date/datetime to func_least/greatest Support was missing and int casting caused unexpected results --- utils/funcexp/func_greatest.cpp | 38 +++++++++++++++++++++++++++++++++ utils/funcexp/func_least.cpp | 38 +++++++++++++++++++++++++++++++++ utils/funcexp/functor_all.h | 20 +++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/utils/funcexp/func_greatest.cpp b/utils/funcexp/func_greatest.cpp index 6e680c529..753c2f03f 100644 --- a/utils/funcexp/func_greatest.cpp +++ b/utils/funcexp/func_greatest.cpp @@ -159,6 +159,44 @@ IDB_Decimal Func_greatest::getDecimalVal(Row& row, return greatestStr; } +int32_t Func_greatest::getDateIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& ct) +{ + int32_t str = fp[0]->data()->getDateIntVal(row, isNull); + + int32_t greatestStr = str; + for (uint32_t i = 1; i < fp.size(); i++) + { + int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull); + + if ( greatestStr < str1 ) + greatestStr = str1; + } + + return greatestStr; +} + +int64_t Func_greatest::getDatetimeIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& ct) +{ + int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull); + + int64_t greatestStr = str; + for (uint32_t i = 1; i < fp.size(); i++) + { + int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull); + + if ( greatestStr < str1 ) + greatestStr = str1; + } + + return greatestStr; +} + } // namespace funcexp // vim:ts=4 sw=4: diff --git a/utils/funcexp/func_least.cpp b/utils/funcexp/func_least.cpp index 3ec8b703f..5eeb24c0c 100644 --- a/utils/funcexp/func_least.cpp +++ b/utils/funcexp/func_least.cpp @@ -137,6 +137,44 @@ IDB_Decimal Func_least::getDecimalVal(Row& row, return leastStr; } +int32_t Func_least::getDateIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct) +{ + int32_t str = fp[0]->data()->getDateIntVal(row, isNull); + + int32_t leastStr = str; + for (uint32_t i = 1; i < fp.size(); i++) + { + int32_t str1 = fp[i]->data()->getDateIntVal(row, isNull); + + if ( leastStr > str1 ) + leastStr = str1; + } + + return leastStr; +} + +int64_t Func_least::getDatetimeIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct) +{ + int64_t str = fp[0]->data()->getDatetimeIntVal(row, isNull); + + int64_t leastStr = str; + for (uint32_t i = 1; i < fp.size(); i++) + { + int64_t str1 = fp[i]->data()->getDatetimeIntVal(row, isNull); + + if ( leastStr > str1 ) + leastStr = str1; + } + + return leastStr; +} + } // namespace funcexp diff --git a/utils/funcexp/functor_all.h b/utils/funcexp/functor_all.h index 29969136e..db7b8a491 100644 --- a/utils/funcexp/functor_all.h +++ b/utils/funcexp/functor_all.h @@ -267,6 +267,16 @@ public: FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); + + int32_t getDateIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); + + int64_t getDatetimeIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); }; @@ -299,6 +309,16 @@ public: FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); + + int32_t getDateIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); + + int64_t getDatetimeIntVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); }; From 472b2bd861731ba0fb7517f52f7ba75dad879c77 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 18 May 2017 15:11:43 -0500 Subject: [PATCH 079/185] update version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b51c8091e..e737f4599 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=9 +COLUMNSTORE_VERSION_PATCH=10 COLUMNSTORE_VERSION_RELEASE=1 From 6c93fe5496e6b80b203994850881cc4548f8ede9 Mon Sep 17 00:00:00 2001 From: David Hill Date: Fri, 19 May 2017 17:22:29 -0500 Subject: [PATCH 080/185] add cluster tester --- cpackEngineRPM.cmake | 2 + oam/install_scripts/remote_command.sh | 38 +- oam/install_scripts/remote_scp_get.sh | 19 +- oam/install_scripts/remote_scp_put.sh | 15 +- utils/CMakeLists.txt | 2 +- utils/clusterTester/CMakeLists.txt | 5 + .../clusterTester/columnstoreClusterTester.sh | 1055 ++++++++++++++++ utils/clusterTester/david.tar.gz | Bin 0 -> 7608 bytes .../david/columnstoreClusterTester.sh | 1077 +++++++++++++++++ utils/clusterTester/david/os_detect.sh | 40 + utils/clusterTester/david/remote_command.sh | 92 ++ utils/clusterTester/david/remote_scp_get.sh | 58 + utils/clusterTester/david/remote_scp_put.sh | 57 + utils/clusterTester/os_detect.sh | 40 + 14 files changed, 2478 insertions(+), 22 deletions(-) mode change 100644 => 100755 oam/install_scripts/remote_scp_put.sh create mode 100644 utils/clusterTester/CMakeLists.txt create mode 100755 utils/clusterTester/columnstoreClusterTester.sh create mode 100644 utils/clusterTester/david.tar.gz create mode 100755 utils/clusterTester/david/columnstoreClusterTester.sh create mode 100755 utils/clusterTester/david/os_detect.sh create mode 100755 utils/clusterTester/david/remote_command.sh create mode 100755 utils/clusterTester/david/remote_scp_get.sh create mode 100755 utils/clusterTester/david/remote_scp_put.sh create mode 100755 utils/clusterTester/os_detect.sh diff --git a/cpackEngineRPM.cmake b/cpackEngineRPM.cmake index e5030c4fb..f567aa40d 100644 --- a/cpackEngineRPM.cmake +++ b/cpackEngineRPM.cmake @@ -215,6 +215,8 @@ SET(CPACK_RPM_platform_USER_FILELIST "/usr/local/mariadb/columnstore/post/test-002.sh" "/usr/local/mariadb/columnstore/post/test-003.sh" "/usr/local/mariadb/columnstore/post/test-004.sh" +"/usr/local/mariadb/columnstore/bin/os_detect.sh" +"/usr/local/mariadb/columnstore/bin/columnstoreClusterTester.sh" ${ignored}) SET(CPACK_RPM_libs_USER_FILELIST diff --git a/oam/install_scripts/remote_command.sh b/oam/install_scripts/remote_command.sh index 6878bcf22..4525a4ed3 100755 --- a/oam/install_scripts/remote_command.sh +++ b/oam/install_scripts/remote_command.sh @@ -10,7 +10,7 @@ # Argument 5 - Remote user name (optional) # Argument 6 - Force a tty to be allocated (optional) set stty_init {cols 512 -opost}; -set timeout 30 +set timeout 10 set SERVER [lindex $argv 0] set PASSWORD [lindex $argv 1] set COMMAND [lindex $argv 2] @@ -33,7 +33,7 @@ if { $TTYOPT != "" } { } log_user $DEBUG spawn -noecho /bin/bash -expect -re {[$#] } +#expect -re {[$#] } if { $PASSWORD == "ssh" } { set PASSWORD "" @@ -42,8 +42,9 @@ if { $PASSWORD == "ssh" } { # # send command # -send "ssh $TTY $USERNAME@$SERVER $COMMAND\n" +send "ssh -v $TTY $USERNAME@$SERVER '$COMMAND'\n" expect { + "cannot access" { exit 1} "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1} "service not known" { send_user " FAILED: Invalid Host\n" ; exit 1} "ssh: connect to host" { send_user " FAILED: Invalid Host\n" ; exit 1 } @@ -57,14 +58,35 @@ expect { } "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } - -re {[$#] } { exit 0 } + "command not found" { exit 3 } +# -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } } expect { - -re {[$#] } { exit 0 } - "Permission denied" { send_user " FAILED: Invalid password\n" ; exit 1 } + "command not found" { exit 3 } +# -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + "cannot access" { exit 1} + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } + "(y or n)" { send "y\n" - expect -re {[$#] } { exit 0 } - } + "command not found" { exit 3 } +# expect -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + } } exit 0 diff --git a/oam/install_scripts/remote_scp_get.sh b/oam/install_scripts/remote_scp_get.sh index d361a951f..aee668b13 100755 --- a/oam/install_scripts/remote_scp_get.sh +++ b/oam/install_scripts/remote_scp_get.sh @@ -6,7 +6,7 @@ # Argument 1 - Remote Server Host Name or IP address # Argument 2 - Remote Server root password # Argument 3 - Command -set timeout 30 +set timeout 10 set USERNAME $env(USER)"@" set SERVER [lindex $argv 0] set PASSWORD [lindex $argv 1] @@ -22,9 +22,12 @@ if { $PASSWORD == "ssh" } { # # send command # -expect -re {[$#] } -send "scp $USERNAME$SERVER:$FILE .\n" +#expect -re {[$#] } +send "scp -v $USERNAME$SERVER:$FILE .\n" expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "100%" { send_user "DONE\n" ; exit 0 } "authenticity" { send "yes\n" expect { "word: " { send "$PASSWORD\n" } @@ -38,16 +41,18 @@ expect { "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } + "scp:" { send_user "FAILED\n" ; exit 1 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } } expect { - "100%" { send_user "DONE\n" } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "100%" { send_user "DONE\n" ; exit 0 } "scp:" { send_user "FAILED\n" ; exit 1 } - "Permission denied" { send_user "FAILED: Invalid password\n" ; exit 1 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } "No such file or directory" { send_user "FAILED: No such file or directory\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } } -#sleep to make sure it's finished -sleep 5 exit 0 diff --git a/oam/install_scripts/remote_scp_put.sh b/oam/install_scripts/remote_scp_put.sh old mode 100644 new mode 100755 index 31b3aa552..7eb6c1ecb --- a/oam/install_scripts/remote_scp_put.sh +++ b/oam/install_scripts/remote_scp_put.sh @@ -22,9 +22,11 @@ if { $PASSWORD == "ssh" } { # # send command # -expect -re "# " -send "scp $FILE $USERNAME$SERVER:$FILE\n" +send "scp -v $FILE $USERNAME$SERVER:$FILE\n" expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + -re "100%" { send_user "DONE\n" ; sleep 2; exit 0 } -re "authenticity" { send "yes\n" expect { -re "word: " { send "$PASSWORD\n" } @@ -39,16 +41,17 @@ expect { -re "word: " { send "$PASSWORD\n" } -re "passphrase" { send "$PASSWORD\n" } -re "WARNING:" { send "rm -f /root/.ssh/known_hosts" ; exit 1 } + -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } } expect { - -re "100%" { send_user "DONE\n" } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + -re "100%" { send_user "DONE\n" ; sleep 2 ; exit 0 } -re "scp:" { send_user "FAILED\n" ; exit 1 } - -re "Permission denied" { send_user "FAILED: Invalid password\n" ; exit 1 } + -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } -re "No such file or directory" { send_user "FAILED: Invalid file\n" ; exit 1 } -re "Connection refused" { send_user "FAILED: Connection refused\n" ; exit 1 } -re "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } } -#sleep to make sure it's finished -sleep 5 exit 0 diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 744f6b40e..59f5ee250 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -24,4 +24,4 @@ add_subdirectory(idbhdfs) add_subdirectory(winport) add_subdirectory(thrift) add_subdirectory(querytele) - +add_subdirectory(clusterTester) diff --git a/utils/clusterTester/CMakeLists.txt b/utils/clusterTester/CMakeLists.txt new file mode 100644 index 000000000..ef3830c3e --- /dev/null +++ b/utils/clusterTester/CMakeLists.txt @@ -0,0 +1,5 @@ + +install(PROGRAMS columnstoreClusterTester.sh + os_detect.sh + DESTINATION ${ENGINE_BINDIR} COMPONENT platform) + diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh new file mode 100755 index 000000000..bfb174d7e --- /dev/null +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -0,0 +1,1055 @@ +#!/bin/bash + +bold=$(tput bold) +normal=$(tput sgr0) + +IPADDRESSES="" +OS="" +PASSWORD="ssh" +CHECK=true +REPORTPASS=true +LOGFILE="" + +OS_LIST=("centos6" "centos7" "debian8" "suse12" "ubuntu16") + +NODE_IPADDRESS="" + +checkContinue() { + + if [ "$CHECK" = false ]; then + return 0 + fi + + echo "" + read -p "Failure occurred, do you want to continue? (y,n) > " answer + case ${answer:0:1} in + y|Y ) + return 0 + ;; + * ) + exit + ;; + esac +} + +### +# Print Fucntions +### + +helpPrint () { + ################################################################################ + echo "" + echo "This is the MariaDB ColumnStore Cluster System Test tool." + echo "" + echo "It will run a set of test to validate the setup of the MariaDB Columnstore system." + echo "This can be run prior to the install of MariaDB ColumnStore to make sure the" + echo "servers/nodes are configured properly. It should be run as the user of the planned" + echo "install. Meaning if MariaDB ColumnStore is going to be installed as root user," + echo "then run from root user. Also the assumption is that the servers/node have be" + echo "setup based on the Preparing for ColumnStore Installation." + echo "It should also be run on the server that is designated as Performance Module #1." + echo "This is the same server where the MariaDB ColumnStore package would be installed" + echo " and where the install script would be executed from, postConfigure." + echo "" + echo "Additional information on Tool is documented at:" + echo "" + echo "https://mariadb.com/kb/en/mariadb/*****/" + echo "" + echo "Items that are checked:" + echo " Node Ping test" + echo " Node SSH test" + echo " ColumnStore Port test" + echo " OS version" + echo " Locale settings" + echo " Firewall settings" + echo " Date/time settings" + echo " Dependent packages installed" + echo " For non-root user install - test permissions on /tmp and /dev/shm" + echo "" + echo "Usage: $0 [options]" + echo "OPTIONS:" + echo " -h,--help Help" + echo " --ipaddr=[ipaddresses] Remote Node IP-Addresses/Hostnames, if not provide, will only check local node" + echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" + echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, suse12, ubuntu16)" + echo " --password=[password] Provide a user password. (Default: ssh-keys setup will be assumed)" + echo " -c,--continue Continue on failures" + echo " --logfile=[fileName] Output results to a log file" + echo "" + echo "NOTE: Dependent package : 'nmap' and 'expect' packages need to be installed locally" + echo "" +} + +# Parse command line options. +while getopts hc-: OPT; do + case "$OPT" in + h) + echo $USAGE + helpPrint + exit 0 + ;; + c) + CHECK=false + ;; + -) LONG_OPTARG="${OPTARG#*=}" + ## Parsing hack for the long style of arguments. + case $OPTARG in + help ) + helpPrint + exit 0 + ;; + continue ) + CHECK=false + ;; + ipaddr=?* ) + IPADDRESSES="$LONG_OPTARG" + ;; + os=?* ) + OS="$LONG_OPTARG" + match=false + for SUPPORTED_OS in "${OS_LIST[@]}"; do + if [ $SUPPORTED_OS == "$OS" ]; then + match=true + break; + fi + done + + if [ $match == "false" ] ; then + echo "" + echo "OS version not-supported, please re-run and provide the OS from list of support OSs " + for SUPPORTED_OS in "${OS_LIST[@]}"; do + echo "$SUPPORTED_OS" + done + echo "" + exit 1 + fi + + ;; + password=?* ) + PASSWORD="$LONG_OPTARG" + ;; + logfile=?* ) + LOGFILE="$LONG_OPTARG" + exec 1<>$LOGFILE + exec 2>&1 + ;; + ipaddr* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + os* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + password* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + continue* ) + echo "No arg allowed for --$OPTARG option" >&2 + exit 1 + ;; + logfile* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + help* ) + helpPrint + exit 0 + ;; + '' ) + break ;; # "--" terminates argument processing + * ) + echo "Illegal option --$OPTARG" >&2 + exit 1 + ;; + esac + ;; + \?) + # getopts issues an error message + echo $USAGE >&2 + exit 1 + ;; + esac +done + +# Remove the switches we parsed above. +shift `expr $OPTIND - 1` + +if [ "$IPADDRESSES" != "" ]; then + #parse IP Addresses into an array + IFS=',' + read -ra NODE_IPADDRESS <<< "$IPADDRESSES" + + if ! type expect > /dev/null 2>&1 ; then + echo "expect is not installed. Please install and rerun." + exit 1 + fi + + if ! type nmap > /dev/null 2>&1; then + echo "nmap is not installed. Please install and rerun." + exit 1 + fi +fi + +checkLocalOS() +{ + echo "** Validate local OS is supported" + echo "" + + #get local OS + `./os_detect.sh > /tmp/os_detect 2>&1` + if [ "$?" -eq 0 ]; then + localOS=`cat /tmp/os_detect | grep "Operating System name" | cut -f2 -d '"'` + echo "Local Node OS System Name : $localOS" + + if [ "$OS" != "" ] ; then + echo "" + echo "Local Node OS Versions doesn't match the command line OS argument" + echo "Contining using the Detected Local Node OS Version" + OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` + + echo "Local Node OS Version : $OS" + else + OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` + fi + else + localOS=`cat /tmp/os_detect | grep "Operating System name" | cut -f2 -d '"'` + echo "Local Node OS System Name : $localOS" + + if [ "$OS" == "" ] ; then + echo "" + echo "Operating System name doesn't match any of the supported OS's" + echo "" + if [ $LOGFILE != "" ] ; then + exit 1 + fi + + echo "Please select from this OS list or enter 'exit'" + for SUPPORTED_OS in "${OS_LIST[@]}"; do + echo " $SUPPORTED_OS" + done + + echo "" + read -p "Enter OS or 'exit' > " answer + if [ $answer == 'exit' ] ; then + exit 1 + fi + match=false + for SUPPORTED_OS in "${OS_LIST[@]}"; do + if [ $SUPPORTED_OS == $answer ] ; then + OS=$answer + match=true + break; + fi + done + + if [ $match == "false" ] ; then + echo "OS version unknown, please re-run and provide the OS in the command line --os" + exit 1 + fi + else + echo "${bold}Warning${normal}: Local Node OS version detected is not supported and different than the enter OS Version" + fi + fi +} + +checkLocalDir() +{ + if [ "$USER" != "root" ]; then + # Non-root User directory permissions check + # + echo "" + echo "** Run Non-root User directory permissions check on Local Node" + echo "" + + #remove any check tmp files from previous runs + `sudo rm -f /tmp/*_check > /dev/null 2>&1` + + #check /tmp and /dev/shm + pass=true + `touch /tmp/cs_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node permission test on /tmp : Passed" + `rm -f /tmp/cs_check` + else + echo "Local Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" + exit 1 + fi + + `touch /dev/shm/cs_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node permission test on /dev/shm : Passed" + `rm -f /dev/shm/cs_check` + else + echo "Local Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" + pass=false + REPORTPASS=false + fi + fi +} + +checkPing() +{ + # ping test + # + echo "" + echo "** Run Ping access Test to remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + + `ping $ipadd -c 1 -w 5 > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo $ipadd " Node Passed ping test" + else + echo $ipadd " Node ${bold}Failed${normal} ping test, correct and retest" + exit 1 + fi + done +} + +checkSSH() +{ + # Login test + # + echo "" + echo "** Run SSH Login access Test to remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD ls 1 > /dev/null 2>&1`; + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + if [ $PASSWORD == "ssh" ] ; then + echo $ipadd " Node Passed SSH login test using ssh-keys" + else + echo $ipadd " Node Passed SSH login test using user password" + fi + else + if [ $PASSWORD == "ssh" ] ; then + echo $ipadd " Node ${bold}Failed${normal} SSH login test using ssh-keys" + else + echo $ipadd " Node ${bold}Failed${normal} SSH login test using user password" + fi + exit 1 + fi + done +} + +checkRemoteDir() +{ + # + # remove old _check tmp files from remote servers + + `sudo rm -f /tmp/*_check > /dev/null 2>&1` + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + done + + if [ "$USER" != "root" ]; then + # Non-root User directory permissions check + # + echo "" + echo "** Run Non-root User directory permissions check on remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "$ipadd Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" + exit 1 + else + echo "$ipadd Node permission test on /tmp : Passed" + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + + `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "$ipadd Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" + pass=false + REPORTPASS=false + else + echo "$ipadd Node permission test on /dev/shm : Passed" + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi + fi +} + +checkOS() +{ + # Os check + # + echo "" + echo "** Run OS check - OS version needs to be the same on all nodes" + echo "" + + echo "Local Node OS Version : $localOS" + echo "" + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check" + else + `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + remoteOS=`cat os_detect | grep "Operating System name" | cut -f2 -d '"'` + echo "$ipadd Node OS Version : $remoteOS" + if [ $localOS != $remoteOS ]; then + echo "${bold}Failed${normal}, $ipadd has a different OS than local node" + pass=false + REPORTPASS=false + fi + rm -f os_detect + fi + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkLocale() +{ + # Locale check + # + echo "" + echo "** Run Locale check - Locale needs to be the same on all nodes" + echo "" + + #get local Locale + `locale | grep LANG= > /tmp/locale_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node Locale : `cat /tmp/locale_check`" + else + echo "Error running 'locale' command on local node" + fi + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + echo "$ipadd Node Locale : `cat locale_check`" + `diff /tmp/locale_check locale_check > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd has a different Locale setting than local node" + pass=false + REPORTPASS=false + fi + `rm -f locale_check` + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkSELINUX() +{ + # SELINUX check + # + echo "" + echo "** Run SELINUX check - Setting should to be disabled on all nodes" + echo "" + + pass=true + #check local SELINUX + if [ -f /etc/selinux/config ]; then + `cat /etc/selinux/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node SELINUX setting is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "Local Node SELINUX setting is Not Enabled" + fi + else + echo "Local Node SELINUX setting is Not Enabled" + fi + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "$ipadd Node SELINUX setting is Not Enabled" + else + `cat config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd SELINUX setting is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "$ipadd Node SELINUX setting is Not Enabled" + fi + `rm -f config` + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkFirewalls() +{ + # FIREWALL checks + # + echo "" + echo "** Run Firewall Services check - Firewall Services should to be disabled on all nodes" + echo "" + + declare -a FIREWALL_LIST=("iptables" "ufw" "firewalld" "firewall") + + fpass=true + #check local FIREWALLS + `chkconfig > /tmp/firewall_check 2>&1` + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `cat /tmp/firewall_check | grep $firewall | grep on > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in chkconfig, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + `systemctl status $firewall > /tmp/firewall1_check 2>&1` + `cat /tmp/firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + if $pass ; then + echo "Local Node $firewall service is Not Enabled" + fi + done + + if ! $fpass; then + checkContinue + fi + + echo "" + fpass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'chkconfig > /tmp/firewall_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `cat firewall_check | grep $firewall | grep on > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in chkconfig, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + `rm -f firewall1_check` + fi + fi + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + done + + `rm -f firewall_check` + fi + else + # 'sysconfig not on remote node + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + `rm -f firewall1_check` + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + fi + fi + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + done + fi + + echo "" + done + + if ! $fpass; then + checkContinue + fi + + if [ $OS == "suse12" ]; then + # rcSuSEfirewall2 check + # + echo "" + echo "** Run rcSuSEfirewall2 check - Service should to be disabled on all nodes" + echo "" + + pass=true + #check local IPTABLES + `/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "Local Node rcSuSEfirewall2 service is Not Enabled" + fi + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] ; then + echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "$ipadd Node rcSuSEfirewall2 service is Not Enabled" + fi + done + + if ! $pass; then + checkContinue + fi + fi +} + +checkPorts() +{ + # port test + # + echo "" + echo "** Run MariaDB ColumnStore Port (8600-8620) availibility test" + echo "" + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + + `nmap $ipadd -p 8600-8620 | grep 'closed unknown' > /dev/null` + if [ "$?" -eq 0 ]; then + echo $ipadd " Node Passed port test" + else + echo $ipadd " Node ${bold}Failed${normal} port test, check and disable any firwalls that were reported enabled" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkTime() +{ + # Time check + # + echo "" + echo "** Run Date/Time check - Date/Time should be within 10 seconds on all nodes" + echo "" + + pass=true + #get local epoch time + localTime=`date +%s` + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'date +%s > /tmp/time_check' > /tmp/time_check` + rc="$?" + if [ $rc -ne 0 ] ; then + echo $ipadd " Node ${bold}Failed${normal} date/time check failed, check /tmp/time_check" + pass=false + REPORTPASS=false + else + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + remoteTime=`cat time_check` + timeDiff=`echo "$(($remoteTime-$localTime))"` + range=10 + if [ $timeDiff -gt $range ] || [ $timeDiff -lt -$range ] ; then + echo $ipadd " Node ${bold}Failed${normal}, $ipadd Node date/time is more than 10 seconds away from local node" + pass=false + else + echo "Passed: $ipadd Node date/time is within 10 seconds of local node" + fi + fi + fi + done + `rm -f time_check` + + if ! $pass; then + checkContinue + fi +} + +checkPackages() +{ + # + # now check packaging on local and remote nodes + # + + echo "" + echo "** Run MariaDB ColumnStore Dependent Package Check" + echo "" + + declare -a CENTOS_PKG=("boost" "expect" "perl" "perl-DBI" "openssl" "zlib" "file" "sudo" "perl-DBD-MySQL" "libaio" "rsync" "snappy" "net-tools") + + if [ "$OS" == "centos6" ] || [ "$OS" == "centos7" ]; then + if [ ! `which yum 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}yum${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${CENTOS_PKG[@]}"; do + if [ $OS == "centos6" ] && [ "$PKG" == "boost" ]; then + `ls /usr/lib/libboost_regex.so > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node ${bold}boost libraries${normal} not installed" + pass=false + REPORTPASS=false + fi + else + `yum list installed "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep Installed > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + fi + done + fi + + if [ $pass == true ] ; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${CENTOS_PKG[@]}"; do + if [ $OS == "centos6" ] && [ $PKG == "boost" ]; then + `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + if [ $? -ne 0 ] ; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}boost libraries${normal} not installed" + pass=false + REPORTPASS=false + fi + else + `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 2 ] ; then + echo "${bold}Failed${normal}, $ipadd Node, 'yum' not installed" + pass=false + REPORTPASS=false + break + elif [ $rc -eq 1 ] ; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + pass=true + fi + echo "" + done + fi + fi + + declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools") + + if [ "$OS" == "suse12" ]; then + if [ ! `which rpm 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${SUSE_PKG[@]}"; do + `rpm -qi "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep "not installed" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${SUSE_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -ne 0 ] ; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + pass=true + fi + echo "" + done + fi + fi + + declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "snappy" "net-tools") + + if [ "$OS" == "ubuntu16" ] ; then + if [ ! `which dpkg 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${UBUNTU_PKG[@]}"; do + `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${UBUNTU_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" + pass=false + break + else + `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi + + `rm -f pkg_check` + fi + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + pass=true + fi + echo "" + done + fi + fi + + declare -a DEBIAN_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "libsnappy1" "net-tools") + + if [ "$OS" == "debian8" ]; then + if [ ! `which dpkg 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${DEBIAN_PKG[@]}"; do + `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${DEBIAN_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 2 ] ; then + echo "${bold}Failed${normal}, $ipadd Node, 'dpkg' not installed" + pass=false + REPORTPASS=false + break + elif [ $rc -eq 1 ] ; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + pass=true + fi + echo "" + done + fi + fi +} + +echo "" +echo "*** This is the MariaDB Columnstore Cluster System test tool ***" +echo "" + +checkLocalOS +checkLocalDir +if [ "$IPADDRESSES" != "" ]; then + checkPing + checkSSH + checkRemoteDir + checkOS + checkLocale + checkSELINUX + checkFirewalls + checkPorts + checkTime +fi +checkPackages + +if [ $REPORTPASS == true ] ; then + echo "" + echo "*** Finished Validation of the Cluster, all Test Passed ***" + echo "" + exit 0 +else + echo "" + echo "*** Finished Validation of the Cluster, Failures occurred. Check for Error/Failed test results ***" + echo "" + exit 1 +fi + diff --git a/utils/clusterTester/david.tar.gz b/utils/clusterTester/david.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b6ec9cfc216c1fd8a67e74deae1ed9dd972fff3a GIT binary patch literal 7608 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 literal 0 HcmV?d00001 diff --git a/utils/clusterTester/david/columnstoreClusterTester.sh b/utils/clusterTester/david/columnstoreClusterTester.sh new file mode 100755 index 000000000..40ac05197 --- /dev/null +++ b/utils/clusterTester/david/columnstoreClusterTester.sh @@ -0,0 +1,1077 @@ +#!/bin/bash + +bold=$(tput bold) +normal=$(tput sgr0) + +IPADDRESSES="" +OS="" +PASSWORD="ssh" +CHECK=true +REPORTPASS=true +LOGFILE="" + +OS_LIST=("centos6" "centos7" "debian8" "suse12" "ubuntu16") + +NODE_IPADDRESS="" + +checkContinue() { + + if [ "$CHECK" = false ]; then + return 0 + fi + + echo "" + read -p "Failure occurred, do you want to continue? (y,n) > " answer + case ${answer:0:1} in + y|Y ) + return 0 + ;; + * ) + exit + ;; + esac +} + +### +# Print Fucntions +### + +helpPrint () { + ################################################################################ + echo "" + echo "This is the MariaDB ColumnStore Cluster System Test tool." + echo "" + echo "It will run a set of test to validate the setup of the MariaDB Columnstore system." + echo "This can be run prior to the install of MariaDB ColumnStore to make sure the" + echo "servers/nodes are configured properly. It should be run as the user of the planned" + echo "install. Meaning if MariaDB ColumnStore is going to be installed as root user," + echo "then run from root user. Also the assumption is that the servers/node have be" + echo "setup based on the Preparing for ColumnStore Installation." + echo "It should also be run on the server that is designated as Performance Module #1." + echo "This is the same server where the MariaDB ColumnStore package would be installed" + echo " and where the install script would be executed from, postConfigure." + echo "" + echo "Additional information on Tool is documented at:" + echo "" + echo "https://mariadb.com/kb/en/mariadb/*****/" + echo "" + echo "Items that are checked:" + echo " Node Ping test" + echo " Node SSH test" + echo " ColumnStore Port test" + echo " OS version" + echo " Locale settings" + echo " Firewall settings" + echo " Date/time settings" + echo " Dependent packages installed" + echo " For non-root user install - test permissions on /tmp and /dev/shm" + echo "" + echo "Usage: $0 [options]" + echo "OPTIONS:" + echo " -h,--help Help" + echo " --ipaddr=[ipaddresses] Remote Node IP-Addresses/Hostnames, if not provide, will only check local node" + echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" + echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, suse12, ubuntu16)" + echo " --password=[password] Provide a user password. (Default: ssh-keys setup will be assumed)" + echo " -c,--continue Continue on failures" + echo " --logfile=[fileName] Output results to a log file" + echo "" + echo "NOTE: Dependent package : 'nmap' and 'expect' packages need to be installed locally" + echo "" +} + +# Parse command line options. +while getopts hc-: OPT; do + case "$OPT" in + h) + echo $USAGE + helpPrint + exit 0 + ;; + c) + CHECK=false + ;; + -) LONG_OPTARG="${OPTARG#*=}" + ## Parsing hack for the long style of arguments. + case $OPTARG in + help ) + helpPrint + exit 0 + ;; + continue ) + CHECK=false + ;; + ipaddr=?* ) + IPADDRESSES="$LONG_OPTARG" + ;; + os=?* ) + OS="$LONG_OPTARG" + match=false + for SUPPORTED_OS in "${OS_LIST[@]}"; do + if [ $SUPPORTED_OS == "$OS" ]; then + match=true + break; + fi + done + + if [ $match == "false" ] ; then + echo "" + echo "OS version not-supported, please re-run and provide the OS from list of support OSs " + for SUPPORTED_OS in "${OS_LIST[@]}"; do + echo "$SUPPORTED_OS" + done + echo "" + exit 1 + fi + + ;; + password=?* ) + PASSWORD="$LONG_OPTARG" + ;; + logfile=?* ) + LOGFILE="$LONG_OPTARG" + exec 1<>$LOGFILE + exec 2>&1 + ;; + ipaddr* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + os* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + password* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + continue* ) + echo "No arg allowed for --$OPTARG option" >&2 + exit 1 + ;; + logfile* ) + echo "No arg for --$OPTARG option" >&2 + exit 1 + ;; + help* ) + helpPrint + exit 0 + ;; + '' ) + break ;; # "--" terminates argument processing + * ) + echo "Illegal option --$OPTARG" >&2 + exit 1 + ;; + esac + ;; + \?) + # getopts issues an error message + echo $USAGE >&2 + exit 1 + ;; + esac +done + +# Remove the switches we parsed above. +shift `expr $OPTIND - 1` + +if [ "$IPADDRESSES" != "" ]; then + #parse IP Addresses into an array + IFS=',' + read -ra NODE_IPADDRESS <<< "$IPADDRESSES" + + if ! type expect > /dev/null 2>&1 ; then + echo "expect is not installed. Please install and rerun." + exit 1 + fi + + if ! type nmap > /dev/null 2>&1; then + echo "nmap is not installed. Please install and rerun." + exit 1 + fi +fi + +checkLocalOS() +{ + echo "** Validate local OS is supported" + echo "" + + #get local OS + `./os_detect.sh > /tmp/os_detect 2>&1` + if [ "$?" -eq 0 ]; then + localOS=`cat /tmp/os_detect | grep "Operating System name" | cut -f2 -d '"'` + echo "Local Node OS System Name : $localOS" + + if [ "$OS" != "" ] ; then + echo "" + echo "Local Node OS Versions doesn't match the command line OS argument" + echo "Contining using the Detected Local Node OS Version" + OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` + + echo "Local Node OS Version : $OS" + else + OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` + fi + else + if [ "$OS" == "" ] ; then + echo "" + echo "Operating System name doesn't match any of the supported OS's" + if [ $LOGFILE == true ] ; then + exit 1 + fi + + echo "Please select from this OS list or enter 'exit'" + for SUPPORTED_OS in "${OS_LIST[@]}"; do + echo "$SUPPORTED_OS" + done + + read -p "Enter OS or 'exit' > " answer + if [ $answer == 'exit' ] ; then + exit 1 + fi + match=false + for SUPPORTED_OS in "${OS_LIST[@]}"; do + if [ $SUPPORTED_OS == $answer ] ; then + match=true + break; + fi + done + + if [ $match == "false" ] ; then + echo "OS version unknown, please re-run and provide the OS in the command line --os" + exit 1 + fi + fi + fi +} + +checkLocalDir() +{ + if [ "$USER" != "root" ]; then + # Non-root User directory permissions check + # + echo "" + echo "** Run Non-root User directory permissions check on Local Node" + echo "" + + #remove any check tmp files from previous runs + `sudo rm -f /tmp/*_check > /dev/null 2>&1` + + #check /tmp and /dev/shm + pass=true + `touch /tmp/cs_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node permission test on /tmp : Passed" + `rm -f /tmp/cs_check` + else + echo "Local Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" + exit 1 + fi + + `touch /dev/shm/cs_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node permission test on /dev/shm : Passed" + `rm -f /dev/shm/cs_check` + else + echo "Local Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" + pass=false + REPORTPASS=false + fi + fi +} + +checkPing() +{ + # ping test + # + echo "" + echo "** Run Ping access Test to remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + + `ping $ipadd -c 1 -w 5 > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo $ipadd " Node Passed ping test" + else + echo $ipadd " Node ${bold}Failed${normal} ping test, correct and retest" + exit 1 + fi + done +} + +checkSSH() +{ + # Login test + # + echo "" + echo "** Run SSH Login access Test to remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD ls 1 > /dev/null 2>&1`; + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + if [ $PASSWORD == "ssh" ] ; then + echo $ipadd " Node Passed SSH login test using ssh-keys" + else + echo $ipadd " Node Passed SSH login test using user password" + fi + else + if [ $PASSWORD == "ssh" ] ; then + echo $ipadd " Node ${bold}Failed${normal} SSH login test using ssh-keys" + else + echo $ipadd " Node ${bold}Failed${normal} SSH login test using user password" + fi + exit 1 + fi + done +} + +checkRemoteDir() +{ + # + # remove old _check tmp files from remote servers + + `sudo rm -f /tmp/*_check > /dev/null 2>&1` + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + done + + if [ "$USER" != "root" ]; then + # Non-root User directory permissions check + # + echo "" + echo "** Run Non-root User directory permissions check on remote nodes" + echo "" + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "$ipadd Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" + exit 1 + else + echo "$ipadd Node permission test on /tmp : Passed" + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + + `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "$ipadd Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" + pass=false + REPORTPASS=false + else + echo "$ipadd Node permission test on /dev/shm : Passed" + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi + fi +} + +checkOS() +{ + # Os check + # + echo "" + echo "** Run OS check - OS version needs to be the same on all nodes" + echo "" + + echo "Local Node OS Version : $localOS" + echo "" + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check" + else + `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + remoteOS=`cat os_detect | grep "Operating System name" | cut -f2 -d '"'` + echo "$ipadd Node OS Version : $remoteOS" + if [ $localOS != $remoteOS ]; then + echo "${bold}Failed${normal}, $ipadd has a different OS than local node" + pass=false + REPORTPASS=false + fi + rm -f os_detect + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkLocale() +{ + # Locale check + # + echo "" + echo "** Run Locale check - Locale needs to be the same on all nodes" + echo "" + + #get local Locale + `locale | grep LANG= > /tmp/locale_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "Local Node Locale : `cat /tmp/locale_check`" + else + echo "Error running 'locale' command on local node" + fi + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + echo "$ipadd Node Locale : `cat locale_check`" + `diff /tmp/locale_check locale_check > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd has a different Locale setting than local node" + pass=false + REPORTPASS=false + fi + `rm -f locale_check` + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkSELINUX() +{ + # SELINUX check + # + echo "" + echo "** Run SELINUX check - Setting should to be disabled on all nodes" + echo "" + + pass=true + #check local SELINUX + if [ -f /etc/selinux/config ]; then + `cat /etc/selinux/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node SELINUX setting is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "Local Node SELINUX setting is Not Enabled" + fi + else + echo "Local Node SELINUX setting is Not Enabled" + fi + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "$ipadd Node SELINUX setting is Not Enabled" + else + `cat config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd SELINUX setting is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "$ipadd Node SELINUX setting is Not Enabled" + fi + `rm -f config` + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkFirewalls() +{ + # FIREWALL checks + # + echo "" + echo "** Run Firewall Services check - Firewall Services should to be disabled on all nodes" + echo "" + + declare -a FIREWALL_LIST=("iptables" "ufw" "firewalld" "firewall") + + fpass=true + #check local FIREWALLS + `chkconfig > /tmp/firewall_check 2>&1` + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `cat /tmp/firewall_check | grep $firewall | grep on > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in chkconfig, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + `systemctl status $firewall > /tmp/firewall1_check 2>&1` + `cat /tmp/firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + if $pass ; then + echo "Local Node $firewall service is Not Enabled" + fi + done + + if ! $fpass; then + checkContinue + fi + + echo "" + fpass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'chkconfig > /tmp/firewall_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `cat firewall_check | grep $firewall | grep on > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in chkconfig, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + `rm -f firewall1_check` + fi + fi + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + done + + `rm -f firewall_check` + fi + else + # 'sysconfig not on remote node + for firewall in "${FIREWALL_LIST[@]}"; do + pass=true + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" + pass=false + fpass=false + REPORTPASS=false + fi + `rm -f firewall1_check` + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + fi + fi + + if $pass ; then + echo "$ipadd Node $firewall service is Not Enabled" + fi + done + fi + + echo "" + done + + if ! $fpass; then + checkContinue + fi + + if [ $OS == "suse12" ]; then + # rcSuSEfirewall2 check + # + echo "" + echo "** Run rcSuSEfirewall2 check - Service should to be disabled on all nodes" + echo "" + + pass=true + #check local IPTABLES + `/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1` + `cat /tmp/rcSuSEfirewall2_check | grep active > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "Local Node rcSuSEfirewall2 service is Not Enabled" + fi + + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/rcSuSEfirewall2_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat rcSuSEfirewall2_check | grep active > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Enabled, please disable" + pass=false + REPORTPASS=false + else + echo "$ipadd Node rcSuSEfirewall2 service is Not Enabled" + fi + `rm -f rcSuSEfirewall2_check` + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi + fi +} + +checkPorts() +{ + # port test + # + echo "" + echo "** Run MariaDB ColumnStore Port (8600-8620) availibility test" + echo "" + + pass=true + for ipadd in "${NODE_IPADDRESS[@]}"; do + + `nmap $ipadd -p 8600-8620 | grep 'closed unknown' > /dev/null` + if [ "$?" -eq 0 ]; then + echo $ipadd " Node Passed port test" + else + echo $ipadd " Node ${bold}Failed${normal} port test, check and disable any firwalls that were reported enabled" + pass=false + REPORTPASS=false + fi + done + + if ! $pass; then + checkContinue + fi +} + +checkTime() +{ + # Time check + # + echo "" + echo "** Run Date/Time check - Date/Time should be within 10 seconds on all nodes" + echo "" + + pass=true + #get local epoch time + localTime=`date +%s` + for ipadd in "${NODE_IPADDRESS[@]}"; do + `./remote_command.sh $ipadd $PASSWORD 'date +%s > /tmp/time_check' > /tmp/time_check` + rc="$?" + if [ $rc -ne 0 ] ; then + echo $ipadd " Node ${bold}Failed${normal} date/time check failed, check /tmp/time_check" + pass=false + REPORTPASS=false + else + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + remoteTime=`cat time_check` + timeDiff=`echo "$(($remoteTime-$localTime))"` + range=10 + if [ $timeDiff -gt $range ] || [ $timeDiff -lt -$range ] ; then + echo $ipadd " Node ${bold}Failed${normal}, $ipadd Node date/time is more than 10 seconds away from local node" + pass=false + else + echo "Passed: $ipadd Node date/time is within 10 seconds of local node" + fi + fi + fi + done + `rm -f time_check` + + if ! $pass; then + checkContinue + fi +} + +checkPackages() +{ + # + # now check packaging on local and remote nodes + # + + echo "" + echo "** Run MariaDB ColumnStore Dependent Package Check" + echo "" + + declare -a CENTOS_PKG=("boost" "expect" "perl" "perl-DBI" "openssl" "zlib" "file" "sudo" "perl-DBD-MySQL" "libaio" "rsync" "snappy" "net-tools") + + if [ "$OS" == "centos6" ] || [ "$OS" == "centos7" ]; then + if [ ! `which yum 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}yum${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${CENTOS_PKG[@]}"; do + if [ $OS == "centos6" ] && [ "$PKG" == "boost" ]; then + `ls /usr/lib/libboost_regex.so > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node ${bold}boost libraries${normal} not installed" + pass=false + REPORTPASS=false + fi + else + `yum list installed "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep Installed > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + fi + done + fi + + if [ $pass == true ] ; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${CENTOS_PKG[@]}"; do + if [ $OS == "centos6" ] && [ $PKG == "boost" ]; then + `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + if [ $? -ne 0 ] ; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}boost libraries${normal} not installed" + pass=false + REPORTPASS=false + fi + else + `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 2 ] ; then + echo "${bold}Failed${normal}, $ipadd Node, 'yum' not installed" + pass=false + REPORTPASS=false + break + elif [ $rc -eq 1 ] ; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + fi + echo "" + done + fi + fi + + declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools") + + if [ "$OS" == "suse12" ]; then + if [ ! `which rpm 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${SUSE_PKG[@]}"; do + `rpm -qi "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep "not installed" > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${SUSE_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -ne 0 ] ; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + fi + echo "" + done + fi + fi + + declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "snappy" "net-tools") + + if [ "$OS" == "ubuntu16" ] ; then + if [ ! `which dpkg 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${UBUNTU_PKG[@]}"; do + `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${UBUNTU_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" + pass=false + break + else + `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi + + `rm -f pkg_check` + fi + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + fi + echo "" + done + fi + fi + + declare -a DEBIAN_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "libsnappy1" "net-tools") + + if [ "$OS" == "debian8" ]; then + if [ ! `which dpkg 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${DEBIAN_PKG[@]}"; do + `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${DEBIAN_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + rc="$?" + if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" + pass=false + break + else + `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi + + `rm -f pkg_check` + fi + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + pass=false + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + fi + echo "" + done + fi + fi +} + +echo "" +echo "*** This is the MariaDB Columnstore Cluster System test tool ***" +echo "" + +checkLocalOS +checkLocalDir +if [ "$IPADDRESSES" != "" ]; then + checkPing + checkSSH + checkRemoteDir + checkOS + checkLocale + checkSELINUX + checkFirewalls + checkPorts + checkTime +fi +checkPackages + +if [ $REPORTPASS == true ] ; then + echo "" + echo "*** Finished Validation of the Cluster, all Test Passed ***" + echo "" + exit 0 +else + echo "" + echo "*** Finished Validation of the Cluster, Failures occurred. Check for Error/Failed test results ***" + echo "" + exit 1 +fi + diff --git a/utils/clusterTester/david/os_detect.sh b/utils/clusterTester/david/os_detect.sh new file mode 100755 index 000000000..1f76a3716 --- /dev/null +++ b/utils/clusterTester/david/os_detect.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +detectOS () { + checkFile1=/etc/os-release + checkFile2=/etc/centos-release + if [ -f "$checkFile1" ] + then + osPrettyName=`cat $checkFile1 | grep PRETTY_NAME|awk -F"=" '{print $2}'` + osVersionID=`cat $checkFile1 | grep VERSION_ID | awk -F"=" '{print $2}' | awk -F"." '{print $1}' | sed 's/"//g'` + else + osPrettyName=`head -n 1 $checkFile2` + osVersionID=`echo $osPrettyName | awk -F" " '{print $3}' | awk -F"." '{print $1}'` + fi +# + osName=`echo $osPrettyName | awk -F" " '{print $1}' | sed 's/"//g'` + if [ -z "$osPrettyName" ] + then + osPrettyName=`uname -o -s -r -v` + fi + if [ -z "$osName" ] || [ -z "$osVersionID" ] + then + osTag="" + else + osTag=`echo $osName$osVersionID | awk '{print tolower($0)}'` + fi +} +# + detectOS + echo Operating System name: $osPrettyName + echo Operating System tag: $osTag + case "$osTag" in + centos6|centos7|ubuntu16|debian8|suse12) + ;; + *) + echo OS not supported + exit 1 + ;; + esac + + exit 0 diff --git a/utils/clusterTester/david/remote_command.sh b/utils/clusterTester/david/remote_command.sh new file mode 100755 index 000000000..4525a4ed3 --- /dev/null +++ b/utils/clusterTester/david/remote_command.sh @@ -0,0 +1,92 @@ +#!/usr/bin/expect +# +# $Id: remote_command.sh 3495 2012-12-17 22:51:40Z dhill $ +# +# Remote command execution script to another server +# Argument 1 - Remote Server Host Name or IP address +# Argument 2 - Remote Server password +# Argument 3 - Command +# Argument 4 - debug flag +# Argument 5 - Remote user name (optional) +# Argument 6 - Force a tty to be allocated (optional) +set stty_init {cols 512 -opost}; +set timeout 10 +set SERVER [lindex $argv 0] +set PASSWORD [lindex $argv 1] +set COMMAND [lindex $argv 2] +set DEBUG [lindex $argv 3] + +if {[info exists env(USER)]} { + set USERNAME $env(USER) +} else { + set USERNAME "root" +} + +set UNM [lindex $argv 4] +if { $UNM != "" && $UNM != "-" } { + set USERNAME "$UNM" +} +set TTY "" +set TTYOPT [lindex $argv 5] +if { $TTYOPT != "" } { + set TTY "-t" +} +log_user $DEBUG +spawn -noecho /bin/bash +#expect -re {[$#] } + +if { $PASSWORD == "ssh" } { + set PASSWORD "" +} + +# +# send command +# +send "ssh -v $TTY $USERNAME@$SERVER '$COMMAND'\n" +expect { + "cannot access" { exit 1} + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1} + "service not known" { send_user " FAILED: Invalid Host\n" ; exit 1} + "ssh: connect to host" { send_user " FAILED: Invalid Host\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "authenticity" { send "yes\n" + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } + } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + "command not found" { exit 3 } +# -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } +} +expect { + "command not found" { exit 3 } +# -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + "cannot access" { exit 1} + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } + + "(y or n)" { send "y\n" + "command not found" { exit 3 } +# expect -re {[$#] } { exit 0 } + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "Exit status 3" { exit 1 } + "Exit status 4" { exit 1 } + timeout { exit 2 } + } +} +exit 0 + diff --git a/utils/clusterTester/david/remote_scp_get.sh b/utils/clusterTester/david/remote_scp_get.sh new file mode 100755 index 000000000..aee668b13 --- /dev/null +++ b/utils/clusterTester/david/remote_scp_get.sh @@ -0,0 +1,58 @@ +#!/usr/bin/expect +# +# $Id: remote_commend.sh 421 2007-04-05 15:46:55Z dhill $ +# +# Remote command execution script to another server +# Argument 1 - Remote Server Host Name or IP address +# Argument 2 - Remote Server root password +# Argument 3 - Command +set timeout 10 +set USERNAME $env(USER)"@" +set SERVER [lindex $argv 0] +set PASSWORD [lindex $argv 1] +set FILE [lindex $argv 2] +set DEBUG [lindex $argv 3] +log_user $DEBUG +spawn -noecho /bin/bash + +if { $PASSWORD == "ssh" } { + set PASSWORD "" +} + +# +# send command +# +#expect -re {[$#] } +send "scp -v $USERNAME$SERVER:$FILE .\n" +expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "100%" { send_user "DONE\n" ; exit 0 } + "authenticity" { send "yes\n" + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } + } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection timed out" { send_user "FAILED: Connection timed out\n" ; exit 1 } + "lost connection" { send_user "FAILED: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + "scp:" { send_user "FAILED\n" ; exit 1 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } +} +expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + "100%" { send_user "DONE\n" ; exit 0 } + "scp:" { send_user "FAILED\n" ; exit 1 } + "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } + "No such file or directory" { send_user "FAILED: No such file or directory\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } +} +exit 0 + diff --git a/utils/clusterTester/david/remote_scp_put.sh b/utils/clusterTester/david/remote_scp_put.sh new file mode 100755 index 000000000..7eb6c1ecb --- /dev/null +++ b/utils/clusterTester/david/remote_scp_put.sh @@ -0,0 +1,57 @@ +#!/usr/bin/expect +# +# $Id: remote_commend.sh 421 2007-04-05 15:46:55Z dhill $ +# +# Remote command execution script to another server +# Argument 1 - Remote Server Host Name or IP address +# Argument 2 - Remote Server root password +# Argument 3 - Command +set timeout 30 +set USERNAME $env(USER)"@" +set SERVER [lindex $argv 0] +set PASSWORD [lindex $argv 1] +set FILE [lindex $argv 2] +set DEBUG [lindex $argv 3] +log_user $DEBUG +spawn -noecho /bin/bash + +if { $PASSWORD == "ssh" } { + set PASSWORD "" +} + +# +# send command +# +send "scp -v $FILE $USERNAME$SERVER:$FILE\n" +expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + -re "100%" { send_user "DONE\n" ; sleep 2; exit 0 } + -re "authenticity" { send "yes\n" + expect { + -re "word: " { send "$PASSWORD\n" } + -re "passphrase" { send "$PASSWORD\n" } + } + } + -re "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + -re "Connection refused" { send_user "FAILED: Connection refused\n" ; exit 1 } + -re "Connection timed out" { send_user "FAILED: Connection timed out\n" ; exit 1 } + -re "lost connection" { send_user "FAILED: Connection refused\n" ; exit 1 } + -re "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + -re "word: " { send "$PASSWORD\n" } + -re "passphrase" { send "$PASSWORD\n" } + -re "WARNING:" { send "rm -f /root/.ssh/known_hosts" ; exit 1 } + -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } +} +expect { + "Exit status 0" { exit 0 } + "Exit status 1" { exit 1 } + -re "100%" { send_user "DONE\n" ; sleep 2 ; exit 0 } + -re "scp:" { send_user "FAILED\n" ; exit 1 } + -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } + -re "No such file or directory" { send_user "FAILED: Invalid file\n" ; exit 1 } + -re "Connection refused" { send_user "FAILED: Connection refused\n" ; exit 1 } + -re "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } +} +exit 0 + diff --git a/utils/clusterTester/os_detect.sh b/utils/clusterTester/os_detect.sh new file mode 100755 index 000000000..1f76a3716 --- /dev/null +++ b/utils/clusterTester/os_detect.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +detectOS () { + checkFile1=/etc/os-release + checkFile2=/etc/centos-release + if [ -f "$checkFile1" ] + then + osPrettyName=`cat $checkFile1 | grep PRETTY_NAME|awk -F"=" '{print $2}'` + osVersionID=`cat $checkFile1 | grep VERSION_ID | awk -F"=" '{print $2}' | awk -F"." '{print $1}' | sed 's/"//g'` + else + osPrettyName=`head -n 1 $checkFile2` + osVersionID=`echo $osPrettyName | awk -F" " '{print $3}' | awk -F"." '{print $1}'` + fi +# + osName=`echo $osPrettyName | awk -F" " '{print $1}' | sed 's/"//g'` + if [ -z "$osPrettyName" ] + then + osPrettyName=`uname -o -s -r -v` + fi + if [ -z "$osName" ] || [ -z "$osVersionID" ] + then + osTag="" + else + osTag=`echo $osName$osVersionID | awk '{print tolower($0)}'` + fi +} +# + detectOS + echo Operating System name: $osPrettyName + echo Operating System tag: $osTag + case "$osTag" in + centos6|centos7|ubuntu16|debian8|suse12) + ;; + *) + echo OS not supported + exit 1 + ;; + esac + + exit 0 From fa21239a7efa9e6a260348eef1ecb0937532c248 Mon Sep 17 00:00:00 2001 From: David Hill Date: Sat, 20 May 2017 17:41:22 -0500 Subject: [PATCH 081/185] updates --- .../clusterTester/columnstoreClusterTester.sh | 140 +++++++----------- 1 file changed, 51 insertions(+), 89 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index bfb174d7e..76d38cc8e 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -70,7 +70,7 @@ helpPrint () { echo "OPTIONS:" echo " -h,--help Help" echo " --ipaddr=[ipaddresses] Remote Node IP-Addresses/Hostnames, if not provide, will only check local node" - echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" + echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, suse12, ubuntu16)" echo " --password=[password] Provide a user password. (Default: ssh-keys setup will be assumed)" echo " -c,--continue Continue on failures" @@ -532,35 +532,33 @@ checkFirewalls() # FIREWALL checks # echo "" - echo "** Run Firewall Services check - Firewall Services should to be disabled on all nodes" + echo "** Run Firewall Services check - Firewall Services should to be Inactive on all nodes" echo "" declare -a FIREWALL_LIST=("iptables" "ufw" "firewalld" "firewall") fpass=true #check local FIREWALLS - `chkconfig > /tmp/firewall_check 2>&1` for firewall in "${FIREWALL_LIST[@]}"; do pass=true - `cat /tmp/firewall_check | grep $firewall | grep on > /dev/null 2>&1` + `service $firewall status > /tmp/firewall1_check 2>&1` if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in chkconfig, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - - `systemctl status $firewall > /tmp/firewall1_check 2>&1` - `cat /tmp/firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in systemctl, please disable" + echo "${bold}Failed${normal}, Local Node $firewall service is Active, please disable" pass=false fpass=false REPORTPASS=false + else + `systemctl status $firewall > /tmp/firewall1_check 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, Local Node $firewall service is Active, please disable" + pass=false + fpass=false + REPORTPASS=false + fi fi if $pass ; then - echo "Local Node $firewall service is Not Enabled" + echo "Local Node $firewall service is Not Active" fi done @@ -571,79 +569,29 @@ checkFirewalls() echo "" fpass=true for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'chkconfig > /tmp/firewall_check 2>&1' 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - for firewall in "${FIREWALL_LIST[@]}"; do - pass=true - `cat firewall_check | grep $firewall | grep on > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in chkconfig, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - `rm -f firewall1_check` - fi - fi - - if $pass ; then - echo "$ipadd Node $firewall service is Not Enabled" - fi - done - - `rm -f firewall_check` - fi - else # 'sysconfig not on remote node for firewall in "${FIREWALL_LIST[@]}"; do pass=true - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" + `./remote_command.sh $ipadd $PASSWORD "service '$firewall' status > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" + pass=false + fpass=false + REPORTPASS=false + else + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" pass=false fpass=false REPORTPASS=false - fi - `rm -f firewall1_check` - - if $pass ; then - echo "$ipadd Node $firewall service is Not Enabled" - fi fi - fi + fi if $pass ; then echo "$ipadd Node $firewall service is Not Enabled" fi done - fi echo "" done @@ -656,14 +604,14 @@ checkFirewalls() # rcSuSEfirewall2 check # echo "" - echo "** Run rcSuSEfirewall2 check - Service should to be disabled on all nodes" + echo "** Run rcSuSEfirewall2 check - Service should to be Inactive on all nodes" echo "" pass=true #check local IPTABLES `/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1` if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Enabled, please disable" + echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Active, please disable" pass=false REPORTPASS=false else @@ -674,7 +622,7 @@ checkFirewalls() `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` rc="$?" if [ $rc -eq 0 ] ; then - echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Enabled, please disable" + echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Active, please disable" pass=false REPORTPASS=false else @@ -927,7 +875,7 @@ checkPackages() for PKG in "${UBUNTU_PKG[@]}"; do `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then + if [ $rc -eq 0 ] ; then `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" @@ -998,16 +946,30 @@ checkPackages() for PKG in "${DEBIAN_PKG[@]}"; do `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` rc="$?" - if [ $rc -eq 2 ] ; then - echo "${bold}Failed${normal}, $ipadd Node, 'dpkg' not installed" + if [ $rc -eq 0 ] ; then + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" + pass=false + break + else + `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi + + `rm -f pkg_check` + fi + fi + else + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" pass=false - REPORTPASS=false - break - elif [ $rc -eq 1 ] ; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi + fi done if $pass; then From 19755539e940a0ae104b7bae860d9e911a50ae37 Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 22 May 2017 08:56:01 -0500 Subject: [PATCH 082/185] updated comments --- utils/clusterTester/columnstoreClusterTester.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index 76d38cc8e..5bc1d2a8e 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -42,18 +42,16 @@ helpPrint () { echo "This is the MariaDB ColumnStore Cluster System Test tool." echo "" echo "It will run a set of test to validate the setup of the MariaDB Columnstore system." - echo "This can be run prior to the install of MariaDB ColumnStore to make sure the" + echo "This can be run prior to running MariaDB ColumnStore 'postConfigure' tool to verify" echo "servers/nodes are configured properly. It should be run as the user of the planned" echo "install. Meaning if MariaDB ColumnStore is going to be installed as root user," echo "then run from root user. Also the assumption is that the servers/node have be" echo "setup based on the Preparing for ColumnStore Installation." echo "It should also be run on the server that is designated as Performance Module #1." - echo "This is the same server where the MariaDB ColumnStore package would be installed" - echo " and where the install script would be executed from, postConfigure." echo "" echo "Additional information on Tool is documented at:" echo "" - echo "https://mariadb.com/kb/en/mariadb/*****/" + echo "https://mariadb.com/kb/en/mariadb/mariadb-columnstore-cluster-test-tool/" echo "" echo "Items that are checked:" echo " Node Ping test" From 37ead3c076bf1be5c30a2a76f50b521c0911ccb2 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 23 May 2017 10:47:01 -0500 Subject: [PATCH 083/185] add ipaddr to the /tmp log files --- .../clusterTester/columnstoreClusterTester.sh | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index 5bc1d2a8e..311e76d87 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -343,7 +343,7 @@ checkRemoteDir() `sudo rm -f /tmp/*_check > /dev/null 2>&1` for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check_$ipadd 2>&1` done if [ "$USER" != "root" ]; then @@ -354,10 +354,10 @@ checkRemoteDir() echo "" for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + `grep "Permission denied" /tmp/remote_command_check_$ipadd > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "$ipadd Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" exit 1 @@ -365,15 +365,15 @@ checkRemoteDir() echo "$ipadd Node permission test on /tmp : Passed" fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" pass=false REPORTPASS=false fi - `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` + `grep "Permission denied" /tmp/remote_command_check_$ipadd > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "$ipadd Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" pass=false @@ -382,7 +382,7 @@ checkRemoteDir() echo "$ipadd Node permission test on /dev/shm : Passed" fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" pass=false REPORTPASS=false fi @@ -407,15 +407,15 @@ checkOS() pass=true for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check 2>&1` + `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check" + echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check_$ipadd" else - `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check` + `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check_$ipadd` rc="$?" - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" else remoteOS=`cat os_detect | grep "Operating System name" | cut -f2 -d '"'` echo "$ipadd Node OS Version : $remoteOS" @@ -452,12 +452,12 @@ checkLocale() pass=true for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check` + `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check_$ipadd` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" else echo "$ipadd Node Locale : `cat locale_check`" `diff /tmp/locale_check locale_check > /dev/null 2>&1` @@ -469,7 +469,7 @@ checkLocale() `rm -f locale_check` fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" pass=false REPORTPASS=false fi @@ -504,7 +504,7 @@ checkSELINUX() fi for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then echo "$ipadd Node SELINUX setting is Not Enabled" else @@ -570,14 +570,14 @@ checkFirewalls() # 'sysconfig not on remote node for firewall in "${FIREWALL_LIST[@]}"; do pass=true - `./remote_command.sh $ipadd $PASSWORD "service '$firewall' status > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` + `./remote_command.sh $ipadd $PASSWORD "service '$firewall' status > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check_$ipadd` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" pass=false fpass=false REPORTPASS=false else - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check_$ipadd` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" pass=false @@ -617,7 +617,7 @@ checkFirewalls() fi for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` + `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check_$ipadd` rc="$?" if [ $rc -eq 0 ] ; then echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Active, please disable" @@ -679,9 +679,9 @@ checkTime() pass=false REPORTPASS=false else - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" else remoteTime=`cat time_check` timeDiff=`echo "$(($remoteTime-$localTime))"` @@ -754,14 +754,14 @@ checkPackages() for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${CENTOS_PKG[@]}"; do if [ $OS == "centos6" ] && [ $PKG == "boost" ]; then - `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check_$ipadd 2>&1` if [ $? -ne 0 ] ; then echo "${bold}Failed${normal}, $ipadd Node ${bold}boost libraries${normal} not installed" pass=false REPORTPASS=false fi else - `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -eq 2 ] ; then echo "${bold}Failed${normal}, $ipadd Node, 'yum' not installed" @@ -819,7 +819,7 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${SUSE_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -ne 0 ] ; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" @@ -871,14 +871,14 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${UBUNTU_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -eq 0 ] ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" else - `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + `cat /tmp/remote_command_check_$ipadd | grep 'command not found' > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" pass=false @@ -894,7 +894,7 @@ checkPackages() fi fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" pass=false fi done @@ -942,14 +942,14 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${DEBIAN_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` rc="$?" if [ $rc -eq 0 ] ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check_$ipadd 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" else - `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + `cat /tmp/remote_command_check_$ipadd | grep 'command not found' > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" pass=false @@ -965,7 +965,7 @@ checkPackages() fi fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" pass=false fi done From dfd15b2b13e1f1d2e3d1d9fb34071dc17216cc87 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 23 May 2017 16:36:45 -0500 Subject: [PATCH 084/185] updates based on QA testing --- .../clusterTester/columnstoreClusterTester.sh | 113 +++++++++--------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index 311e76d87..de59b25da 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -42,16 +42,18 @@ helpPrint () { echo "This is the MariaDB ColumnStore Cluster System Test tool." echo "" echo "It will run a set of test to validate the setup of the MariaDB Columnstore system." - echo "This can be run prior to running MariaDB ColumnStore 'postConfigure' tool to verify" + echo "This can be run prior to the install of MariaDB ColumnStore to make sure the" echo "servers/nodes are configured properly. It should be run as the user of the planned" echo "install. Meaning if MariaDB ColumnStore is going to be installed as root user," echo "then run from root user. Also the assumption is that the servers/node have be" echo "setup based on the Preparing for ColumnStore Installation." echo "It should also be run on the server that is designated as Performance Module #1." + echo "This is the same server where the MariaDB ColumnStore package would be installed" + echo " and where the install script would be executed from, postConfigure." echo "" echo "Additional information on Tool is documented at:" echo "" - echo "https://mariadb.com/kb/en/mariadb/mariadb-columnstore-cluster-test-tool/" + echo "https://mariadb.com/kb/en/mariadb/*****/" echo "" echo "Items that are checked:" echo " Node Ping test" @@ -343,7 +345,7 @@ checkRemoteDir() `sudo rm -f /tmp/*_check > /dev/null 2>&1` for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` done if [ "$USER" != "root" ]; then @@ -354,10 +356,10 @@ checkRemoteDir() echo "" for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check 2>&1` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check_$ipadd > /dev/null 2>&1` + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "$ipadd Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" exit 1 @@ -365,15 +367,15 @@ checkRemoteDir() echo "$ipadd Node permission test on /tmp : Passed" fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" pass=false REPORTPASS=false fi - `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check 2>&1` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check_$ipadd > /dev/null 2>&1` + `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "$ipadd Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" pass=false @@ -382,7 +384,7 @@ checkRemoteDir() echo "$ipadd Node permission test on /dev/shm : Passed" fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" pass=false REPORTPASS=false fi @@ -407,15 +409,15 @@ checkOS() pass=true for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check_$ipadd 2>&1` + `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check_$ipadd" + echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check" else - `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check_$ipadd` + `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check` rc="$?" - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" else remoteOS=`cat os_detect | grep "Operating System name" | cut -f2 -d '"'` echo "$ipadd Node OS Version : $remoteOS" @@ -452,12 +454,12 @@ checkLocale() pass=true for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check_$ipadd` + `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check` rc="$?" if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" else echo "$ipadd Node Locale : `cat locale_check`" `diff /tmp/locale_check locale_check > /dev/null 2>&1` @@ -469,7 +471,7 @@ checkLocale() `rm -f locale_check` fi else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" + echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" pass=false REPORTPASS=false fi @@ -504,7 +506,7 @@ checkSELINUX() fi for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then echo "$ipadd Node SELINUX setting is Not Enabled" else @@ -570,14 +572,14 @@ checkFirewalls() # 'sysconfig not on remote node for firewall in "${FIREWALL_LIST[@]}"; do pass=true - `./remote_command.sh $ipadd $PASSWORD "service '$firewall' status > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check_$ipadd` + `./remote_command.sh $ipadd $PASSWORD "service '$firewall' status > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" pass=false fpass=false REPORTPASS=false else - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check_$ipadd` + `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall_check 2>&1" 1 > /tmp/remote_command_check` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node $firewall service is Active, please disable" pass=false @@ -602,14 +604,14 @@ checkFirewalls() # rcSuSEfirewall2 check # echo "" - echo "** Run rcSuSEfirewall2 check - Service should to be Inactive on all nodes" + echo "** Run rcSuSEfirewall2 check - Service should to be disabled on all nodes" echo "" pass=true #check local IPTABLES `/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1` if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Active, please disable" + echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Enabled, please disable" pass=false REPORTPASS=false else @@ -617,10 +619,10 @@ checkFirewalls() fi for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check_$ipadd` + `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` rc="$?" if [ $rc -eq 0 ] ; then - echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Active, please disable" + echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Enabled, please disable" pass=false REPORTPASS=false else @@ -679,9 +681,9 @@ checkTime() pass=false REPORTPASS=false else - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" else remoteTime=`cat time_check` timeDiff=`echo "$(($remoteTime-$localTime))"` @@ -712,7 +714,7 @@ checkPackages() echo "** Run MariaDB ColumnStore Dependent Package Check" echo "" - declare -a CENTOS_PKG=("boost" "expect" "perl" "perl-DBI" "openssl" "zlib" "file" "sudo" "perl-DBD-MySQL" "libaio" "rsync" "snappy" "net-tools") + declare -a CENTOS_PKG=("expect" "perl" "perl-DBI" "openssl" "zlib" "file" "sudo" "libaio" "rsync" "snappy" "net-tools" "perl-DBD-MySQL") if [ "$OS" == "centos6" ] || [ "$OS" == "centos7" ]; then if [ ! `which yum 2>/dev/null` ] ; then @@ -754,14 +756,14 @@ checkPackages() for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${CENTOS_PKG[@]}"; do if [ $OS == "centos6" ] && [ $PKG == "boost" ]; then - `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` if [ $? -ne 0 ] ; then echo "${bold}Failed${normal}, $ipadd Node ${bold}boost libraries${normal} not installed" pass=false REPORTPASS=false fi else - `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` rc="$?" if [ $rc -eq 2 ] ; then echo "${bold}Failed${normal}, $ipadd Node, 'yum' not installed" @@ -787,7 +789,7 @@ checkPackages() fi fi - declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools") + declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools" "perl-DBD-MySQL") if [ "$OS" == "suse12" ]; then if [ ! `which rpm 2>/dev/null` ] ; then @@ -819,7 +821,7 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${SUSE_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` rc="$?" if [ $rc -ne 0 ] ; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" @@ -839,7 +841,7 @@ checkPackages() fi fi - declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "snappy" "net-tools") + declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline-dev" "rsync" "snappy" "net-tools" "libdbd-mysql-perl") if [ "$OS" == "ubuntu16" ] ; then if [ ! `which dpkg 2>/dev/null` ] ; then @@ -871,14 +873,12 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${UBUNTU_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` - rc="$?" - if [ $rc -eq 0 ] ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" else - `cat /tmp/remote_command_check_$ipadd | grep 'command not found' > /dev/null 2>&1` + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" pass=false @@ -888,16 +888,16 @@ checkPackages() if [ "$?" -ne 0 ]; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" pass=false + else + `cat pkg_check | grep 'not installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi fi `rm -f pkg_check` fi - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" - pass=false - fi - done if $pass; then echo "$ipadd Node - Passed, all dependency packages are installed" @@ -910,7 +910,7 @@ checkPackages() fi fi - declare -a DEBIAN_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "libsnappy1" "net-tools") + declare -a DEBIAN_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline-dev" "rsync" "libsnappy1" "net-tools" "libdbd-mysql-perl") if [ "$OS" == "debian8" ]; then if [ ! `which dpkg 2>/dev/null` ] ; then @@ -942,14 +942,12 @@ checkPackages() if [ "$IPADDRESSES" != "" ]; then for ipadd in "${NODE_IPADDRESS[@]}"; do for PKG in "${DEBIAN_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check_$ipadd 2>&1` - rc="$?" - if [ $rc -eq 0 ] ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check_$ipadd 2>&1` + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check_$ipadd" + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" else - `cat /tmp/remote_command_check_$ipadd | grep 'command not found' > /dev/null 2>&1` + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` if [ "$?" -eq 0 ]; then echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" pass=false @@ -959,15 +957,16 @@ checkPackages() if [ "$?" -ne 0 ]; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" pass=false + else + `cat pkg_check | grep 'not installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi fi - `rm -f pkg_check` fi fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check_$ipadd" - pass=false - fi done if $pass; then From 54fb807fef6b9259e0435d56c93a4662636bdf57 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 24 May 2017 08:59:41 -0500 Subject: [PATCH 085/185] fix missing fi --- utils/clusterTester/columnstoreClusterTester.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index de59b25da..8ad485fd7 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -898,6 +898,8 @@ checkPackages() `rm -f pkg_check` fi + fi + done if $pass; then echo "$ipadd Node - Passed, all dependency packages are installed" From 0f2bccd0d22996a2eeccf8dc1333af5463891ddb Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 24 May 2017 10:18:45 -0500 Subject: [PATCH 086/185] fix suse package name --- utils/clusterTester/columnstoreClusterTester.sh | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index 8ad485fd7..1265a3620 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -789,7 +789,7 @@ checkPackages() fi fi - declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools" "perl-DBD-MySQL") + declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools" "perl-DBD-mysql") if [ "$OS" == "suse12" ]; then if [ ! `which rpm 2>/dev/null` ] ; then @@ -886,14 +886,8 @@ checkPackages() else `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - else - `cat pkg_check | grep 'not installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" pass=false - fi fi `rm -f pkg_check` @@ -957,15 +951,10 @@ checkPackages() else `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - else - `cat pkg_check | grep 'not installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" pass=false - fi fi + `rm -f pkg_check` fi fi From ccbdb07007dfde95c610fcead008b62e30d7411f Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 26 May 2017 10:52:17 -0500 Subject: [PATCH 087/185] MCOL-379 - fix false critical memory usage alarm --- oam/install_scripts/post-install | 2 +- oamapps/serverMonitor/memoryMonitor.cpp | 41 +++++++++++++++++++------ procmgr/processmanager.cpp | 5 ++- utils/common/cgroupconfigurator.cpp | 39 ++++++++++++++--------- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 6831724f5..e90494d75 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -155,6 +155,7 @@ rm -f $installdir/data/bulk/tmpjob/* >/dev/null 2>&1 #create columnstore temp file directory $SUDO chmod 777 /tmp +$SUDO rm -f /tmp/* > /dev/null 2>&1 mkdir -p /tmp/columnstore_tmp_files >/dev/null 2>&1 #setup core file directory and link @@ -213,7 +214,6 @@ if [ $user = "root" ]; then $installdir/bin/syslogSetup.sh install > /tmp/syslog_install.log 2>&1 rm -f /etc/default/columnstore else - $SUDO rm -fr /tmp/* > /dev/null 2>&1 $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml $SUDO chmod -R 777 /dev/shm diff --git a/oamapps/serverMonitor/memoryMonitor.cpp b/oamapps/serverMonitor/memoryMonitor.cpp index 9c9988558..a1de4540f 100644 --- a/oamapps/serverMonitor/memoryMonitor.cpp +++ b/oamapps/serverMonitor/memoryMonitor.cpp @@ -32,10 +32,11 @@ using namespace logging; using namespace servermonitor; //using namespace procheartbeat; -unsigned long totalMem; ProcessMemoryList pml; int swapFlag = 0; +uint64_t totalMem; + pthread_mutex_t MEMORY_LOCK; /***************************************************************************************** @@ -62,7 +63,7 @@ void memoryMonitor() //set monitoring period to 60 seconds int monitorPeriod = MONITOR_PERIOD; - utils::CGroupConfigurator cg; + utils::CGroupConfigurator cg; while(true) { @@ -87,12 +88,11 @@ void memoryMonitor() //get memory stats totalMem = cg.getTotalMemory(); uint64_t freeMem = cg.getFreeMemory(); - uint64_t usedMem = totalMem - freeMem; + uint64_t usedMem = totalMem - freeMem; //get swap stats - uint64_t totalSwap = cg.getTotalSwapSpace(); - uint64_t usedSwap = cg.getSwapInUse(); - + uint64_t totalSwap = cg.getTotalSwapSpace(); + uint64_t usedSwap = cg.getSwapInUse(); if ( totalSwap == 0 ) { swapUsagePercent = 0; @@ -136,13 +136,34 @@ void memoryMonitor() else memoryUsagePercent = (usedMem / (totalMem / 100)) + 1; + /*LoggingID lid(SERVER_MONITOR_LOG_ID); + MessageLog ml(lid); + Message msg; + Message::Args args; + args.add("memoryUsagePercent "); + args.add((uint64_t) memoryUsagePercent); + args.add("usedMem "); + args.add((uint64_t) usedMem); + args.add("totalMem "); + args.add((uint64_t) totalMem); + msg.format(args); + ml.logInfoMessage(msg); +*/ + //first time called, log + //adjust if over 100% + if ( swapUsagePercent < 0 ) + swapUsagePercent = 0; + if ( swapUsagePercent > 100 ) + swapUsagePercent = 100; + + if ( memoryUsagePercent < 0 ) + memoryUsagePercent = 0; + if ( memoryUsagePercent > 100 ) + memoryUsagePercent = 100; + // check for Memory alarms if (memoryUsagePercent >= memoryCritical && memoryCritical > 0 ) { if ( monitorPeriod == MONITOR_PERIOD ) { - //first time called, log - //adjust if over 100% - if ( memoryUsagePercent > 100 ) - memoryUsagePercent = 100; LoggingID lid(SERVER_MONITOR_LOG_ID); MessageLog ml(lid); diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index c0d53c989..a25943f67 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -3783,7 +3783,6 @@ void ProcessManager::setSystemState(uint16_t state) { // log.writeLog(__LINE__, "EXCEPTION ERROR on MessageQueueClient: Caught unknown exception!", LOG_TYPE_ERROR); } - pthread_mutex_unlock(&STATUS_LOCK); // Process Alarms string system = "System"; @@ -3798,7 +3797,11 @@ void ProcessManager::setSystemState(uint16_t state) else if ( state == oam::AUTO_OFFLINE ) aManager.sendAlarmReport(system.c_str(), SYSTEM_DOWN_AUTO, SET); + //this alarm doesnt get clear by reporter, so clear on stopage + aManager.sendAlarmReport(system.c_str(), CONN_FAILURE, CLEAR); } + + pthread_mutex_unlock(&STATUS_LOCK); } /****************************************************************************************** diff --git a/utils/common/cgroupconfigurator.cpp b/utils/common/cgroupconfigurator.cpp index 1c3046af6..01eb4f6f4 100644 --- a/utils/common/cgroupconfigurator.cpp +++ b/utils/common/cgroupconfigurator.cpp @@ -173,9 +173,6 @@ uint64_t CGroupConfigurator::getTotalMemory() { uint64_t ret; - if (totalMemory != 0) - return totalMemory; - if (!cGroupDefined) ret = getTotalMemoryFromProc(); else { @@ -183,7 +180,11 @@ uint64_t CGroupConfigurator::getTotalMemory() if (ret == 0) ret = getTotalMemoryFromProc(); } - //cout << "Total mem available is " << ret << endl; + //ostringstream os; + //os << "Total mem available is " << ret; + //cerr << os.str() << endl; + //log(logging::LOG_TYPE_WARNING, os.str()); + totalMemory = ret; return totalMemory; } @@ -216,17 +217,31 @@ uint64_t CGroupConfigurator::getTotalMemoryFromProc() input[79] = '\0'; pclose(cmdPipe); memTot = atoi(input); + + //ostringstream os; + //os << "FreeBSD Total mem available is " << memTot; + //cerr << os.str() << endl; + //log(logging::LOG_TYPE_WARNING, os.str()); #else ifstream in("/proc/meminfo"); string x; in >> x; in >> memTot; + + //ostringstream os; + //os << "meminfo Total mem available is " << memTot; + //cerr << os.str() << endl; + //log(logging::LOG_TYPE_WARNING, os.str()); #endif //memTot is now in KB, convert to bytes memTot *= 1024; + //os << "meminfo Total bytes mem available is " << memTot; + //cerr << os.str() << endl; + //log(logging::LOG_TYPE_WARNING, os.str()); + return memTot; } @@ -307,9 +322,8 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup() uint64_t CGroupConfigurator::getFreeMemoryFromProc() { uint64_t memFree = 0; - uint64_t buffers = 0; - uint64_t cached = 0; - uint64_t memTotal = 0; + uint64_t memAvailable = 0; + uint64_t memTotal = 0; #if defined(_MSC_VER) MEMORYSTATUSEX memStat; @@ -338,18 +352,15 @@ uint64_t CGroupConfigurator::getFreeMemoryFromProc() in >> memFree; in >> x; // kB - in >> x; // Buffers: - in >> buffers; + in >> x; // MemAvailable: + in >> memAvailable; in >> x; // kB - in >> x; // Cached: - in >> cached; #endif // amount available for application - memFree = memFree + buffers + cached; - memFree *= 1024; - return memFree; + memAvailable *= 1024; + return memAvailable; } uint64_t CGroupConfigurator::getTotalSwapSpace() From 22191d908890ecf6dc4e911d70c14b8336bc693a Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 30 May 2017 14:33:21 -0500 Subject: [PATCH 088/185] MCOL-379 - changed to make the check for mem available for dynamic --- utils/common/cgroupconfigurator.cpp | 51 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/utils/common/cgroupconfigurator.cpp b/utils/common/cgroupconfigurator.cpp index 01eb4f6f4..a4a67d68e 100644 --- a/utils/common/cgroupconfigurator.cpp +++ b/utils/common/cgroupconfigurator.cpp @@ -173,6 +173,9 @@ uint64_t CGroupConfigurator::getTotalMemory() { uint64_t ret; + if (totalMemory != 0) + return totalMemory; + if (!cGroupDefined) ret = getTotalMemoryFromProc(); else { @@ -180,11 +183,7 @@ uint64_t CGroupConfigurator::getTotalMemory() if (ret == 0) ret = getTotalMemoryFromProc(); } - //ostringstream os; - //os << "Total mem available is " << ret; - //cerr << os.str() << endl; - //log(logging::LOG_TYPE_WARNING, os.str()); - + //cout << "Total mem available is " << ret << endl; totalMemory = ret; return totalMemory; } @@ -217,31 +216,17 @@ uint64_t CGroupConfigurator::getTotalMemoryFromProc() input[79] = '\0'; pclose(cmdPipe); memTot = atoi(input); - - //ostringstream os; - //os << "FreeBSD Total mem available is " << memTot; - //cerr << os.str() << endl; - //log(logging::LOG_TYPE_WARNING, os.str()); #else ifstream in("/proc/meminfo"); string x; in >> x; in >> memTot; - - //ostringstream os; - //os << "meminfo Total mem available is " << memTot; - //cerr << os.str() << endl; - //log(logging::LOG_TYPE_WARNING, os.str()); #endif //memTot is now in KB, convert to bytes memTot *= 1024; - //os << "meminfo Total bytes mem available is " << memTot; - //cerr << os.str() << endl; - //log(logging::LOG_TYPE_WARNING, os.str()); - return memTot; } @@ -322,24 +307,26 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup() uint64_t CGroupConfigurator::getFreeMemoryFromProc() { uint64_t memFree = 0; - uint64_t memAvailable = 0; + uint64_t buffers = 0; + uint64_t cached = 0; uint64_t memTotal = 0; + uint64_t memAvailable = 0; #if defined(_MSC_VER) MEMORYSTATUSEX memStat; memStat.dwLength = sizeof(memStat); if (GlobalMemoryStatusEx(&memStat)) { - memFree = memStat.ullAvailPhys; + memAvailable = memStat.ullAvailPhys; #ifndef _WIN64 uint64_t tmp = getTotalMemoryFromProc(); if (memFree > tmp) - memFree = tmp; + memAvailable = tmp; #endif } #elif defined(__FreeBSD__) // FreeBSD is not supported, no optimization. - memFree = 0; + memAvailable = 0; #else ifstream in("/proc/meminfo"); string x; @@ -352,10 +339,22 @@ uint64_t CGroupConfigurator::getFreeMemoryFromProc() in >> memFree; in >> x; // kB - in >> x; // MemAvailable: - in >> memAvailable; - in >> x; // kB + //check if available or buffers is passed + in >> x; + if ( x == "MemAvailable:") + { + in >> memAvailable; // MemAvailable + } + else + { // centos 6 and older OSs + in >> buffers; + in >> x; // kB + in >> x; // Cached: + in >> cached; + + memAvailable = memFree + buffers + cached; + } #endif // amount available for application From c51746602667773c5a5206731857203215393cc2 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 2 Jun 2017 14:50:40 +0100 Subject: [PATCH 089/185] MCOL-730 Fix decimals in cross engine join We would get strange values for scale/precision in the results column of a cross engine join causing bad results. This patch uses the values from the libdrizzle client connector instead. --- dbcon/joblist/crossenginestep.cpp | 28 ++++++++++++++++++---------- dbcon/joblist/crossenginestep.h | 3 ++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/dbcon/joblist/crossenginestep.cpp b/dbcon/joblist/crossenginestep.cpp index 98098fe62..505b17de4 100644 --- a/dbcon/joblist/crossenginestep.cpp +++ b/dbcon/joblist/crossenginestep.cpp @@ -247,7 +247,7 @@ void CrossEngineStep::makeMappings() } -void CrossEngineStep::setField(int i, const char* value, Row& row) +void CrossEngineStep::setField(int i, const char* value, drizzle_column_st* field, Row& row) { CalpontSystemCatalog::ColDataType colType = row.getColType(i); @@ -263,9 +263,17 @@ void CrossEngineStep::setField(int i, const char* value, Row& row) { CalpontSystemCatalog::ColType ct; ct.colDataType = colType; - ct.colWidth = row.getColumnWidth(i); - ct.scale = row.getScale(i); - ct.precision = row.getPrecision(i); + ct.colWidth = row.getColumnWidth(i); + if (colType == CalpontSystemCatalog::DECIMAL) + { + ct.scale = field->decimals; + ct.precision = field->size; + } + else + { + ct.scale = row.getScale(i); + ct.precision = row.getPrecision(i); + } row.setIntField(convertValueNum(value, ct, row.getSignedNullValue(i)), i); } } @@ -500,7 +508,7 @@ void CrossEngineStep::execute() while ((rowIn = drizzle->nextRow()) && !cancelled()) { for(int i = 0; i < num_fields; i++) - setField(i, rowIn[i], fRowDelivered); + setField(i, rowIn[i], drizzle->getField(i), fRowDelivered); addRow(rgDataDelivered); } @@ -520,7 +528,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] != -1) - setField(fFe1Column[i], rowIn[i], rowFe1); + setField(fFe1Column[i], rowIn[i], drizzle->getField(i), rowFe1); } if (fFeFilters && fFeInstance->evaluate(rowFe1, fFeFilters.get()) == false) @@ -534,7 +542,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] == -1) - setField(i, rowIn[i], fRowDelivered); + setField(i, rowIn[i], drizzle->getField(i), fRowDelivered); } addRow(rgDataDelivered); @@ -552,7 +560,7 @@ void CrossEngineStep::execute() while ((rowIn = drizzle->nextRow()) && !cancelled()) { for(int i = 0; i < num_fields; i++) - setField(i, rowIn[i], rowFe3); + setField(i, rowIn[i], drizzle->getField(i), rowFe3); fFeInstance->evaluate(rowFe3, fFeSelects); fFeInstance->evaluate(rowFe3, fFeSelects); @@ -583,7 +591,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] != -1) - setField(fFe1Column[i], rowIn[i], rowFe1); + setField(fFe1Column[i], rowIn[i], drizzle->getField(i), rowFe1); } if (fFeFilters && fFeInstance->evaluate(rowFe1, fFeFilters.get()) == false) @@ -597,7 +605,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] == -1) - setField(i, rowIn[i], rowFe3); + setField(i, rowIn[i], drizzle->getField(i), rowFe3); } fFeInstance->evaluate(rowFe3, fFeSelects); diff --git a/dbcon/joblist/crossenginestep.h b/dbcon/joblist/crossenginestep.h index a0f21cc50..2c8411413 100644 --- a/dbcon/joblist/crossenginestep.h +++ b/dbcon/joblist/crossenginestep.h @@ -60,6 +60,7 @@ public: int getRowCount() { return drizzle_result_row_count(fDrzrp); } char** nextRow() { return drizzle_row_next(fDrzrp); } const string& getError() { return fErrStr; } + drizzle_column_st* getField(int field) { return drizzle_column_index(fDrzrp, field); } private: drizzle_st* fDrzp; @@ -149,7 +150,7 @@ protected: virtual void makeMappings(); virtual void addFilterStr(const std::vector&, const std::string&); virtual std::string makeQuery(); - virtual void setField(int, const char*, rowgroup::Row&); + virtual void setField(int, const char*, drizzle_column_st*, rowgroup::Row&); inline void addRow(rowgroup::RGData &); //inline void addRow(boost::shared_array&); virtual int64_t convertValueNum( From a82bf1c17effde490911d70268a1c8ec3b39aaff Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 2 Jun 2017 09:26:14 -0500 Subject: [PATCH 090/185] MCOL-734 - correct command name --- oamapps/mcsadmin/mcsadmin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index 375b21c96..b8dbde771 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -5774,7 +5774,7 @@ int processCommand(string* arguments) {} if ( !dbrootConfigList.empty() ) { - cout << "**** removeModule Failed : " << (*pt).DeviceName << " has dbroots still assigned. Please run movePmDbrootConfig or unassignPmDbrootConfig."; + cout << "**** removeModule Failed : " << (*pt).DeviceName << " has dbroots still assigned. Please run movePmDbrootConfig or unassignDbrootPmConfig."; quit = true; cout << endl; break; @@ -6747,7 +6747,7 @@ int processCommand(string* arguments) {} if ( !dbrootConfigList.empty() ) { - cout << endl << "**** alterSystem-disableModule Failed : " << (*pt).DeviceName << " has dbroots still assigned and will not be disabled. Please run movePmDbrootConfig or unassignPmDbrootConfig."; + cout << endl << "**** alterSystem-disableModule Failed : " << (*pt).DeviceName << " has dbroots still assigned and will not be disabled. Please run movePmDbrootConfig or unassignDbrootPmConfig."; quit = true; cout << endl; break; From 8ba6db5b36c7668685177fde63376c667145f268 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 2 Jun 2017 09:35:11 -0500 Subject: [PATCH 091/185] MCOL-538 - change mcsmysql alias --- oam/install_scripts/columnstoreAlias | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/install_scripts/columnstoreAlias b/oam/install_scripts/columnstoreAlias index b1dc3dd9c..9afb3f5fe 100644 --- a/oam/install_scripts/columnstoreAlias +++ b/oam/install_scripts/columnstoreAlias @@ -1,6 +1,6 @@ # MariaDB Columnstore Alias Commands # -alias mcsmysql='/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root' +alias mcsmysql='/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra=/usr/local/mariadb/columnstore/mysql/my.cnf -u root' alias ma=/usr/local/mariadb/columnstore/bin/mcsadmin alias mcsadmin=/usr/local/mariadb/columnstore/bin/mcsadmin alias cpimport=/usr/local/mariadb/columnstore/bin/cpimport From 4d5a59d3d104cda2a7715b4e619318e43e964214 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 2 Jun 2017 11:03:12 -0500 Subject: [PATCH 092/185] MCOL-538 - fix spelling issue --- oam/install_scripts/columnstoreAlias | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/install_scripts/columnstoreAlias b/oam/install_scripts/columnstoreAlias index 9afb3f5fe..cd225c1a9 100644 --- a/oam/install_scripts/columnstoreAlias +++ b/oam/install_scripts/columnstoreAlias @@ -1,6 +1,6 @@ # MariaDB Columnstore Alias Commands # -alias mcsmysql='/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra=/usr/local/mariadb/columnstore/mysql/my.cnf -u root' +alias mcsmysql='/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root' alias ma=/usr/local/mariadb/columnstore/bin/mcsadmin alias mcsadmin=/usr/local/mariadb/columnstore/bin/mcsadmin alias cpimport=/usr/local/mariadb/columnstore/bin/cpimport From 149c944bf0530a4dbaa4152ea839b6c60128d69a Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 12 Jun 2017 15:51:56 -0500 Subject: [PATCH 093/185] remove david clustertest dir --- utils/clusterTester/david.tar.gz | Bin 7608 -> 0 bytes .../david/columnstoreClusterTester.sh | 1077 ----------------- utils/clusterTester/david/os_detect.sh | 40 - utils/clusterTester/david/remote_command.sh | 92 -- utils/clusterTester/david/remote_scp_get.sh | 58 - utils/clusterTester/david/remote_scp_put.sh | 57 - 6 files changed, 1324 deletions(-) delete mode 100644 utils/clusterTester/david.tar.gz delete mode 100755 utils/clusterTester/david/columnstoreClusterTester.sh delete mode 100755 utils/clusterTester/david/os_detect.sh delete mode 100755 utils/clusterTester/david/remote_command.sh delete mode 100755 utils/clusterTester/david/remote_scp_get.sh delete mode 100755 utils/clusterTester/david/remote_scp_put.sh diff --git a/utils/clusterTester/david.tar.gz b/utils/clusterTester/david.tar.gz deleted file mode 100644 index b6ec9cfc216c1fd8a67e74deae1ed9dd972fff3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7608 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 diff --git a/utils/clusterTester/david/columnstoreClusterTester.sh b/utils/clusterTester/david/columnstoreClusterTester.sh deleted file mode 100755 index 40ac05197..000000000 --- a/utils/clusterTester/david/columnstoreClusterTester.sh +++ /dev/null @@ -1,1077 +0,0 @@ -#!/bin/bash - -bold=$(tput bold) -normal=$(tput sgr0) - -IPADDRESSES="" -OS="" -PASSWORD="ssh" -CHECK=true -REPORTPASS=true -LOGFILE="" - -OS_LIST=("centos6" "centos7" "debian8" "suse12" "ubuntu16") - -NODE_IPADDRESS="" - -checkContinue() { - - if [ "$CHECK" = false ]; then - return 0 - fi - - echo "" - read -p "Failure occurred, do you want to continue? (y,n) > " answer - case ${answer:0:1} in - y|Y ) - return 0 - ;; - * ) - exit - ;; - esac -} - -### -# Print Fucntions -### - -helpPrint () { - ################################################################################ - echo "" - echo "This is the MariaDB ColumnStore Cluster System Test tool." - echo "" - echo "It will run a set of test to validate the setup of the MariaDB Columnstore system." - echo "This can be run prior to the install of MariaDB ColumnStore to make sure the" - echo "servers/nodes are configured properly. It should be run as the user of the planned" - echo "install. Meaning if MariaDB ColumnStore is going to be installed as root user," - echo "then run from root user. Also the assumption is that the servers/node have be" - echo "setup based on the Preparing for ColumnStore Installation." - echo "It should also be run on the server that is designated as Performance Module #1." - echo "This is the same server where the MariaDB ColumnStore package would be installed" - echo " and where the install script would be executed from, postConfigure." - echo "" - echo "Additional information on Tool is documented at:" - echo "" - echo "https://mariadb.com/kb/en/mariadb/*****/" - echo "" - echo "Items that are checked:" - echo " Node Ping test" - echo " Node SSH test" - echo " ColumnStore Port test" - echo " OS version" - echo " Locale settings" - echo " Firewall settings" - echo " Date/time settings" - echo " Dependent packages installed" - echo " For non-root user install - test permissions on /tmp and /dev/shm" - echo "" - echo "Usage: $0 [options]" - echo "OPTIONS:" - echo " -h,--help Help" - echo " --ipaddr=[ipaddresses] Remote Node IP-Addresses/Hostnames, if not provide, will only check local node" - echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" - echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, suse12, ubuntu16)" - echo " --password=[password] Provide a user password. (Default: ssh-keys setup will be assumed)" - echo " -c,--continue Continue on failures" - echo " --logfile=[fileName] Output results to a log file" - echo "" - echo "NOTE: Dependent package : 'nmap' and 'expect' packages need to be installed locally" - echo "" -} - -# Parse command line options. -while getopts hc-: OPT; do - case "$OPT" in - h) - echo $USAGE - helpPrint - exit 0 - ;; - c) - CHECK=false - ;; - -) LONG_OPTARG="${OPTARG#*=}" - ## Parsing hack for the long style of arguments. - case $OPTARG in - help ) - helpPrint - exit 0 - ;; - continue ) - CHECK=false - ;; - ipaddr=?* ) - IPADDRESSES="$LONG_OPTARG" - ;; - os=?* ) - OS="$LONG_OPTARG" - match=false - for SUPPORTED_OS in "${OS_LIST[@]}"; do - if [ $SUPPORTED_OS == "$OS" ]; then - match=true - break; - fi - done - - if [ $match == "false" ] ; then - echo "" - echo "OS version not-supported, please re-run and provide the OS from list of support OSs " - for SUPPORTED_OS in "${OS_LIST[@]}"; do - echo "$SUPPORTED_OS" - done - echo "" - exit 1 - fi - - ;; - password=?* ) - PASSWORD="$LONG_OPTARG" - ;; - logfile=?* ) - LOGFILE="$LONG_OPTARG" - exec 1<>$LOGFILE - exec 2>&1 - ;; - ipaddr* ) - echo "No arg for --$OPTARG option" >&2 - exit 1 - ;; - os* ) - echo "No arg for --$OPTARG option" >&2 - exit 1 - ;; - password* ) - echo "No arg for --$OPTARG option" >&2 - exit 1 - ;; - continue* ) - echo "No arg allowed for --$OPTARG option" >&2 - exit 1 - ;; - logfile* ) - echo "No arg for --$OPTARG option" >&2 - exit 1 - ;; - help* ) - helpPrint - exit 0 - ;; - '' ) - break ;; # "--" terminates argument processing - * ) - echo "Illegal option --$OPTARG" >&2 - exit 1 - ;; - esac - ;; - \?) - # getopts issues an error message - echo $USAGE >&2 - exit 1 - ;; - esac -done - -# Remove the switches we parsed above. -shift `expr $OPTIND - 1` - -if [ "$IPADDRESSES" != "" ]; then - #parse IP Addresses into an array - IFS=',' - read -ra NODE_IPADDRESS <<< "$IPADDRESSES" - - if ! type expect > /dev/null 2>&1 ; then - echo "expect is not installed. Please install and rerun." - exit 1 - fi - - if ! type nmap > /dev/null 2>&1; then - echo "nmap is not installed. Please install and rerun." - exit 1 - fi -fi - -checkLocalOS() -{ - echo "** Validate local OS is supported" - echo "" - - #get local OS - `./os_detect.sh > /tmp/os_detect 2>&1` - if [ "$?" -eq 0 ]; then - localOS=`cat /tmp/os_detect | grep "Operating System name" | cut -f2 -d '"'` - echo "Local Node OS System Name : $localOS" - - if [ "$OS" != "" ] ; then - echo "" - echo "Local Node OS Versions doesn't match the command line OS argument" - echo "Contining using the Detected Local Node OS Version" - OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` - - echo "Local Node OS Version : $OS" - else - OS=`cat /tmp/os_detect | grep "Operating System tag" | cut -f4 -d " "` - fi - else - if [ "$OS" == "" ] ; then - echo "" - echo "Operating System name doesn't match any of the supported OS's" - if [ $LOGFILE == true ] ; then - exit 1 - fi - - echo "Please select from this OS list or enter 'exit'" - for SUPPORTED_OS in "${OS_LIST[@]}"; do - echo "$SUPPORTED_OS" - done - - read -p "Enter OS or 'exit' > " answer - if [ $answer == 'exit' ] ; then - exit 1 - fi - match=false - for SUPPORTED_OS in "${OS_LIST[@]}"; do - if [ $SUPPORTED_OS == $answer ] ; then - match=true - break; - fi - done - - if [ $match == "false" ] ; then - echo "OS version unknown, please re-run and provide the OS in the command line --os" - exit 1 - fi - fi - fi -} - -checkLocalDir() -{ - if [ "$USER" != "root" ]; then - # Non-root User directory permissions check - # - echo "" - echo "** Run Non-root User directory permissions check on Local Node" - echo "" - - #remove any check tmp files from previous runs - `sudo rm -f /tmp/*_check > /dev/null 2>&1` - - #check /tmp and /dev/shm - pass=true - `touch /tmp/cs_check > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "Local Node permission test on /tmp : Passed" - `rm -f /tmp/cs_check` - else - echo "Local Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" - exit 1 - fi - - `touch /dev/shm/cs_check > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "Local Node permission test on /dev/shm : Passed" - `rm -f /dev/shm/cs_check` - else - echo "Local Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" - pass=false - REPORTPASS=false - fi - fi -} - -checkPing() -{ - # ping test - # - echo "" - echo "** Run Ping access Test to remote nodes" - echo "" - - for ipadd in "${NODE_IPADDRESS[@]}"; do - - `ping $ipadd -c 1 -w 5 > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo $ipadd " Node Passed ping test" - else - echo $ipadd " Node ${bold}Failed${normal} ping test, correct and retest" - exit 1 - fi - done -} - -checkSSH() -{ - # Login test - # - echo "" - echo "** Run SSH Login access Test to remote nodes" - echo "" - - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD ls 1 > /dev/null 2>&1`; - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - if [ $PASSWORD == "ssh" ] ; then - echo $ipadd " Node Passed SSH login test using ssh-keys" - else - echo $ipadd " Node Passed SSH login test using user password" - fi - else - if [ $PASSWORD == "ssh" ] ; then - echo $ipadd " Node ${bold}Failed${normal} SSH login test using ssh-keys" - else - echo $ipadd " Node ${bold}Failed${normal} SSH login test using user password" - fi - exit 1 - fi - done -} - -checkRemoteDir() -{ - # - # remove old _check tmp files from remote servers - - `sudo rm -f /tmp/*_check > /dev/null 2>&1` - - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'sudo rm -f /tmp/*_check > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` - done - - if [ "$USER" != "root" ]; then - # Non-root User directory permissions check - # - echo "" - echo "** Run Non-root User directory permissions check on remote nodes" - echo "" - - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'touch /tmp/cs_check' 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "$ipadd Node permission test on /tmp : ${bold}Failed${normal}, change permissions to 777 and re-test" - exit 1 - else - echo "$ipadd Node permission test on /tmp : Passed" - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - REPORTPASS=false - fi - - `./remote_command.sh $ipadd $PASSWORD 'touch /dev/shm/cs_check' 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `grep "Permission denied" /tmp/remote_command_check > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "$ipadd Node permission test on /dev/shm : ${bold}Failed${normal}, change permissions to 777 and re-test" - pass=false - REPORTPASS=false - else - echo "$ipadd Node permission test on /dev/shm : Passed" - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - REPORTPASS=false - fi - done - - if ! $pass; then - checkContinue - fi - fi -} - -checkOS() -{ - # Os check - # - echo "" - echo "** Run OS check - OS version needs to be the same on all nodes" - echo "" - - echo "Local Node OS Version : $localOS" - echo "" - - pass=true - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_put.sh $ipadd $PASSWORD os_detect.sh 1 > /tmp/remote_scp_put_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_put.sh to $ipadd Node, check /tmp/remote_scp_put_check" - else - `./remote_command.sh $ipadd $PASSWORD './os_detect.sh > /tmp/os_detect 2>&1' 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/os_detect > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - remoteOS=`cat os_detect | grep "Operating System name" | cut -f2 -d '"'` - echo "$ipadd Node OS Version : $remoteOS" - if [ $localOS != $remoteOS ]; then - echo "${bold}Failed${normal}, $ipadd has a different OS than local node" - pass=false - REPORTPASS=false - fi - rm -f os_detect - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - REPORTPASS=false - fi - fi - done - - if ! $pass; then - checkContinue - fi -} - -checkLocale() -{ - # Locale check - # - echo "" - echo "** Run Locale check - Locale needs to be the same on all nodes" - echo "" - - #get local Locale - `locale | grep LANG= > /tmp/locale_check 2>&1` - if [ "$?" -eq 0 ]; then - echo "Local Node Locale : `cat /tmp/locale_check`" - else - echo "Error running 'locale' command on local node" - fi - - pass=true - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'locale | grep LANG= > /tmp/locale_check 2>&1' 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/locale_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - echo "$ipadd Node Locale : `cat locale_check`" - `diff /tmp/locale_check locale_check > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, $ipadd has a different Locale setting than local node" - pass=false - REPORTPASS=false - fi - `rm -f locale_check` - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - REPORTPASS=false - fi - done - - if ! $pass; then - checkContinue - fi -} - -checkSELINUX() -{ - # SELINUX check - # - echo "" - echo "** Run SELINUX check - Setting should to be disabled on all nodes" - echo "" - - pass=true - #check local SELINUX - if [ -f /etc/selinux/config ]; then - `cat /etc/selinux/config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node SELINUX setting is Enabled, please disable" - pass=false - REPORTPASS=false - else - echo "Local Node SELINUX setting is Not Enabled" - fi - else - echo "Local Node SELINUX setting is Not Enabled" - fi - - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_scp_get.sh $ipadd $PASSWORD /etc/selinux/config > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "$ipadd Node SELINUX setting is Not Enabled" - else - `cat config | grep SELINUX | grep enforcing > /tmp/selinux_check 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd SELINUX setting is Enabled, please disable" - pass=false - REPORTPASS=false - else - echo "$ipadd Node SELINUX setting is Not Enabled" - fi - `rm -f config` - fi - done - - if ! $pass; then - checkContinue - fi -} - -checkFirewalls() -{ - # FIREWALL checks - # - echo "" - echo "** Run Firewall Services check - Firewall Services should to be disabled on all nodes" - echo "" - - declare -a FIREWALL_LIST=("iptables" "ufw" "firewalld" "firewall") - - fpass=true - #check local FIREWALLS - `chkconfig > /tmp/firewall_check 2>&1` - for firewall in "${FIREWALL_LIST[@]}"; do - pass=true - `cat /tmp/firewall_check | grep $firewall | grep on > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in chkconfig, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - - `systemctl status $firewall > /tmp/firewall1_check 2>&1` - `cat /tmp/firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node $firewall service is Enabled in systemctl, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - - if $pass ; then - echo "Local Node $firewall service is Not Enabled" - fi - done - - if ! $fpass; then - checkContinue - fi - - echo "" - fpass=true - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'chkconfig > /tmp/firewall_check 2>&1' 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - for firewall in "${FIREWALL_LIST[@]}"; do - pass=true - `cat firewall_check | grep $firewall | grep on > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in chkconfig, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - `rm -f firewall1_check` - fi - fi - - if $pass ; then - echo "$ipadd Node $firewall service is Not Enabled" - fi - done - - `rm -f firewall_check` - fi - else - # 'sysconfig not on remote node - for firewall in "${FIREWALL_LIST[@]}"; do - pass=true - `./remote_command.sh $ipadd $PASSWORD "systemctl status '$firewall' > /tmp/firewall1_check 2>&1" 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/firewall1_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat firewall1_check | grep "Active: active" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node $firewall service is Enabled in systemctl, please disable" - pass=false - fpass=false - REPORTPASS=false - fi - `rm -f firewall1_check` - - if $pass ; then - echo "$ipadd Node $firewall service is Not Enabled" - fi - fi - fi - - if $pass ; then - echo "$ipadd Node $firewall service is Not Enabled" - fi - done - fi - - echo "" - done - - if ! $fpass; then - checkContinue - fi - - if [ $OS == "suse12" ]; then - # rcSuSEfirewall2 check - # - echo "" - echo "** Run rcSuSEfirewall2 check - Service should to be disabled on all nodes" - echo "" - - pass=true - #check local IPTABLES - `/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1` - `cat /tmp/rcSuSEfirewall2_check | grep active > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node rcSuSEfirewall2 service is Enabled, please disable" - pass=false - REPORTPASS=false - else - echo "Local Node rcSuSEfirewall2 service is Not Enabled" - fi - - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD '/sbin/rcSuSEfirewall2 status > /tmp/rcSuSEfirewall2_check 2>&1' 1 > /tmp/remote_command_check` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/rcSuSEfirewall2_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat rcSuSEfirewall2_check | grep active > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node rcSuSEfirewall2 service is Enabled, please disable" - pass=false - REPORTPASS=false - else - echo "$ipadd Node rcSuSEfirewall2 service is Not Enabled" - fi - `rm -f rcSuSEfirewall2_check` - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - REPORTPASS=false - fi - done - - if ! $pass; then - checkContinue - fi - fi -} - -checkPorts() -{ - # port test - # - echo "" - echo "** Run MariaDB ColumnStore Port (8600-8620) availibility test" - echo "" - - pass=true - for ipadd in "${NODE_IPADDRESS[@]}"; do - - `nmap $ipadd -p 8600-8620 | grep 'closed unknown' > /dev/null` - if [ "$?" -eq 0 ]; then - echo $ipadd " Node Passed port test" - else - echo $ipadd " Node ${bold}Failed${normal} port test, check and disable any firwalls that were reported enabled" - pass=false - REPORTPASS=false - fi - done - - if ! $pass; then - checkContinue - fi -} - -checkTime() -{ - # Time check - # - echo "" - echo "** Run Date/Time check - Date/Time should be within 10 seconds on all nodes" - echo "" - - pass=true - #get local epoch time - localTime=`date +%s` - for ipadd in "${NODE_IPADDRESS[@]}"; do - `./remote_command.sh $ipadd $PASSWORD 'date +%s > /tmp/time_check' > /tmp/time_check` - rc="$?" - if [ $rc -ne 0 ] ; then - echo $ipadd " Node ${bold}Failed${normal} date/time check failed, check /tmp/time_check" - pass=false - REPORTPASS=false - else - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/time_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - remoteTime=`cat time_check` - timeDiff=`echo "$(($remoteTime-$localTime))"` - range=10 - if [ $timeDiff -gt $range ] || [ $timeDiff -lt -$range ] ; then - echo $ipadd " Node ${bold}Failed${normal}, $ipadd Node date/time is more than 10 seconds away from local node" - pass=false - else - echo "Passed: $ipadd Node date/time is within 10 seconds of local node" - fi - fi - fi - done - `rm -f time_check` - - if ! $pass; then - checkContinue - fi -} - -checkPackages() -{ - # - # now check packaging on local and remote nodes - # - - echo "" - echo "** Run MariaDB ColumnStore Dependent Package Check" - echo "" - - declare -a CENTOS_PKG=("boost" "expect" "perl" "perl-DBI" "openssl" "zlib" "file" "sudo" "perl-DBD-MySQL" "libaio" "rsync" "snappy" "net-tools") - - if [ "$OS" == "centos6" ] || [ "$OS" == "centos7" ]; then - if [ ! `which yum 2>/dev/null` ] ; then - echo "${bold}Failed${normal}, Local Node ${bold}yum${normal} package not installed" - pass=false - REPORTPASS=false - else - pass=true - #check centos packages on local node - for PKG in "${CENTOS_PKG[@]}"; do - if [ $OS == "centos6" ] && [ "$PKG" == "boost" ]; then - `ls /usr/lib/libboost_regex.so > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, Local Node ${bold}boost libraries${normal} not installed" - pass=false - REPORTPASS=false - fi - else - `yum list installed "$PKG" > /tmp/pkg_check 2>&1` - `cat /tmp/pkg_check | grep Installed > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - fi - done - fi - - if [ $pass == true ] ; then - echo "Local Node - Passed, all dependency packages are installed" - else - checkContinue - fi - - echo "" - pass=true - if [ "$IPADDRESSES" != "" ]; then - for ipadd in "${NODE_IPADDRESS[@]}"; do - for PKG in "${CENTOS_PKG[@]}"; do - if [ $OS == "centos6" ] && [ $PKG == "boost" ]; then - `./remote_command.sh $ipadd $PASSWORD 'ls /usr/lib/libboost_regex.so > /dev/null 2>&1' 1 > /tmp/remote_command_check 2>&1` - if [ $? -ne 0 ] ; then - echo "${bold}Failed${normal}, $ipadd Node ${bold}boost libraries${normal} not installed" - pass=false - REPORTPASS=false - fi - else - `./remote_command.sh $ipadd $PASSWORD "yum list installed '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -eq 2 ] ; then - echo "${bold}Failed${normal}, $ipadd Node, 'yum' not installed" - pass=false - REPORTPASS=false - break - elif [ $rc -eq 1 ] ; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - fi - done - - if $pass; then - echo "$ipadd Node - Passed, all dependency packages are installed" - else - checkContinue - fi - echo "" - done - fi - fi - - declare -a SUSE_PKG=("boost-devel" "expect" "perl" "perl-DBI" "openssl" "file" "sudo" "libaio1" "rsync" "libsnappy1" "net-tools") - - if [ "$OS" == "suse12" ]; then - if [ ! `which rpm 2>/dev/null` ] ; then - echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" - pass=false - REPORTPASS=false - else - pass=true - #check centos packages on local node - for PKG in "${SUSE_PKG[@]}"; do - `rpm -qi "$PKG" > /tmp/pkg_check 2>&1` - `cat /tmp/pkg_check | grep "not installed" > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - done - - if $pass; then - echo "Local Node - Passed, all dependency packages are installed" - else - checkContinue - fi - fi - - echo "" - pass=true - if [ "$IPADDRESSES" != "" ]; then - for ipadd in "${NODE_IPADDRESS[@]}"; do - for PKG in "${SUSE_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "rpm -qi '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -ne 0 ] ; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - done - - if $pass; then - echo "$ipadd Node - Passed, all dependency packages are installed" - else - checkContinue - fi - echo "" - done - fi - fi - - declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "snappy" "net-tools") - - if [ "$OS" == "ubuntu16" ] ; then - if [ ! `which dpkg 2>/dev/null` ] ; then - echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" - pass=false - REPORTPASS=false - else - pass=true - #check centos packages on local node - for PKG in "${UBUNTU_PKG[@]}"; do - `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` - `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - done - - if $pass; then - echo "Local Node - Passed, all dependency packages are installed" - else - checkContinue - fi - fi - - echo "" - pass=true - if [ "$IPADDRESSES" != "" ]; then - for ipadd in "${NODE_IPADDRESS[@]}"; do - for PKG in "${UBUNTU_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" - pass=false - break - else - `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - fi - - `rm -f pkg_check` - fi - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - fi - done - - if $pass; then - echo "$ipadd Node - Passed, all dependency packages are installed" - else - checkContinue - fi - echo "" - done - fi - fi - - declare -a DEBIAN_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "libreadline-dev" "rsync" "libsnappy1" "net-tools") - - if [ "$OS" == "debian8" ]; then - if [ ! `which dpkg 2>/dev/null` ] ; then - echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" - pass=false - REPORTPASS=false - else - pass=true - #check centos packages on local node - for PKG in "${DEBIAN_PKG[@]}"; do - `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` - `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - REPORTPASS=false - fi - done - - if $pass; then - echo "Local Node - Passed, all dependency packages are installed" - else - checkContinue - fi - fi - - echo "" - pass=true - if [ "$IPADDRESSES" != "" ]; then - for ipadd in "${NODE_IPADDRESS[@]}"; do - for PKG in "${DEBIAN_PKG[@]}"; do - `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` - rc="$?" - if [ $rc -eq 0 ] || ( [ $rc -eq 2 ] && [ $OS == "suse12" ] ) ; then - `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` - if [ "$?" -ne 0 ]; then - echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" - else - `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` - if [ "$?" -eq 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" - pass=false - break - else - `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` - if [ "$?" -ne 0 ]; then - echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" - pass=false - fi - - `rm -f pkg_check` - fi - fi - else - echo "Error running remote_command.sh to $ipadd Node, check /tmp/remote_command_check" - pass=false - fi - done - - if $pass; then - echo "$ipadd Node - Passed, all dependency packages are installed" - else - checkContinue - fi - echo "" - done - fi - fi -} - -echo "" -echo "*** This is the MariaDB Columnstore Cluster System test tool ***" -echo "" - -checkLocalOS -checkLocalDir -if [ "$IPADDRESSES" != "" ]; then - checkPing - checkSSH - checkRemoteDir - checkOS - checkLocale - checkSELINUX - checkFirewalls - checkPorts - checkTime -fi -checkPackages - -if [ $REPORTPASS == true ] ; then - echo "" - echo "*** Finished Validation of the Cluster, all Test Passed ***" - echo "" - exit 0 -else - echo "" - echo "*** Finished Validation of the Cluster, Failures occurred. Check for Error/Failed test results ***" - echo "" - exit 1 -fi - diff --git a/utils/clusterTester/david/os_detect.sh b/utils/clusterTester/david/os_detect.sh deleted file mode 100755 index 1f76a3716..000000000 --- a/utils/clusterTester/david/os_detect.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -# -detectOS () { - checkFile1=/etc/os-release - checkFile2=/etc/centos-release - if [ -f "$checkFile1" ] - then - osPrettyName=`cat $checkFile1 | grep PRETTY_NAME|awk -F"=" '{print $2}'` - osVersionID=`cat $checkFile1 | grep VERSION_ID | awk -F"=" '{print $2}' | awk -F"." '{print $1}' | sed 's/"//g'` - else - osPrettyName=`head -n 1 $checkFile2` - osVersionID=`echo $osPrettyName | awk -F" " '{print $3}' | awk -F"." '{print $1}'` - fi -# - osName=`echo $osPrettyName | awk -F" " '{print $1}' | sed 's/"//g'` - if [ -z "$osPrettyName" ] - then - osPrettyName=`uname -o -s -r -v` - fi - if [ -z "$osName" ] || [ -z "$osVersionID" ] - then - osTag="" - else - osTag=`echo $osName$osVersionID | awk '{print tolower($0)}'` - fi -} -# - detectOS - echo Operating System name: $osPrettyName - echo Operating System tag: $osTag - case "$osTag" in - centos6|centos7|ubuntu16|debian8|suse12) - ;; - *) - echo OS not supported - exit 1 - ;; - esac - - exit 0 diff --git a/utils/clusterTester/david/remote_command.sh b/utils/clusterTester/david/remote_command.sh deleted file mode 100755 index 4525a4ed3..000000000 --- a/utils/clusterTester/david/remote_command.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/expect -# -# $Id: remote_command.sh 3495 2012-12-17 22:51:40Z dhill $ -# -# Remote command execution script to another server -# Argument 1 - Remote Server Host Name or IP address -# Argument 2 - Remote Server password -# Argument 3 - Command -# Argument 4 - debug flag -# Argument 5 - Remote user name (optional) -# Argument 6 - Force a tty to be allocated (optional) -set stty_init {cols 512 -opost}; -set timeout 10 -set SERVER [lindex $argv 0] -set PASSWORD [lindex $argv 1] -set COMMAND [lindex $argv 2] -set DEBUG [lindex $argv 3] - -if {[info exists env(USER)]} { - set USERNAME $env(USER) -} else { - set USERNAME "root" -} - -set UNM [lindex $argv 4] -if { $UNM != "" && $UNM != "-" } { - set USERNAME "$UNM" -} -set TTY "" -set TTYOPT [lindex $argv 5] -if { $TTYOPT != "" } { - set TTY "-t" -} -log_user $DEBUG -spawn -noecho /bin/bash -#expect -re {[$#] } - -if { $PASSWORD == "ssh" } { - set PASSWORD "" -} - -# -# send command -# -send "ssh -v $TTY $USERNAME@$SERVER '$COMMAND'\n" -expect { - "cannot access" { exit 1} - "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1} - "service not known" { send_user " FAILED: Invalid Host\n" ; exit 1} - "ssh: connect to host" { send_user " FAILED: Invalid Host\n" ; exit 1 } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "authenticity" { send "yes\n" - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - "command not found" { exit 3 } -# -re {[$#] } { exit 0 } - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - "Exit status 3" { exit 1 } - "Exit status 4" { exit 1 } - timeout { exit 2 } - "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } -} -expect { - "command not found" { exit 3 } -# -re {[$#] } { exit 0 } - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - "Exit status 3" { exit 1 } - "Exit status 4" { exit 1 } - timeout { exit 2 } - "cannot access" { exit 1} - "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } - - "(y or n)" { send "y\n" - "command not found" { exit 3 } -# expect -re {[$#] } { exit 0 } - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - "Exit status 3" { exit 1 } - "Exit status 4" { exit 1 } - timeout { exit 2 } - } -} -exit 0 - diff --git a/utils/clusterTester/david/remote_scp_get.sh b/utils/clusterTester/david/remote_scp_get.sh deleted file mode 100755 index aee668b13..000000000 --- a/utils/clusterTester/david/remote_scp_get.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/expect -# -# $Id: remote_commend.sh 421 2007-04-05 15:46:55Z dhill $ -# -# Remote command execution script to another server -# Argument 1 - Remote Server Host Name or IP address -# Argument 2 - Remote Server root password -# Argument 3 - Command -set timeout 10 -set USERNAME $env(USER)"@" -set SERVER [lindex $argv 0] -set PASSWORD [lindex $argv 1] -set FILE [lindex $argv 2] -set DEBUG [lindex $argv 3] -log_user $DEBUG -spawn -noecho /bin/bash - -if { $PASSWORD == "ssh" } { - set PASSWORD "" -} - -# -# send command -# -#expect -re {[$#] } -send "scp -v $USERNAME$SERVER:$FILE .\n" -expect { - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - "100%" { send_user "DONE\n" ; exit 0 } - "authenticity" { send "yes\n" - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection timed out" { send_user "FAILED: Connection timed out\n" ; exit 1 } - "lost connection" { send_user "FAILED: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - "scp:" { send_user "FAILED\n" ; exit 1 } - "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } -} -expect { - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - "100%" { send_user "DONE\n" ; exit 0 } - "scp:" { send_user "FAILED\n" ; exit 1 } - "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } - "No such file or directory" { send_user "FAILED: No such file or directory\n" ; exit 1 } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } -} -exit 0 - diff --git a/utils/clusterTester/david/remote_scp_put.sh b/utils/clusterTester/david/remote_scp_put.sh deleted file mode 100755 index 7eb6c1ecb..000000000 --- a/utils/clusterTester/david/remote_scp_put.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/expect -# -# $Id: remote_commend.sh 421 2007-04-05 15:46:55Z dhill $ -# -# Remote command execution script to another server -# Argument 1 - Remote Server Host Name or IP address -# Argument 2 - Remote Server root password -# Argument 3 - Command -set timeout 30 -set USERNAME $env(USER)"@" -set SERVER [lindex $argv 0] -set PASSWORD [lindex $argv 1] -set FILE [lindex $argv 2] -set DEBUG [lindex $argv 3] -log_user $DEBUG -spawn -noecho /bin/bash - -if { $PASSWORD == "ssh" } { - set PASSWORD "" -} - -# -# send command -# -send "scp -v $FILE $USERNAME$SERVER:$FILE\n" -expect { - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - -re "100%" { send_user "DONE\n" ; sleep 2; exit 0 } - -re "authenticity" { send "yes\n" - expect { - -re "word: " { send "$PASSWORD\n" } - -re "passphrase" { send "$PASSWORD\n" } - } - } - -re "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } - -re "Connection refused" { send_user "FAILED: Connection refused\n" ; exit 1 } - -re "Connection timed out" { send_user "FAILED: Connection timed out\n" ; exit 1 } - -re "lost connection" { send_user "FAILED: Connection refused\n" ; exit 1 } - -re "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - -re "word: " { send "$PASSWORD\n" } - -re "passphrase" { send "$PASSWORD\n" } - -re "WARNING:" { send "rm -f /root/.ssh/known_hosts" ; exit 1 } - -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } -} -expect { - "Exit status 0" { exit 0 } - "Exit status 1" { exit 1 } - -re "100%" { send_user "DONE\n" ; sleep 2 ; exit 0 } - -re "scp:" { send_user "FAILED\n" ; exit 1 } - -re "Permission denied, please try again" { send_user "FAILED: Invalid password\n" ; exit 1 } - -re "No such file or directory" { send_user "FAILED: Invalid file\n" ; exit 1 } - -re "Connection refused" { send_user "FAILED: Connection refused\n" ; exit 1 } - -re "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } -} -exit 0 - From 2dd99eabf7ace7cee3bf1e1452d58034ce3ce948 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 12 Jun 2017 16:29:49 -0500 Subject: [PATCH 094/185] MCOL-472 - fix the force shutdown command --- dbcon/mysql/mysql-Columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/mysql/mysql-Columnstore b/dbcon/mysql/mysql-Columnstore index 92bb76e8e..a0c8bca23 100755 --- a/dbcon/mysql/mysql-Columnstore +++ b/dbcon/mysql/mysql-Columnstore @@ -310,7 +310,7 @@ fi kill_by_pid() { # let's see if we can kill the 2 mysql procs by hand # get the our mysql from ps - eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql//sbin/mysqld" | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') + eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql//bin/mysqld" | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') if [ -n "$pid" ]; then ppid=$(ps -o ppid= -p $pid) From 84741a7eb29fdd6976b1b9f96a57a677ccc2a3f0 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 13 Jun 2017 09:51:46 -0500 Subject: [PATCH 095/185] MCOL-472 - additional tweak to full shutdown both mysql processes --- dbcon/mysql/mysql-Columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/mysql/mysql-Columnstore b/dbcon/mysql/mysql-Columnstore index a0c8bca23..de090329f 100755 --- a/dbcon/mysql/mysql-Columnstore +++ b/dbcon/mysql/mysql-Columnstore @@ -310,7 +310,7 @@ fi kill_by_pid() { # let's see if we can kill the 2 mysql procs by hand # get the our mysql from ps - eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql//bin/mysqld" | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') + eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql//bin/mysqld " | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') if [ -n "$pid" ]; then ppid=$(ps -o ppid= -p $pid) From d9bc366c935b98f77f2a6aa007ec67e725cc2d18 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 13 Jun 2017 10:08:22 -0500 Subject: [PATCH 096/185] fix non-root logrotate issue - permission problem --- oam/install_scripts/columnstoreSyslog7 | 2 ++ oam/install_scripts/post-install | 30 ++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/oam/install_scripts/columnstoreSyslog7 b/oam/install_scripts/columnstoreSyslog7 index 0ed37f975..25e807eea 100644 --- a/oam/install_scripts/columnstoreSyslog7 +++ b/oam/install_scripts/columnstoreSyslog7 @@ -1,4 +1,6 @@ # MariaDB Columnstore Database Platform Logging +$FileGroup groupname +$FileOwner username local1.crit -/var/log/mariadb/columnstore/crit.log local1.err -/var/log/mariadb/columnstore/err.log local1.warning -/var/log/mariadb/columnstore/warning.log diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index e90494d75..c9a3d707f 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -126,7 +126,7 @@ test -d /var/log/mariadb || $SUDO mkdir /var/log/mariadb >/dev/null 2>&1 test -d /var/log/mariadb/columnstore || $SUDO mkdir /var/log/mariadb/columnstore >/dev/null 2>&1 if [ $user != "root" ]; then - $SUDO chmod -R 777 /var/log/mariadb >/dev/null 2>&1 + $SUDO chmod -R 755 /var/log/mariadb >/dev/null 2>&1 $SUDO chown -R $user:$user /var/log/mariadb >/dev/null 2>&1 fi @@ -166,10 +166,6 @@ chmod 755 /var/log/mariadb/columnstore/corefiles > /dev/null 2>&1 mkdir /mnt/tmp > /dev/null 2>&1 mkdir /var/log/mariadb/columnstore/data/archive > /dev/null 2>&1 -# install Columnstore Log Rotate File -$SUDO cp $installdir/bin/columnstoreLogRotate /etc/logrotate.d/columnstore > /dev/null 2>&1 -$SUDO chmod 644 /etc/logrotate.d/columnstore - # remove mysql archive log test -d $installdir/mysql/db || mkdir -p $installdir/mysql/db rm -rf $installdir/mysql/db/columnstore_log_archive > /dev/null 2>&1 @@ -209,25 +205,37 @@ if [ $user = "root" ]; then fi fi fi + +#setup MariaDB Columnstore system logging +sed -i -e s/groupname/$user/g $installdir/bin/columnstoreSyslog7 +sed -i -e s/username/$user/g $installdir/bin/columnstoreSyslog7 + #setup MariaDB Columnstore system logging if [ $user = "root" ]; then $installdir/bin/syslogSetup.sh install > /tmp/syslog_install.log 2>&1 rm -f /etc/default/columnstore else + sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def + sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstoreLogRotate + + $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore + + sed -i -e s@prefix=/home/quest@prefix=$prefix@g $installdir/bin/* + + $SUDO rm -f /tmp/* > /dev/null 2>&1 $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml $SUDO chmod -R 777 /dev/shm $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore - $SUDO chmod 666 /etc/fstab - - sed -i -e s@/usr/local/mariadb/columnstore@$installdir@g $installdir/bin/columnstore.def - $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore - - sed -i -e s@prefix=/usr/local@prefix=$prefix@g $installdir/bin/* + $SUDO chmod 644 /etc/fstab fi +# install Columnstore Log Rotate File +$SUDO cp $installdir/bin/columnstoreLogRotate /etc/logrotate.d/columnstore > /dev/null 2>&1 +$SUDO chmod 644 /etc/logrotate.d/columnstore + #check if MariaDB Columnstore system logging was setup cat /tmp/syslog_install.log | grep 'No System Logging' >/dev/null 2>&1 if [ $? -eq 0 ]; then From fef65814cb02287ea834fe9717f6903861feb4c3 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 16 Jun 2017 09:11:06 -0500 Subject: [PATCH 097/185] MCOL-733 - changed to not watch for command line prompts --- oam/install_scripts/remote_command.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/oam/install_scripts/remote_command.sh b/oam/install_scripts/remote_command.sh index 4525a4ed3..9d0f7c2ed 100755 --- a/oam/install_scripts/remote_command.sh +++ b/oam/install_scripts/remote_command.sh @@ -16,11 +16,9 @@ set PASSWORD [lindex $argv 1] set COMMAND [lindex $argv 2] set DEBUG [lindex $argv 3] -if {[info exists env(USER)]} { - set USERNAME $env(USER) -} else { - set USERNAME "root" -} +exec whoami >/tmp/whoami.tmp +set USERNAME [exec cat /tmp/whoami.tmp] +exec rm -f /tmp/whoami.tmp set UNM [lindex $argv 4] if { $UNM != "" && $UNM != "-" } { From 3b1864621fa6cb6a04245ee62d0c2464433868c1 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 26 Jun 2017 10:13:43 -0500 Subject: [PATCH 098/185] MCOL-787 - add code to create system catlog on startup --- procmgr/processmanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index a25943f67..ae76401ca 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -6854,6 +6854,9 @@ void startSystemThread(oam::DeviceNetworkList Devicenetworklist) processManager.setSystemState(rtn); } + //run command to build system table if they don't already exist + processManager.buildSystemTables("pm1"); + // exit thread log.writeLog(__LINE__, "startSystemThread Exit", LOG_TYPE_DEBUG); startsystemthreadStatus = status; From 3bb347679a64fc18eaa7470df354c76d3bc4a33f Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 5 Jul 2017 06:44:20 -0500 Subject: [PATCH 099/185] MCOL-715 - fixed um storage type setup --- oam/cloud/MCSInstanceCmds.sh | 11 +++++--- oam/cloud/MCSVolumeCmds.sh | 36 ++++++++++++++----------- oam/install_scripts/module_installer.sh | 1 + oam/install_scripts/post-install | 4 +-- oamapps/postConfigure/postConfigure.cpp | 8 +++--- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/oam/cloud/MCSInstanceCmds.sh b/oam/cloud/MCSInstanceCmds.sh index fbd0b6f31..32e674f90 100755 --- a/oam/cloud/MCSInstanceCmds.sh +++ b/oam/cloud/MCSInstanceCmds.sh @@ -4,7 +4,12 @@ # # 1. Amazon EC2 -prefix=/usr/local +if [ -z "$COLUMNSTORE_INSTALL_DIR" ]; then + COLUMNSTORE_INSTALL_DIR=/usr/local/mariadb/columnstore +fi + +export COLUMNSTORE_INSTALL_DIR=$COLUMNSTORE_INSTALL_DIR + #check command if [ "$1" = "" ]; then @@ -87,9 +92,9 @@ if [ "$1" = "deassignElasticIP" ]; then fi -$prefix/mariadb/columnstore/bin/MCSgetCredentials.sh >/dev/null 2>&1 +$COLUMNSTORE_INSTALL_DIR/bin/MCSgetCredentials.sh >/dev/null 2>&1 -test -f $prefix//mariadb/columnstore/post/functions && . $prefix//mariadb/columnstore/post/functions +test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions #default instance to null instance="" diff --git a/oam/cloud/MCSVolumeCmds.sh b/oam/cloud/MCSVolumeCmds.sh index cb87ae039..ff9b1681a 100755 --- a/oam/cloud/MCSVolumeCmds.sh +++ b/oam/cloud/MCSVolumeCmds.sh @@ -4,7 +4,11 @@ # # 1. Amazon EC2 -prefix=/usr/local +if [ -z "$COLUMNSTORE_INSTALL_DIR" ]; then + COLUMNSTORE_INSTALL_DIR=/usr/local/mariadb/columnstore +fi + +export COLUMNSTORE_INSTALL_DIR=$COLUMNSTORE_INSTALL_DIR #check command if [ "$1" = "" ]; then @@ -93,14 +97,14 @@ if [ "$1" = "createTag" ]; then fi -test -f $prefix/mariadb/columnstore/post/functions && . $prefix/mariadb/columnstore/post/functions +test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions AWSCLI="aws ec2 " -$prefix/mariadb/columnstore/bin/MCSgetCredentials.sh >/dev/null 2>&1 +$COLUMNSTORE_INSTALL_DIR/MCSgetCredentials.sh >/dev/null 2>&1 #get Region -Region=`$prefix/mariadb/columnstore/bin/MCSInstanceCmds.sh getRegion` +Region=`$COLUMNSTORE_INSTALL_DIR/bin/MCSInstanceCmds.sh getRegion` checkInfostatus() { #check if attached @@ -153,21 +157,21 @@ checkInfostatus() { createvolume() { # get zone - zone=`$prefix/mariadb/columnstore/bin/MCSInstanceCmds.sh getZone` + zone=`$COLUMNSTORE_INSTALL_DIR/bin/MCSInstanceCmds.sh getZone` if [ $moduleType == "um" ]; then # get type - volumeType=`$prefix/mariadb/columnstore/bin/getConfig Installation UMVolumeType` + volumeType=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMVolumeType` if [ $volumeType == "io1" ]; then # get IOPS - volumeIOPS=`$prefix/mariadb/columnstore/bin/getConfig Installation UMVolumeIOPS` + volumeIOPS=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMVolumeIOPS` fi else # pm # get type - volumeType=`$prefix/mariadb/columnstore/bin/getConfig Installation PMVolumeType` + volumeType=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation PMVolumeType` if [ $volumeType == "io1" ]; then # get IOPS - volumeIOPS=`$prefix/mariadb/columnstore/bin/getConfig Installation PMVolumeIOPS` + volumeIOPS=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation PMVolumeIOPS` fi fi @@ -211,7 +215,7 @@ detachvolume() { sleep 1 done test -f /usr/local/mariadb/columnstore/post/functions && . /usr/local/mariadb/columnstore/post/functions - $prefix/mariadb/columnstore/bin/cplogger -w 100 "detachvolume failed: $STATUS" + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "detachvolume failed: $STATUS" echo "failed" exit 1 fi @@ -221,8 +225,8 @@ detachvolume() { exit 0 fi - test -f /usr/local/mariadb/columnstore/post/functions && . /usr/local/mariadb/columnstore/post/functions - $prefix/mariadb/columnstore/bin/cplogger -w 100 "detachvolume failed status: $STATUS" + test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "detachvolume failed status: $STATUS" echo $STATUS exit 1 } @@ -245,8 +249,8 @@ attachvolume() { ((retries++)) sleep 1 done - test -f /usr/local/mariadb/columnstore/post/functions && . /usr/local/mariadb/columnstore/post/functions - $prefix/mariadb/columnstore/bin/cplogger -w 100 "attachvolume failed: $STATUS" + test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "attachvolume failed: $STATUS" echo "failed" exit 1 fi @@ -256,8 +260,8 @@ attachvolume() { exit 0 fi - test -f /usr/local/mariadb/columnstore/post/functions && . /usr/local/mariadb/columnstore/post/functions - $prefix/mariadb/columnstore/bin/cplogger -w 100 "attachvolume failed: $STATUS" + test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "attachvolume failed: $STATUS" echo $STATUS exit 1 } diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index fcc80ab8c..5822c4082 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -69,6 +69,7 @@ if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then cat $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab >> /etc/fstab else sudo touch /etc/fstab + sudo chmod 666 /etc/fstab sudo rm -f /etc/fstab.columnstoreSave sudo cp /etc/fstab /etc/fstab.columnstoreSave sudo cat $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab >> /etc/fstab diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index c9a3d707f..bb8edf5c8 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -229,12 +229,12 @@ else $SUDO mkdir /var/lock/subsys > /dev/null 2>&1 $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore - $SUDO chmod 644 /etc/fstab + $SUDO chmod 666 /etc/fstab fi # install Columnstore Log Rotate File $SUDO cp $installdir/bin/columnstoreLogRotate /etc/logrotate.d/columnstore > /dev/null 2>&1 -$SUDO chmod 644 /etc/logrotate.d/columnstore +$SUDO chmod 666 /etc/logrotate.d/columnstore #check if MariaDB Columnstore system logging was setup cat /tmp/syslog_install.log | grep 'No System Logging' >/dev/null 2>&1 diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index f96f210e0..66bffa5e6 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -4213,7 +4213,7 @@ bool storageSetup(bool amazonInstall) catch(...) {} - if ( UMVolumeType.empty() || UMVolumeType == "") + if ( UMVolumeType.empty() || UMVolumeType == "" || UMVolumeType == oam::UnassignedName) UMVolumeType = "gp2"; while(true) @@ -4311,7 +4311,7 @@ bool storageSetup(bool amazonInstall) catch(...) {} - if ( UMVolumeIOPS.empty() || UMVolumeIOPS == "") + if ( UMVolumeIOPS.empty() || UMVolumeIOPS == "" || UMVolumeIOPS == oam::UnassignedName) UMVolumeIOPS = maxIOPS; while(true) @@ -4556,7 +4556,7 @@ bool storageSetup(bool amazonInstall) catch(...) {} - if ( PMVolumeType.empty() || PMVolumeType == "") + if ( PMVolumeType.empty() || PMVolumeType == "" || PMVolumeType == oam::UnassignedName) PMVolumeType = "gp2"; while(true) @@ -4739,7 +4739,7 @@ bool storageSetup(bool amazonInstall) DataFileEnvFile = "setenv-hdfs-20"; } - if (DataFileEnvFile.empty() || DataFileEnvFile == "") + if (DataFileEnvFile.empty() || DataFileEnvFile == "" || DataFileEnvFile == oam::UnassignedName) DataFileEnvFile = "setenv-hdfs-20"; cout << endl; From e3ba11cdbff184d4181df592efff5c7e05d99cb2 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 6 Jul 2017 03:25:24 -0500 Subject: [PATCH 100/185] MCOL-626 --- oamapps/mcsadmin/mcsadmin.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index b8dbde771..bc44b5598 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -65,6 +65,7 @@ string parentOAMModule; string localModule; bool rootUser = true; string HOME = "/root"; +string SingleServerInstall; bool repeatStop; @@ -259,7 +260,12 @@ int main(int argc, char *argv[]) exit(-1); } - //check if root-user + try { + oam.getSystemConfig("SingleServerInstall", SingleServerInstall); + } + catch(...) {} + + //check if root-user int user; user = getuid(); if (user != 0) @@ -5038,6 +5044,12 @@ int processCommand(string* arguments) case 48: // addModule - parameters: Module type/Module Name, Number of Modules, Server Hostnames, // Server root password optional { + if ( SingleServerInstall == "y" ) { + // exit out since not on single-server install + cout << endl << "**** addModule Failed : not supported on a Single-Server type installs " << endl; + break; + } + parentOAMModule = getParentOAMModule(); if ( localModule != parentOAMModule ) { // exit out since not on Parent OAM Module @@ -5600,6 +5612,12 @@ int processCommand(string* arguments) case 49: // removeModule - parameters: Module name/type, number-of-modules { + if ( SingleServerInstall == "y" ) { + // exit out since not on single-server install + cout << endl << "**** removeModule Failed : not supported on a Single-Server type installs " << endl; + break; + } + if (arguments[1] == "") { // need atleast 1 arguments @@ -6665,6 +6683,11 @@ int processCommand(string* arguments) case 65: // alterSystem-disableModule { + if ( SingleServerInstall == "y" ) { + // exit out since not on single-server install + cout << endl << "**** alterSystem-disableModule Failed : not supported on a Single-Server type installs " << endl; + break; + } parentOAMModule = getParentOAMModule(); if ( localModule != parentOAMModule ) { //exit out since not on Parent OAM Module @@ -6815,6 +6838,11 @@ int processCommand(string* arguments) case 66: // alterSystem-enableModule { + if ( SingleServerInstall == "y" ) { + // exit out since not on single-server install + cout << endl << "**** alterSystem-enableModule Failed : not supported on a Single-Server type installs " << endl; + break; + } parentOAMModule = getParentOAMModule(); if ( localModule != parentOAMModule ) { //exit out since not on Parent OAM Module From 14771bd9418a4c6c133ad0909649233fe7138cf1 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 11 Jul 2017 13:55:22 +0100 Subject: [PATCH 101/185] MCOL-674 Fix subquery in UPDATE When some subquery changes were made over a year ago the flag to state that an UPDATE subquery was not constant data was accidentally commented out. This brings it back in again. --- dbcon/mysql/ha_calpont_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index de6cae449..8f20abd64 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1038,8 +1038,8 @@ uint32_t doUpdateDelete(THD *thd) } else if ( value->type() == Item::SUBSELECT_ITEM ) { -// isFromCol = true; -// columnAssignmentPtr->fFromCol = true; + isFromCol = true; + columnAssignmentPtr->fFromCol = true; // Item_field* setIt = reinterpret_cast (value); // string sectableName = string(setIt->table_name); // string secschemaName = string(setIt->db_name); From f3f830a9caa1c0fad62b0ee77750ca702c150e3f Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 11 Jul 2017 15:14:24 +0100 Subject: [PATCH 102/185] Support ORDER BY NULL --- dbcon/mysql/ha_calpont_execplan.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 2a8c590e0..c9c56a342 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -6501,6 +6501,10 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i oss << ordercol->counter; ord_cols += oss.str(); } + else if (ord_item->type() == Item::NULL_ITEM) + { + // MCOL-793 Do nothing for an ORDER BY NULL + } else if (ord_item->type() == Item::SUM_FUNC_ITEM) { Item_sum* ifp = (Item_sum*)(*(ordercol->item)); From d4908037848fc27dd4c64293a8312f3912959a8e Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 11 Jul 2017 13:54:57 -0500 Subject: [PATCH 103/185] MCOL-811 - change to only call syslogSetup once and have it only restart the service once --- oam/install_scripts/syslogSetup.sh | 53 +++++++++++++++---------- oamapps/postConfigure/installer.cpp | 4 -- oamapps/postConfigure/postConfigure.cpp | 7 ---- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/oam/install_scripts/syslogSetup.sh b/oam/install_scripts/syslogSetup.sh index 87c1b0cf5..684b90fb6 100755 --- a/oam/install_scripts/syslogSetup.sh +++ b/oam/install_scripts/syslogSetup.sh @@ -12,10 +12,10 @@ installdir=$prefix/mariadb/columnstore syslog_conf=nofile rsyslog7=0 -user=root +user=`whoami 2>/dev/null` + SUDO=" " -if [ "$USER" != "root" ]; then - user=$USER +if [ "$user" != "root" ]; then SUDO="sudo " fi @@ -155,6 +155,11 @@ install() { checkSyslog if [ ! -z "$syslog_conf" ] ; then $installdir/bin/setConfig -d Installation SystemLogConfigFile ${syslog_conf} >/dev/null 2>&1 + if [ "$syslog_conf" != /etc/rsyslog.d/columnstore.conf ]; then + $SUDO rm -f ${syslog_conf}.columnstoreSave + $SUDO cp ${syslog_conf} ${syslog_conf}.columnstoreSave >/dev/null 2>&1 + $SUDO sed -i '/# MariaDB/,$d' ${syslog_conf}.columnstoreSave > /dev/null 2>&1 + fi egrep -qs 'MariaDB Columnstore Database Platform Logging' ${syslog_conf} if [ $? -ne 0 ]; then @@ -170,14 +175,7 @@ if [ ! -z "$syslog_conf" ] ; then fi fi - $SUDO /etc/init.d/rsyslog restart > /dev/null 2>&1 - $SUDO /etc/init.d/syslog restart > /dev/null 2>&1 - $SUDO /etc/init.d/syslog-ng restart > /dev/null 2>&1 - - $SUDO systemctl restart rsyslog.service > /dev/null 2>&1 - $SUDO systemctl restart syslog.service > /dev/null 2>&1 - $SUDO systemctl restart syslog-ng.service > /dev/null 2>&1 - + restartSyslog fi } @@ -206,16 +204,7 @@ if [ ! -z "$syslog_conf" ] ; then $SUDO rm -f "$syslog_conf" fi - $SUDO /etc/init.d/rsyslog restart > /dev/null 2>&1 - $SUDO /etc/init.d/syslog restart > /dev/null 2>&1 - $SUDO /etc/init.d/syslog-ng restart > /dev/null 2>&1 - - $SUDO systemctl restart rsyslog.service > /dev/null 2>&1 - $SUDO systemctl restart syslog.service > /dev/null 2>&1 - $SUDO systemctl restart syslog-ng.service > /dev/null 2>&1 - - - $installdir/bin/setConfig -d Installation SystemLogConfigFile "unassigned" + restartSyslog fi @@ -248,6 +237,28 @@ else fi } +restartSyslog() { + + if [ "$daemon" = "syslog-ng" ]; then + if [ -f /etc/init.d/syslog-ng ]; then + $SUDO /etc/init.d/syslog-ng restart > /dev/null 2>&1 + else + $SUDO systemctl restart syslog-ng.service > /dev/null 2>&1 + fi + elif [ "$daemon" = "rsyslog" ]; then + if [ -f /etc/init.d/rsyslog ]; then + $SUDO /etc/init.d/rsyslog restart > /dev/null 2>&1 + else + $SUDO systemctl restart rsyslog.service > /dev/null 2>&1 + fi + elif [ "$daemon" = "syslog" ]; then + if [ -f /etc/init.d/syslog ]; then + $SUDO /etc/init.d/syslog restart > /dev/null 2>&1 + else + $SUDO systemctl restart syslog.service > /dev/null 2>&1 + fi + fi +} case "$1" in install) diff --git a/oamapps/postConfigure/installer.cpp b/oamapps/postConfigure/installer.cpp index 8ea9af62f..824f82137 100644 --- a/oamapps/postConfigure/installer.cpp +++ b/oamapps/postConfigure/installer.cpp @@ -369,10 +369,6 @@ int main(int argc, char *argv[]) exit(1); } - //store syslog config file in Calpont Config file - cmd = installDir + "/bin/syslogSetup.sh install > /dev/null 2>&1"; - system(cmd.c_str()); - //get PPackage Type try{ packageType = sysConfig->getConfig(InstallSection, "EEPackageType"); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 66bffa5e6..1bfe5dc8e 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -3158,13 +3158,6 @@ int main(int argc, char *argv[]) //check if local MariaDB ColumnStore system logging is working cout << endl << "===== Checking MariaDB ColumnStore System Logging Functionality =====" << endl << endl; - if ( rootUser) - cmd = installDir + "/bin/syslogSetup.sh install > /dev/null 2>&1"; - else - cmd = "sudo " + installDir + "/bin/syslogSetup.sh --installdir=" + installDir + " install > /dev/null 2>&1"; - - system(cmd.c_str()); - if ( rootUser) cmd = installDir + "/bin/syslogSetup.sh status > /dev/null 2>&1"; else From 3501c1a17a920ee765c6255c5a5fd8c64fed7c8e Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 12 Jul 2017 09:52:28 -0500 Subject: [PATCH 104/185] MCOL-811 - removed the preuninstall and added check for binary on the post-install --- oamapps/postConfigure/postConfigure.cpp | 89 +++++++++++-------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 1bfe5dc8e..590bbafd9 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -411,21 +411,41 @@ int main(int argc, char *argv[]) exit (1); } - //if InitialInstallFlag is set, then an install has been done - // run pre-uninstall to clean from previous install and continue - try { - string InitialInstallFlag = sysConfig->getConfig(InstallSection, "InitialInstallFlag"); - if ( InitialInstallFlag == "y" ) { - cmd = installDir + "/bin/pre-uninstall --quiet > /dev/null 2>&1"; - system(cmd.c_str()); - } - } - catch(...) - {} + //determine package type + string EEPackageType; - //run post install for coverage of possible binary package install - cmd = installDir + "/bin/post-install --installdir=" + installDir + " > /dev/null 2>&1"; - system(cmd.c_str()); + if (!rootUser) + EEPackageType = "binary"; + else + { + int rtnCode = system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) + EEPackageType = "rpm"; + else { + rtnCode = system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); + if (WEXITSTATUS(rtnCode) == 0) + EEPackageType = "deb"; + else + EEPackageType = "binary"; + } + } + + try { + sysConfig->setConfig(InstallSection, "EEPackageType", EEPackageType); + } + catch(...) + { + cout << "ERROR: Problem setting EEPackageType from the MariaDB ColumnStore System Configuration file" << endl; + exit(1); + } + + //if binary install, then run post-install just in case the user didnt run it + if ( EEPackageType == "binary" ) + { + //run post install + cmd = installDir + "/bin/post-install --installdir=" + installDir + " > /dev/null 2>&1"; + system(cmd.c_str()); + } //check Config saved files if ( !checkSaveConfigFile()) @@ -434,7 +454,12 @@ int main(int argc, char *argv[]) exit(1); } - //check for local ip address as pm1 + if ( !writeConfig(sysConfig) ) { + cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; + exit(1); + } + + //check for local ip address as pm1 ModuleConfig moduleconfig; try @@ -2676,40 +2701,6 @@ int main(int argc, char *argv[]) /* create a thread_data_t argument array */ thread_data_t thr_data[childmodulelist.size()]; - // determine package type - string EEPackageType; - - if (!rootUser) - EEPackageType = "binary"; - else - { - int rtnCode = system("rpm -qi mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (WEXITSTATUS(rtnCode) == 0) - EEPackageType = "rpm"; - else { - rtnCode = system("dpkg -s mariadb-columnstore-platform > /tmp/columnstore.txt 2>&1"); - if (WEXITSTATUS(rtnCode) == 0) - EEPackageType = "deb"; - else - EEPackageType = "binary"; - } - } - - try { - sysConfig->setConfig(InstallSection, "EEPackageType", EEPackageType); - } - catch(...) - { - cout << "ERROR: Problem setting EEPackageType from the MariaDB ColumnStore System Configuration file" << endl; - exit(1); - } - - if ( !writeConfig(sysConfig) ) { - cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; - exit(1); - } - - string install = "y"; if ( IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM || From d5e873e1981d50fec690df62ba545aa2dd0c7ed6 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 17 Jul 2017 15:43:18 -0500 Subject: [PATCH 105/185] MCOL-814 --- dbcon/joblist/distributedenginecomm.cpp | 42 +- procmgr/processmanager.cpp | 889 +++++++++++++----------- 2 files changed, 519 insertions(+), 412 deletions(-) diff --git a/dbcon/joblist/distributedenginecomm.cpp b/dbcon/joblist/distributedenginecomm.cpp index a059623fc..4407c4d6d 100644 --- a/dbcon/joblist/distributedenginecomm.cpp +++ b/dbcon/joblist/distributedenginecomm.cpp @@ -171,7 +171,7 @@ namespace joblist DistributedEngineComm* DistributedEngineComm::fInstance = 0; /*static*/ - DistributedEngineComm* DistributedEngineComm::instance(ResourceManager& rm, bool isExeMgr) + DistributedEngineComm* DistributedEngineComm::instance(ResourceManager* rm, bool isExeMgr) { if (fInstance == 0) fInstance = new DistributedEngineComm(rm, isExeMgr); @@ -186,9 +186,9 @@ namespace joblist fInstance = 0; } - DistributedEngineComm::DistributedEngineComm(ResourceManager& rm, bool isExeMgr) : + DistributedEngineComm::DistributedEngineComm(ResourceManager* rm, bool isExeMgr) : fRm(rm), - fLBIDShift(fRm.getPsLBID_Shift()), + fLBIDShift(fRm->getPsLBID_Shift()), pmCount(0), fIsExeMgr(isExeMgr) { @@ -219,10 +219,10 @@ void DistributedEngineComm::Setup() newClients.clear(); newLocks.clear(); - throttleThreshold = fRm.getDECThrottleThreshold(); - uint32_t newPmCount = fRm.getPsCount(); - int cpp = (fIsExeMgr ? fRm.getPsConnectionsPerPrimProc() : 1); - tbpsThreadCount = fRm.getJlNumScanReceiveThreads(); + throttleThreshold = fRm->getDECThrottleThreshold(); + uint32_t newPmCount = fRm->getPsCount(); + int cpp = (fIsExeMgr ? fRm->getPsConnectionsPerPrimProc() : 1); + tbpsThreadCount = fRm->getJlNumScanReceiveThreads(); unsigned numConnections = newPmCount * cpp; oam::Oam oam; ModuleTypeConfig moduletypeconfig; @@ -246,7 +246,7 @@ void DistributedEngineComm::Setup() string fServer (oss.str()); boost::shared_ptr - cl(new MessageQueueClient(fServer, fRm.getConfig())); + cl(new MessageQueueClient(fServer, fRm->getConfig())); boost::shared_ptr nl(new boost::mutex()); try { if (cl->connect()) { @@ -297,7 +297,7 @@ void DistributedEngineComm::Setup() int DistributedEngineComm::Close() { - //cout << "DistributedEngineComm::Close() called" << endl; + cout << "DistributedEngineComm::Close() called" << endl; makeBusy(false); // for each MessageQueueClient in pmConnections delete the MessageQueueClient; @@ -337,9 +337,9 @@ Error: // @bug 488 - error condition! push 0 length bs to messagequeuemap and // eventually let jobstep error out. mutex::scoped_lock lk(fMlock); - //cout << "WARNING: DEC READ 0 LENGTH BS FROM " << client->otherEnd()<< endl; + cout << "WARNING: DEC READ 0 LENGTH BS FROM " << client->otherEnd()<< endl; - MessageQueueMap::iterator map_tok; +/* MessageQueueMap::iterator map_tok; sbs.reset(new ByteStream(0)); for (map_tok = fSessionMessages.begin(); map_tok != fSessionMessages.end(); ++map_tok) @@ -356,21 +356,21 @@ Error: { mutex::scoped_lock onErrLock(fOnErrMutex); string moduleName = client->moduleName(); - //cout << "moduleName=" << moduleName << endl; + cout << "moduleName=" << moduleName << endl; for ( uint32_t i = 0; i < fPmConnections.size(); i++) { if (moduleName != fPmConnections[i]->moduleName()) tempConns.push_back(fPmConnections[i]); //else - //cout << "DEC remove PM" << fPmConnections[i]->otherEnd() << " moduleName=" << fPmConnections[i]->moduleName() << endl; + cout << "DEC remove PM" << fPmConnections[i]->otherEnd() << " moduleName=" << fPmConnections[i]->moduleName() << endl; } if (tempConns.size() == fPmConnections.size()) return; fPmConnections.swap(tempConns); pmCount = (pmCount == 0 ? 0 : pmCount - 1); - //cout << "PMCOUNT=" << pmCount << endl; - + cout << "PMCOUNT=" << pmCount << endl; +*/ // send alarm & log it ALARMManager alarmMgr; string alarmItem = client->addr2String(); @@ -380,7 +380,7 @@ Error: ostringstream os; os << "DEC: lost connection to " << client->addr2String(); writeToLog(__FILE__, __LINE__, os.str(), LOG_TYPE_CRITICAL); - } +// } return; } @@ -861,9 +861,9 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin { // @bug 488. error out under such condition instead of re-trying other connection, // by pushing 0 size bytestream to messagequeue and throw excpetion - SBS sbs; +/* SBS sbs; lk.lock(); - //cout << "WARNING: DEC WRITE BROKEN PIPE. PMS index = " << index << endl; + cout << "WARNING: DEC WRITE BROKEN PIPE. PMS index = " << index << endl; MessageQueueMap::iterator map_tok; sbs.reset(new ByteStream(0)); @@ -879,10 +879,10 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin // reconfig the connection array ClientList tempConns; { - //cout << "WARNING: DEC WRITE BROKEN PIPE " << fPmConnections[index]->otherEnd()<< endl; + cout << "WARNING: DEC WRITE BROKEN PIPE " << fPmConnections[index]->otherEnd()<< endl; mutex::scoped_lock onErrLock(fOnErrMutex); string moduleName = fPmConnections[index]->moduleName(); - //cout << "module name = " << moduleName << endl; + cout << "module name = " << moduleName << endl; if (index >= fPmConnections.size()) return 0; for (uint32_t i = 0; i < fPmConnections.size(); i++) @@ -894,7 +894,7 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin fPmConnections.swap(tempConns); pmCount = (pmCount == 0 ? 0 : pmCount - 1); } - +*/ // send alarm ALARMManager alarmMgr; string alarmItem("UNKNOWN"); diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index ae76401ca..e5c783c40 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -618,11 +618,11 @@ void processMSG(messageqcpp::IOSocket* cfIos) oam.dbrmctl("resume"); log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); - processManager.restartProcessType("ExeMgr"); +// processManager.restartProcessType("ExeMgr"); //setup MySQL Replication for started modules - log.writeLog(__LINE__, "Setup MySQL Replication for module being started", LOG_TYPE_DEBUG); - processManager.setMySQLReplication(startdevicenetworklist); +// log.writeLog(__LINE__, "Setup MySQL Replication for module being started", LOG_TYPE_DEBUG); +// processManager.setMySQLReplication(startdevicenetworklist); } } else @@ -2791,7 +2791,17 @@ void processMSG(messageqcpp::IOSocket* cfIos) log.writeLog(__LINE__, "MSG RECEIVED: Process Restarted on " + moduleName + "/" + processName); - //request reinit after Process is active + //set query system states not ready + BRM::DBRM dbrm; + dbrm.setSystemQueryReady(false); + + processManager.setQuerySystemState(false); + + processManager.setSystemState(oam::BUSY_INIT); + + processManager.reinitProcessType("cpimport"); + + //request reinit after Process is active for ( int i = 0; i < 600 ; i++ ) { try { ProcessStatus procstat; @@ -2805,7 +2815,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) processManager.distributeConfigFile("system"); processManager.reinitProcessType("WriteEngineServer"); - processManager.restartProcessType("ExeMgr"); + processManager.reinitProcessType("ExeMgr"); processManager.reinitProcessType("DDLProc"); processManager.reinitProcessType("DMLProc"); } @@ -2851,7 +2861,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) } // Wait for DMLProc to be ACTIVE - BRM::DBRM dbrm; + //BRM::DBRM dbrm; state = AUTO_OFFLINE; while (state == oam::MAN_OFFLINE || state == oam::AUTO_OFFLINE @@ -2865,7 +2875,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) break; sleep(1); } - dbrm.setSystemQueryReady(true); + //dbrm.setSystemQueryReady(true); } // if a DDLProc was restarted, reinit DMLProc @@ -2916,6 +2926,13 @@ void processMSG(messageqcpp::IOSocket* cfIos) break; } } + + //enable query stats + dbrm.setSystemQueryReady(true); + + processManager.setQuerySystemState(true); + + processManager.setSystemState(oam::ACTIVE); } break; @@ -3797,10 +3814,8 @@ void ProcessManager::setSystemState(uint16_t state) else if ( state == oam::AUTO_OFFLINE ) aManager.sendAlarmReport(system.c_str(), SYSTEM_DOWN_AUTO, SET); - //this alarm doesnt get clear by reporter, so clear on stopage aManager.sendAlarmReport(system.c_str(), CONN_FAILURE, CLEAR); } - pthread_mutex_unlock(&STATUS_LOCK); } @@ -4420,6 +4435,18 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str pthread_mutex_lock(&THREAD_LOCK); + //get Distributed Install + string DistributedInstall = "y"; + + try + { + oam.getSystemConfig("DistributedInstall", DistributedInstall); + } + catch (...) + { + log.writeLog(__LINE__, "addModule - ERROR: get DistributedInstall", LOG_TYPE_ERROR); + } + int AddModuleCount = devicenetworklist.size(); DeviceNetworkList::iterator listPT = devicenetworklist.begin(); string moduleType = (*listPT).DeviceName.substr(0,MAX_MODULE_TYPE_SIZE); @@ -4510,8 +4537,6 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str return API_FAILURE; } - - //check if pkgs are located in /root directory string homedir = "/root"; if (!rootUser) { char* p= getenv("HOME"); @@ -4519,6 +4544,13 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str homedir = p; } + //clear out the known_host file, sometimes causes a failure on amazon during addModule + if ( amazon ) + { + string cmd = "sudo unlink " + homedir + ".ssh/know_hosts > /dev/null 2>&1"; + system(cmd.c_str()); + } + if ( packageType == "rpm") calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.rpm.tar.gz"; else @@ -4527,55 +4559,59 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str else calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.bin.tar.gz"; - string cmd = "ls " + calpontPackage + " > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - log.writeLog(__LINE__, "addModule - ERROR: Package not found: " + calpontPackage, LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FILE_OPEN_ERROR; - } - log.writeLog(__LINE__, "addModule - Calpont Package found:" + calpontPackage, LOG_TYPE_DEBUG); - - // - // Verify Host IP and Password - // - - if ( password == "ssh" && amazon ) - { // check if there is a root password stored - string rpw = oam::UnassignedName; - try - { - oam.getSystemConfig("rpw", rpw); - } - catch(...) - { - rpw = "mariadb1"; - } - - if (rpw != oam::UnassignedName) - password = rpw; - } - - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) + if ( DistributedInstall == "y" ) { - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string newHostName = (*pt1).HostName; - if ( newHostName == oam::UnassignedName ) - continue; + //check if pkgs are located in /root directory + string cmd = "ls " + calpontPackage + " > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + log.writeLog(__LINE__, "addModule - ERROR: Package not found: " + calpontPackage, LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FILE_OPEN_ERROR; + } + log.writeLog(__LINE__, "addModule - ColumnStore Package found:" + calpontPackage, LOG_TYPE_DEBUG); + + // + // Verify Host IP and Password + // - string newIPAddr = (*pt1).IPAddr; - string cmd = installDir + "/bin/remote_command.sh " + newIPAddr + " " + password + " ls"; - log.writeLog(__LINE__, cmd, LOG_TYPE_DEBUG); - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - log.writeLog(__LINE__, "addModule - ERROR: Remote login test failed, Invalid IP / Password " + newIPAddr, LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FAILURE; - } - log.writeLog(__LINE__, "addModule - Remote login test successful: " + newIPAddr, LOG_TYPE_DEBUG); + if ( password == "ssh" && amazon ) + { // check if there is a root password stored + string rpw = oam::UnassignedName; + try + { + oam.getSystemConfig("rpw", rpw); + } + catch(...) + { + rpw = "mariadb1"; + } + + if (rpw != oam::UnassignedName) + password = rpw; + } + + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string newHostName = (*pt1).HostName; + if ( newHostName == oam::UnassignedName ) + continue; + + string newIPAddr = (*pt1).IPAddr; + string cmd = installDir + "/bin/remote_command.sh " + newIPAddr + " " + password + " ls"; + log.writeLog(__LINE__, cmd, LOG_TYPE_DEBUG); + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + log.writeLog(__LINE__, "addModule - ERROR: Remote login test failed, Invalid IP / Password " + newIPAddr, LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FAILURE; + } + log.writeLog(__LINE__, "addModule - Remote login test successful: " + newIPAddr, LOG_TYPE_DEBUG); + } } - + // //Get System Configuration file // @@ -4971,343 +5007,366 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } } - //PMwithUM config - string PMwithUM = "n"; - try { - oam.getSystemConfig( "PMwithUM", PMwithUM); - } - catch(...) { - PMwithUM = "n"; - } - - //check mysql port changes - string MySQLPort; - try { - oam.getSystemConfig( "MySQLPort", MySQLPort); - } - catch(...) - {} - - if ( MySQLPort.empty() || MySQLPort == "" || MySQLPort == oam::UnassignedName ) - MySQLPort = "3306"; - - string version = systemsoftware.Version + "-" + systemsoftware.Release; - - //setup and push custom OS files - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string remoteModuleName = (*listPT).DeviceName; - string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string remoteModuleIP = (*pt1).IPAddr; - string remoteHostName = (*pt1).HostName; - - //create and copy custom OS - //run remote installer script - string dir = installDir + "/local/etc/" + remoteModuleName; - - string cmd = "mkdir " + dir + " > /dev/null 2>&1"; - system(cmd.c_str()); - - if ( remoteModuleType == "um" ) { - cmd = "cp " + installDir + "/local/etc/um1/* " + dir + "/."; - system(cmd.c_str()); - } - else - { - if ( remoteModuleType == "pm") { - cmd = "cp " + installDir + "/local/etc/pm1/* " + dir + "/."; - system(cmd.c_str()); - } - } - log.writeLog(__LINE__, "addModule - created directory and custom OS files for " + remoteModuleName, LOG_TYPE_DEBUG); - - //create module file - if( !createModuleFile(remoteModuleName) ) { - log.writeLog(__LINE__, "addModule - ERROR: createModuleFile failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FAILURE; - } - log.writeLog(__LINE__, "addModule - create module file for " + remoteModuleName, LOG_TYPE_DEBUG); - - if ( remoteModuleType == "pm" ) { - //setup Standby OAM Parent, if needed - if ( config.OAMStandbyName() == oam::UnassignedName ) - setStandbyModule(remoteModuleName, false); - } - - //set root password - if (amazon) { - cmd = startup::StartUp::installDir() + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '/root/.scripts/updatePassword.sh " + password + "' > /tmp/password_change.log"; - log.writeLog(__LINE__, "addModule - cmd: " + cmd, LOG_TYPE_DEBUG); - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - log.writeLog(__LINE__, "addModule - update root password: " + remoteModuleName, LOG_TYPE_DEBUG); - else - log.writeLog(__LINE__, "addModule - ERROR: update root password: " + remoteModuleName, LOG_TYPE_DEBUG); - } - - //default - string binaryInstallDir = installDir; - - //run installer on remote module - if ( remoteModuleType == "um" || - ( remoteModuleType == "pm" && config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM ) || - ( remoteModuleType == "pm" && PMwithUM == "y" ) ) { - //run remote installer script - if ( packageType != "binary" ) { - log.writeLog(__LINE__, "addModule - user_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string cmd = installDir + "/bin/user_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + packageType + " --nodeps none " + MySQLPort + " 1 > /tmp/user_installer.log"; - - log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in("/tmp/user_installer.log"); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: user_installer.sh failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: user_installer.sh failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - system("/bin/cp -f /tmp/user_installer.log /tmp/user_installer.log.failed"); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - else - { // do a binary package install - log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string binservertype = oam.itoa(config.ServerInstallType()); - if ( PMwithUM == "y" ) - binservertype = "pmwithum"; - string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " " + remoteModuleType + " initial " + binservertype + " " + MySQLPort + " 1 " + binaryInstallDir + " > /tmp/binary_installer.log"; - - log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in("/tmp/binary_installer.log"); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - system("/bin/cp -f /tmp/binary_installer.log /tmp/binary_installer.log.failed"); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - } - else - { - if ( remoteModuleType == "pm" ) { - if ( packageType != "binary" ) { - log.writeLog(__LINE__, "addModule - performance_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - string cmd = installDir + "/bin/performance_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + packageType + + " --nodeps 1 > /tmp/performance_installer.log"; - log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); - - rtnCode = system(cmd.c_str()); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in("/tmp/performance_installer.log"); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: performance_installer.sh failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: performance_installer.sh failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - system("/bin/cp -f /tmp/performance_installer.log /tmp/performance_installer.log.failed"); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - else - { // do a binary package install - log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string binservertype = oam.itoa(config.ServerInstallType()); - if ( PMwithUM == "y" ) - binservertype = "pmwithum"; - - string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " " + remoteModuleType + " initial " + binservertype + " " + MySQLPort + " 1 " + binaryInstallDir + " > /tmp/binary_installer.log"; - - log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in("/tmp/binary_installer.log"); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - system("/bin/cp -f /tmp/binary_installer.log /tmp/binary_installer.log.failed"); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - } - } - } - - //Start new modules by starting up local Process-Monitor - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string remoteModuleName = (*listPT).DeviceName; - - if (manualFlag) - //set new module to disable state if manual add - disableModule(remoteModuleName, true); - - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string remoteModuleIP = (*pt1).IPAddr; - string remoteHostName = (*pt1).HostName; - - //send start service commands - string cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/columnstore restart;" + installDir + "/mysql/mysqld-Calpont restart' 0"; - system(cmd.c_str()); - log.writeLog(__LINE__, "addModule - restart columnstore service " + remoteModuleName, LOG_TYPE_DEBUG); - - // add to monitor list - moduleInfoList.insert(moduleList::value_type(remoteModuleName, 0)); - if (amazon) { - //check and assign Elastic IP Address - int AmazonElasticIPCount = 0; - try{ - oam.getSystemConfig("AmazonElasticIPCount", AmazonElasticIPCount); - } - catch(...) { - AmazonElasticIPCount = 0; - } - - for ( int id = 1 ; id < AmazonElasticIPCount+1 ; id++ ) - { - string AmazonElasticModule = "AmazonElasticModule" + oam.itoa(id); - string ELmoduleName; - try{ - oam.getSystemConfig(AmazonElasticModule, ELmoduleName); - } - catch(...) {} - - if ( ELmoduleName == remoteModuleName ) - { //match found assign Elastic IP Address - string AmazonElasticIPAddr = "AmazonElasticIPAddr" + oam.itoa(id); - string ELIPaddress; - try{ - oam.getSystemConfig(AmazonElasticIPAddr, ELIPaddress); - } - catch(...) {} - - try{ - oam.assignElasticIP(remoteHostName, ELIPaddress); - log.writeLog(__LINE__, "addModule - Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_DEBUG); - } - catch(...) { - log.writeLog(__LINE__, "addModule - Failed to Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_ERROR); - } - break; - } - } - } - } - - //if amazon, delay to give time for ProcMon to start - if (amazon) { - log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to start on new Instance", LOG_TYPE_DEBUG); - sleep(30); - } - //distribute config file distributeConfigFile("system"); + if ( DistributedInstall == "y" ) { + + //PMwithUM config + string PMwithUM = "n"; + try { + oam.getSystemConfig( "PMwithUM", PMwithUM); + } + catch(...) { + PMwithUM = "n"; + } + + string version = systemsoftware.Version + "-" + systemsoftware.Release; + + string AmazonInstall = "0"; + if ( amazon ) + AmazonInstall = "1"; + + //setup and push custom OS files + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string remoteModuleName = (*listPT).DeviceName; + string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string remoteModuleIP = (*pt1).IPAddr; + string remoteHostName = (*pt1).HostName; + + //create and copy custom OS + //run remote installer script + string dir = installDir + "/local/etc/" + remoteModuleName; + + string cmd = "mkdir " + dir + " > /dev/null 2>&1"; + system(cmd.c_str()); + + if ( remoteModuleType == "um" ) { + cmd = "cp " + installDir + "/local/etc/um1/* " + dir + "/."; + system(cmd.c_str()); + } + else + { + if ( remoteModuleType == "pm") { + cmd = "cp " + installDir + "/local/etc/pm1/* " + dir + "/."; + system(cmd.c_str()); + } + } + log.writeLog(__LINE__, "addModule - created directory and custom OS files for " + remoteModuleName, LOG_TYPE_DEBUG); + + //create module file + if( !createModuleFile(remoteModuleName) ) { + log.writeLog(__LINE__, "addModule - ERROR: createModuleFile failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FAILURE; + } + log.writeLog(__LINE__, "addModule - create module file for " + remoteModuleName, LOG_TYPE_DEBUG); + + if ( remoteModuleType == "pm" ) { + //setup Standby OAM Parent, if needed + if ( config.OAMStandbyName() == oam::UnassignedName ) + setStandbyModule(remoteModuleName, false); + } + + //set root password + if (amazon) { + cmd = startup::StartUp::installDir() + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '/root/.scripts/updatePassword.sh " + password + "' > /tmp/password_change.log"; + log.writeLog(__LINE__, "addModule - cmd: " + cmd, LOG_TYPE_DEBUG); + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + log.writeLog(__LINE__, "addModule - update root password: " + remoteModuleName, LOG_TYPE_DEBUG); + else + log.writeLog(__LINE__, "addModule - ERROR: update root password: " + remoteModuleName, LOG_TYPE_DEBUG); + } + + //default + string binaryInstallDir = installDir; + + //run installer on remote module + if ( remoteModuleType == "um" || + ( remoteModuleType == "pm" && config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM ) || + ( remoteModuleType == "pm" && PMwithUM == "y" ) ) { + //run remote installer script + if ( packageType != "binary" ) { + string logFile = "/tmp/" + remoteModuleName + "_user_installer.log"; + log.writeLog(__LINE__, "addModule - user_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string cmd = installDir + "/bin/user_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + packageType + " --nodeps none 1 > " + logFile; + + log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in(logFile.c_str()); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; + system(cmd.c_str()); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + else + { // do a binary package install + string logFile = "/tmp/" + remoteModuleName + "_binary_installer.log"; + log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string binservertype = oam.itoa(config.ServerInstallType()); + if ( PMwithUM == "y" ) + binservertype = "pmwithum"; + string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " initial " + AmazonInstall + " 1 " + binaryInstallDir + " > " + logFile; + + log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in(logFile.c_str()); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + pthread_mutex_unlock(&THREAD_LOCK); + cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; + system(cmd.c_str()); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + } + else + { + if ( remoteModuleType == "pm" ) { + if ( packageType != "binary" ) { + string logFile = "/tmp/" + remoteModuleName + "_performance_installer.log"; + log.writeLog(__LINE__, "addModule - performance_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + string cmd = installDir + "/bin/performance_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + packageType + + " --nodeps 1 > " + logFile; + log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); + + system(cmd.c_str()); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in(logFile.c_str()); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + pthread_mutex_unlock(&THREAD_LOCK); + cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; + system(cmd.c_str()); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + else + { // do a binary package install + string logFile = "/tmp/" + remoteModuleName + "_binary_installer.log"; + log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string binservertype = oam.itoa(config.ServerInstallType()); + if ( PMwithUM == "y" ) + binservertype = "pmwithum"; + + string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " initial " + AmazonInstall + " 1 " + binaryInstallDir + " > " + logFile; + + log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in(logFile.c_str()); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); + pthread_mutex_unlock(&THREAD_LOCK); + cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; + system(cmd.c_str()); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + } + } + } + + //distribute config file + distributeConfigFile("system"); + + //Start new modules by starting up local Process-Monitor + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string remoteModuleName = (*listPT).DeviceName; + + if (manualFlag) + //set new module to disable state if manual add + disableModule(remoteModuleName, true); + + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string remoteModuleIP = (*pt1).IPAddr; + string remoteHostName = (*pt1).HostName; + + + // add to monitor list + moduleInfoList.insert(moduleList::value_type(remoteModuleName, 0)); + if (amazon) { + //check and assign Elastic IP Address + int AmazonElasticIPCount = 0; + try{ + oam.getSystemConfig("AmazonElasticIPCount", AmazonElasticIPCount); + } + catch(...) { + AmazonElasticIPCount = 0; + } + + for ( int id = 1 ; id < AmazonElasticIPCount+1 ; id++ ) + { + string AmazonElasticModule = "AmazonElasticModule" + oam.itoa(id); + string ELmoduleName; + try{ + oam.getSystemConfig(AmazonElasticModule, ELmoduleName); + } + catch(...) {} + + if ( ELmoduleName == remoteModuleName ) + { //match found assign Elastic IP Address + string AmazonElasticIPAddr = "AmazonElasticIPAddr" + oam.itoa(id); + string ELIPaddress; + try{ + oam.getSystemConfig(AmazonElasticIPAddr, ELIPaddress); + } + catch(...) {} + + try{ + oam.assignElasticIP(remoteHostName, ELIPaddress); + log.writeLog(__LINE__, "addModule - Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_DEBUG); + } + catch(...) { + log.writeLog(__LINE__, "addModule - Failed to Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_ERROR); + } + break; + } + } + } + } + + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string moduleName = (*listPT).DeviceName; + + processManager.configureModule(moduleName); + sleep(10); + } + + //if amazon, delay to give time for ProcMon to start +// if (amazon) { +// log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to start on new Instance", LOG_TYPE_DEBUG); +// sleep(30); +// } + } + else + { + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string moduleName = (*listPT).DeviceName; + + processManager.configureModule(moduleName); + sleep(10); + } + } + log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); @@ -5607,6 +5666,20 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool return API_FAILURE; } + //clear out the known_host file, sometimes causes a failure on amazon during addModule + if ( amazon ) + { + string homedir = "/root"; + if (!rootUser) { + char* p= getenv("HOME"); + if (p && *p) + homedir = p; + } + + string cmd = "sudo unlink " + homedir + ".ssh/know_hosts > /dev/null 2>&1"; + system(cmd.c_str()); + } + pthread_mutex_unlock(&THREAD_LOCK); //check if any removed modules was Standby OAM or Active OAM @@ -6010,6 +6083,40 @@ int ProcessManager::reconfigureModule(oam::DeviceNetworkList devicenetworklist) return API_SUCCESS; } +/****************************************************************************************** +* @brief configureModule +* +* purpose: Configure Module sends message to procmon to setup modulename +* +******************************************************************************************/ +int ProcessManager::configureModule(std::string moduleName) +{ + //distribute config file + distributeConfigFile(moduleName); + + // + //Send Configure msg to Module's Process-Monitor being reconfigured + // + ByteStream msg; + ByteStream::byte requestID = CONFIGURE; + + msg << requestID; + msg << moduleName; + + int returnStatus = sendMsgProcMon( moduleName, msg, requestID ); + + if ( returnStatus == API_SUCCESS) + //log the event + log.writeLog(__LINE__, "configureModule - procmon configure successful", LOG_TYPE_DEBUG); + else + { + log.writeLog(__LINE__, "configureModule - procmon configure failed", LOG_TYPE_ERROR); + return API_FAILURE; + } + + return API_SUCCESS; +} + /****************************************************************************************** * @brief sendMsgProcMon From c88903191d83d420322d77c9f0afec73b26191ce Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 17 Jul 2017 15:56:06 -0500 Subject: [PATCH 106/185] MCOL-814 --- dbcon/joblist/distributedenginecomm.cpp | 36 +- procmgr/processmanager.cpp | 876 +++++++++++------------- 2 files changed, 411 insertions(+), 501 deletions(-) diff --git a/dbcon/joblist/distributedenginecomm.cpp b/dbcon/joblist/distributedenginecomm.cpp index 4407c4d6d..c1345f6d0 100644 --- a/dbcon/joblist/distributedenginecomm.cpp +++ b/dbcon/joblist/distributedenginecomm.cpp @@ -171,7 +171,7 @@ namespace joblist DistributedEngineComm* DistributedEngineComm::fInstance = 0; /*static*/ - DistributedEngineComm* DistributedEngineComm::instance(ResourceManager* rm, bool isExeMgr) + DistributedEngineComm* DistributedEngineComm::instance(ResourceManager& rm, bool isExeMgr) { if (fInstance == 0) fInstance = new DistributedEngineComm(rm, isExeMgr); @@ -186,9 +186,9 @@ namespace joblist fInstance = 0; } - DistributedEngineComm::DistributedEngineComm(ResourceManager* rm, bool isExeMgr) : + DistributedEngineComm::DistributedEngineComm(ResourceManager& rm, bool isExeMgr) : fRm(rm), - fLBIDShift(fRm->getPsLBID_Shift()), + fLBIDShift(fRm.getPsLBID_Shift()), pmCount(0), fIsExeMgr(isExeMgr) { @@ -219,10 +219,10 @@ void DistributedEngineComm::Setup() newClients.clear(); newLocks.clear(); - throttleThreshold = fRm->getDECThrottleThreshold(); - uint32_t newPmCount = fRm->getPsCount(); - int cpp = (fIsExeMgr ? fRm->getPsConnectionsPerPrimProc() : 1); - tbpsThreadCount = fRm->getJlNumScanReceiveThreads(); + throttleThreshold = fRm.getDECThrottleThreshold(); + uint32_t newPmCount = fRm.getPsCount(); + int cpp = (fIsExeMgr ? fRm.getPsConnectionsPerPrimProc() : 1); + tbpsThreadCount = fRm.getJlNumScanReceiveThreads(); unsigned numConnections = newPmCount * cpp; oam::Oam oam; ModuleTypeConfig moduletypeconfig; @@ -246,7 +246,7 @@ void DistributedEngineComm::Setup() string fServer (oss.str()); boost::shared_ptr - cl(new MessageQueueClient(fServer, fRm->getConfig())); + cl(new MessageQueueClient(fServer, fRm.getConfig())); boost::shared_ptr nl(new boost::mutex()); try { if (cl->connect()) { @@ -297,7 +297,7 @@ void DistributedEngineComm::Setup() int DistributedEngineComm::Close() { - cout << "DistributedEngineComm::Close() called" << endl; + //cout << "DistributedEngineComm::Close() called" << endl; makeBusy(false); // for each MessageQueueClient in pmConnections delete the MessageQueueClient; @@ -336,10 +336,10 @@ void DistributedEngineComm::Listen(boost::shared_ptr client, Error: // @bug 488 - error condition! push 0 length bs to messagequeuemap and // eventually let jobstep error out. - mutex::scoped_lock lk(fMlock); - cout << "WARNING: DEC READ 0 LENGTH BS FROM " << client->otherEnd()<< endl; +/* mutex::scoped_lock lk(fMlock); + //cout << "WARNING: DEC READ 0 LENGTH BS FROM " << client->otherEnd()<< endl; -/* MessageQueueMap::iterator map_tok; + MessageQueueMap::iterator map_tok; sbs.reset(new ByteStream(0)); for (map_tok = fSessionMessages.begin(); map_tok != fSessionMessages.end(); ++map_tok) @@ -356,20 +356,20 @@ Error: { mutex::scoped_lock onErrLock(fOnErrMutex); string moduleName = client->moduleName(); - cout << "moduleName=" << moduleName << endl; + //cout << "moduleName=" << moduleName << endl; for ( uint32_t i = 0; i < fPmConnections.size(); i++) { if (moduleName != fPmConnections[i]->moduleName()) tempConns.push_back(fPmConnections[i]); //else - cout << "DEC remove PM" << fPmConnections[i]->otherEnd() << " moduleName=" << fPmConnections[i]->moduleName() << endl; + //cout << "DEC remove PM" << fPmConnections[i]->otherEnd() << " moduleName=" << fPmConnections[i]->moduleName() << endl; } if (tempConns.size() == fPmConnections.size()) return; fPmConnections.swap(tempConns); pmCount = (pmCount == 0 ? 0 : pmCount - 1); - cout << "PMCOUNT=" << pmCount << endl; + //cout << "PMCOUNT=" << pmCount << endl; */ // send alarm & log it ALARMManager alarmMgr; @@ -863,7 +863,7 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin // by pushing 0 size bytestream to messagequeue and throw excpetion /* SBS sbs; lk.lock(); - cout << "WARNING: DEC WRITE BROKEN PIPE. PMS index = " << index << endl; + //cout << "WARNING: DEC WRITE BROKEN PIPE. PMS index = " << index << endl; MessageQueueMap::iterator map_tok; sbs.reset(new ByteStream(0)); @@ -879,10 +879,10 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin // reconfig the connection array ClientList tempConns; { - cout << "WARNING: DEC WRITE BROKEN PIPE " << fPmConnections[index]->otherEnd()<< endl; + //cout << "WARNING: DEC WRITE BROKEN PIPE " << fPmConnections[index]->otherEnd()<< endl; mutex::scoped_lock onErrLock(fOnErrMutex); string moduleName = fPmConnections[index]->moduleName(); - cout << "module name = " << moduleName << endl; + //cout << "module name = " << moduleName << endl; if (index >= fPmConnections.size()) return 0; for (uint32_t i = 0; i < fPmConnections.size(); i++) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index e5c783c40..0a6efcef0 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -618,11 +618,11 @@ void processMSG(messageqcpp::IOSocket* cfIos) oam.dbrmctl("resume"); log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); -// processManager.restartProcessType("ExeMgr"); + processManager.restartProcessType("ExeMgr"); //setup MySQL Replication for started modules -// log.writeLog(__LINE__, "Setup MySQL Replication for module being started", LOG_TYPE_DEBUG); -// processManager.setMySQLReplication(startdevicenetworklist); + log.writeLog(__LINE__, "Setup MySQL Replication for module being started", LOG_TYPE_DEBUG); + processManager.setMySQLReplication(startdevicenetworklist); } } else @@ -2801,7 +2801,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) processManager.reinitProcessType("cpimport"); - //request reinit after Process is active + //request reinit after Process is active for ( int i = 0; i < 600 ; i++ ) { try { ProcessStatus procstat; @@ -2861,7 +2861,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) } // Wait for DMLProc to be ACTIVE - //BRM::DBRM dbrm; + BRM::DBRM dbrm; state = AUTO_OFFLINE; while (state == oam::MAN_OFFLINE || state == oam::AUTO_OFFLINE @@ -2875,7 +2875,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) break; sleep(1); } - //dbrm.setSystemQueryReady(true); + dbrm.setSystemQueryReady(true); } // if a DDLProc was restarted, reinit DMLProc @@ -2926,7 +2926,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) break; } } - + //enable query stats dbrm.setSystemQueryReady(true); @@ -3814,8 +3814,10 @@ void ProcessManager::setSystemState(uint16_t state) else if ( state == oam::AUTO_OFFLINE ) aManager.sendAlarmReport(system.c_str(), SYSTEM_DOWN_AUTO, SET); + //this alarm doesnt get clear by reporter, so clear on stopage aManager.sendAlarmReport(system.c_str(), CONN_FAILURE, CLEAR); } + pthread_mutex_unlock(&STATUS_LOCK); } @@ -4435,18 +4437,6 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str pthread_mutex_lock(&THREAD_LOCK); - //get Distributed Install - string DistributedInstall = "y"; - - try - { - oam.getSystemConfig("DistributedInstall", DistributedInstall); - } - catch (...) - { - log.writeLog(__LINE__, "addModule - ERROR: get DistributedInstall", LOG_TYPE_ERROR); - } - int AddModuleCount = devicenetworklist.size(); DeviceNetworkList::iterator listPT = devicenetworklist.begin(); string moduleType = (*listPT).DeviceName.substr(0,MAX_MODULE_TYPE_SIZE); @@ -4537,6 +4527,8 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str return API_FAILURE; } + + //check if pkgs are located in /root directory string homedir = "/root"; if (!rootUser) { char* p= getenv("HOME"); @@ -4544,13 +4536,6 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str homedir = p; } - //clear out the known_host file, sometimes causes a failure on amazon during addModule - if ( amazon ) - { - string cmd = "sudo unlink " + homedir + ".ssh/know_hosts > /dev/null 2>&1"; - system(cmd.c_str()); - } - if ( packageType == "rpm") calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.rpm.tar.gz"; else @@ -4559,59 +4544,55 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str else calpontPackage = homedir + "/mariadb-columnstore*" + systemsoftware.Version + "-" + systemsoftware.Release + "*.bin.tar.gz"; - if ( DistributedInstall == "y" ) - { - //check if pkgs are located in /root directory - string cmd = "ls " + calpontPackage + " > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - log.writeLog(__LINE__, "addModule - ERROR: Package not found: " + calpontPackage, LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FILE_OPEN_ERROR; - } - log.writeLog(__LINE__, "addModule - ColumnStore Package found:" + calpontPackage, LOG_TYPE_DEBUG); - - // - // Verify Host IP and Password - // - - if ( password == "ssh" && amazon ) - { // check if there is a root password stored - string rpw = oam::UnassignedName; - try - { - oam.getSystemConfig("rpw", rpw); - } - catch(...) - { - rpw = "mariadb1"; - } - - if (rpw != oam::UnassignedName) - password = rpw; - } - - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string newHostName = (*pt1).HostName; - if ( newHostName == oam::UnassignedName ) - continue; - - string newIPAddr = (*pt1).IPAddr; - string cmd = installDir + "/bin/remote_command.sh " + newIPAddr + " " + password + " ls"; - log.writeLog(__LINE__, cmd, LOG_TYPE_DEBUG); - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - log.writeLog(__LINE__, "addModule - ERROR: Remote login test failed, Invalid IP / Password " + newIPAddr, LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FAILURE; - } - log.writeLog(__LINE__, "addModule - Remote login test successful: " + newIPAddr, LOG_TYPE_DEBUG); - } + string cmd = "ls " + calpontPackage + " > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + log.writeLog(__LINE__, "addModule - ERROR: Package not found: " + calpontPackage, LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FILE_OPEN_ERROR; } - + log.writeLog(__LINE__, "addModule - Calpont Package found:" + calpontPackage, LOG_TYPE_DEBUG); + + // + // Verify Host IP and Password + // + + if ( password == "ssh" && amazon ) + { // check if there is a root password stored + string rpw = oam::UnassignedName; + try + { + oam.getSystemConfig("rpw", rpw); + } + catch(...) + { + rpw = "mariadb1"; + } + + if (rpw != oam::UnassignedName) + password = rpw; + } + + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string newHostName = (*pt1).HostName; + if ( newHostName == oam::UnassignedName ) + continue; + + string newIPAddr = (*pt1).IPAddr; + string cmd = installDir + "/bin/remote_command.sh " + newIPAddr + " " + password + " ls"; + log.writeLog(__LINE__, cmd, LOG_TYPE_DEBUG); + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + log.writeLog(__LINE__, "addModule - ERROR: Remote login test failed, Invalid IP / Password " + newIPAddr, LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FAILURE; + } + log.writeLog(__LINE__, "addModule - Remote login test successful: " + newIPAddr, LOG_TYPE_DEBUG); + } + // //Get System Configuration file // @@ -5007,366 +4988,343 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } } + //PMwithUM config + string PMwithUM = "n"; + try { + oam.getSystemConfig( "PMwithUM", PMwithUM); + } + catch(...) { + PMwithUM = "n"; + } + + //check mysql port changes + string MySQLPort; + try { + oam.getSystemConfig( "MySQLPort", MySQLPort); + } + catch(...) + {} + + if ( MySQLPort.empty() || MySQLPort == "" || MySQLPort == oam::UnassignedName ) + MySQLPort = "3306"; + + string version = systemsoftware.Version + "-" + systemsoftware.Release; + + //setup and push custom OS files + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string remoteModuleName = (*listPT).DeviceName; + string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string remoteModuleIP = (*pt1).IPAddr; + string remoteHostName = (*pt1).HostName; + + //create and copy custom OS + //run remote installer script + string dir = installDir + "/local/etc/" + remoteModuleName; + + string cmd = "mkdir " + dir + " > /dev/null 2>&1"; + system(cmd.c_str()); + + if ( remoteModuleType == "um" ) { + cmd = "cp " + installDir + "/local/etc/um1/* " + dir + "/."; + system(cmd.c_str()); + } + else + { + if ( remoteModuleType == "pm") { + cmd = "cp " + installDir + "/local/etc/pm1/* " + dir + "/."; + system(cmd.c_str()); + } + } + log.writeLog(__LINE__, "addModule - created directory and custom OS files for " + remoteModuleName, LOG_TYPE_DEBUG); + + //create module file + if( !createModuleFile(remoteModuleName) ) { + log.writeLog(__LINE__, "addModule - ERROR: createModuleFile failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + return API_FAILURE; + } + log.writeLog(__LINE__, "addModule - create module file for " + remoteModuleName, LOG_TYPE_DEBUG); + + if ( remoteModuleType == "pm" ) { + //setup Standby OAM Parent, if needed + if ( config.OAMStandbyName() == oam::UnassignedName ) + setStandbyModule(remoteModuleName, false); + } + + //set root password + if (amazon) { + cmd = startup::StartUp::installDir() + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '/root/.scripts/updatePassword.sh " + password + "' > /tmp/password_change.log"; + log.writeLog(__LINE__, "addModule - cmd: " + cmd, LOG_TYPE_DEBUG); + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + log.writeLog(__LINE__, "addModule - update root password: " + remoteModuleName, LOG_TYPE_DEBUG); + else + log.writeLog(__LINE__, "addModule - ERROR: update root password: " + remoteModuleName, LOG_TYPE_DEBUG); + } + + //default + string binaryInstallDir = installDir; + + //run installer on remote module + if ( remoteModuleType == "um" || + ( remoteModuleType == "pm" && config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM ) || + ( remoteModuleType == "pm" && PMwithUM == "y" ) ) { + //run remote installer script + if ( packageType != "binary" ) { + log.writeLog(__LINE__, "addModule - user_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string cmd = installDir + "/bin/user_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + packageType + " --nodeps none " + MySQLPort + " 1 > /tmp/user_installer.log"; + + log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in("/tmp/user_installer.log"); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: user_installer.sh failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: user_installer.sh failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + system("/bin/cp -f /tmp/user_installer.log /tmp/user_installer.log.failed"); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + else + { // do a binary package install + log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string binservertype = oam.itoa(config.ServerInstallType()); + if ( PMwithUM == "y" ) + binservertype = "pmwithum"; + string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " " + remoteModuleType + " initial " + binservertype + " " + MySQLPort + " 1 " + binaryInstallDir + " > /tmp/binary_installer.log"; + + log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in("/tmp/binary_installer.log"); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + system("/bin/cp -f /tmp/binary_installer.log /tmp/binary_installer.log.failed"); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + } + else + { + if ( remoteModuleType == "pm" ) { + if ( packageType != "binary" ) { + log.writeLog(__LINE__, "addModule - performance_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + string cmd = installDir + "/bin/performance_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + packageType + + " --nodeps 1 > /tmp/performance_installer.log"; + log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); + + rtnCode = system(cmd.c_str()); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in("/tmp/performance_installer.log"); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: performance_installer.sh failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: performance_installer.sh failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + system("/bin/cp -f /tmp/performance_installer.log /tmp/performance_installer.log.failed"); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + else + { // do a binary package install + log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); + + string binservertype = oam.itoa(config.ServerInstallType()); + if ( PMwithUM == "y" ) + binservertype = "pmwithum"; + + string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " " + remoteModuleType + " initial " + binservertype + " " + MySQLPort + " 1 " + binaryInstallDir + " > /tmp/binary_installer.log"; + + log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); + + bool passed = false; + for ( int retry = 0 ; retry < 20 ; retry++ ) + { + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + // if log file size is zero, retry + ifstream in("/tmp/binary_installer.log"); + in.seekg(0, std::ios::end); + int size = in.tellg(); + if ( size == 0 ) + { + log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed, retry", LOG_TYPE_DEBUG); + sleep(5); + continue; + } + else + break; + } + else + { + passed = true; + break; + } + } + + if ( !passed ) + { + log.writeLog(__LINE__, "addModule - ERROR: binary_installer.sh failed", LOG_TYPE_ERROR); + pthread_mutex_unlock(&THREAD_LOCK); + system("/bin/cp -f /tmp/binary_installer.log /tmp/binary_installer.log.failed"); + processManager.setModuleState(remoteModuleName, oam::FAILED); + return API_FAILURE; + } + } + } + } + } + + //Start new modules by starting up local Process-Monitor + listPT = devicenetworklist.begin(); + for( ; listPT != devicenetworklist.end() ; listPT++) + { + string remoteModuleName = (*listPT).DeviceName; + + if (manualFlag) + //set new module to disable state if manual add + disableModule(remoteModuleName, true); + + HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); + string remoteModuleIP = (*pt1).IPAddr; + string remoteHostName = (*pt1).HostName; + + //send start service commands + string cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/columnstore restart;" + installDir + "/mysql/mysqld-Calpont restart' 0"; + system(cmd.c_str()); + log.writeLog(__LINE__, "addModule - restart columnstore service " + remoteModuleName, LOG_TYPE_DEBUG); + + // add to monitor list + moduleInfoList.insert(moduleList::value_type(remoteModuleName, 0)); + if (amazon) { + //check and assign Elastic IP Address + int AmazonElasticIPCount = 0; + try{ + oam.getSystemConfig("AmazonElasticIPCount", AmazonElasticIPCount); + } + catch(...) { + AmazonElasticIPCount = 0; + } + + for ( int id = 1 ; id < AmazonElasticIPCount+1 ; id++ ) + { + string AmazonElasticModule = "AmazonElasticModule" + oam.itoa(id); + string ELmoduleName; + try{ + oam.getSystemConfig(AmazonElasticModule, ELmoduleName); + } + catch(...) {} + + if ( ELmoduleName == remoteModuleName ) + { //match found assign Elastic IP Address + string AmazonElasticIPAddr = "AmazonElasticIPAddr" + oam.itoa(id); + string ELIPaddress; + try{ + oam.getSystemConfig(AmazonElasticIPAddr, ELIPaddress); + } + catch(...) {} + + try{ + oam.assignElasticIP(remoteHostName, ELIPaddress); + log.writeLog(__LINE__, "addModule - Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_DEBUG); + } + catch(...) { + log.writeLog(__LINE__, "addModule - Failed to Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_ERROR); + } + break; + } + } + } + } + + //if amazon, delay to give time for ProcMon to start + if (amazon) { + log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to start on new Instance", LOG_TYPE_DEBUG); + sleep(30); + } + //distribute config file distributeConfigFile("system"); - if ( DistributedInstall == "y" ) { - - //PMwithUM config - string PMwithUM = "n"; - try { - oam.getSystemConfig( "PMwithUM", PMwithUM); - } - catch(...) { - PMwithUM = "n"; - } - - string version = systemsoftware.Version + "-" + systemsoftware.Release; - - string AmazonInstall = "0"; - if ( amazon ) - AmazonInstall = "1"; - - //setup and push custom OS files - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string remoteModuleName = (*listPT).DeviceName; - string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string remoteModuleIP = (*pt1).IPAddr; - string remoteHostName = (*pt1).HostName; - - //create and copy custom OS - //run remote installer script - string dir = installDir + "/local/etc/" + remoteModuleName; - - string cmd = "mkdir " + dir + " > /dev/null 2>&1"; - system(cmd.c_str()); - - if ( remoteModuleType == "um" ) { - cmd = "cp " + installDir + "/local/etc/um1/* " + dir + "/."; - system(cmd.c_str()); - } - else - { - if ( remoteModuleType == "pm") { - cmd = "cp " + installDir + "/local/etc/pm1/* " + dir + "/."; - system(cmd.c_str()); - } - } - log.writeLog(__LINE__, "addModule - created directory and custom OS files for " + remoteModuleName, LOG_TYPE_DEBUG); - - //create module file - if( !createModuleFile(remoteModuleName) ) { - log.writeLog(__LINE__, "addModule - ERROR: createModuleFile failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - return API_FAILURE; - } - log.writeLog(__LINE__, "addModule - create module file for " + remoteModuleName, LOG_TYPE_DEBUG); - - if ( remoteModuleType == "pm" ) { - //setup Standby OAM Parent, if needed - if ( config.OAMStandbyName() == oam::UnassignedName ) - setStandbyModule(remoteModuleName, false); - } - - //set root password - if (amazon) { - cmd = startup::StartUp::installDir() + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '/root/.scripts/updatePassword.sh " + password + "' > /tmp/password_change.log"; - log.writeLog(__LINE__, "addModule - cmd: " + cmd, LOG_TYPE_DEBUG); - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) == 0) - log.writeLog(__LINE__, "addModule - update root password: " + remoteModuleName, LOG_TYPE_DEBUG); - else - log.writeLog(__LINE__, "addModule - ERROR: update root password: " + remoteModuleName, LOG_TYPE_DEBUG); - } - - //default - string binaryInstallDir = installDir; - - //run installer on remote module - if ( remoteModuleType == "um" || - ( remoteModuleType == "pm" && config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM ) || - ( remoteModuleType == "pm" && PMwithUM == "y" ) ) { - //run remote installer script - if ( packageType != "binary" ) { - string logFile = "/tmp/" + remoteModuleName + "_user_installer.log"; - log.writeLog(__LINE__, "addModule - user_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string cmd = installDir + "/bin/user_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + packageType + " --nodeps none 1 > " + logFile; - - log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in(logFile.c_str()); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed", LOG_TYPE_ERROR); - pthread_mutex_unlock(&THREAD_LOCK); - cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; - system(cmd.c_str()); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - else - { // do a binary package install - string logFile = "/tmp/" + remoteModuleName + "_binary_installer.log"; - log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string binservertype = oam.itoa(config.ServerInstallType()); - if ( PMwithUM == "y" ) - binservertype = "pmwithum"; - string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " initial " + AmazonInstall + " 1 " + binaryInstallDir + " > " + logFile; - - log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in(logFile.c_str()); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - pthread_mutex_unlock(&THREAD_LOCK); - cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; - system(cmd.c_str()); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - } - else - { - if ( remoteModuleType == "pm" ) { - if ( packageType != "binary" ) { - string logFile = "/tmp/" + remoteModuleName + "_performance_installer.log"; - log.writeLog(__LINE__, "addModule - performance_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - string cmd = installDir + "/bin/performance_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + packageType + + " --nodeps 1 > " + logFile; - log.writeLog(__LINE__, "addModule cmd: " + cmd, LOG_TYPE_DEBUG); - - system(cmd.c_str()); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in(logFile.c_str()); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - pthread_mutex_unlock(&THREAD_LOCK); - cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; - system(cmd.c_str()); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - else - { // do a binary package install - string logFile = "/tmp/" + remoteModuleName + "_binary_installer.log"; - log.writeLog(__LINE__, "addModule - binary_installer run for " + remoteModuleName, LOG_TYPE_DEBUG); - - string binservertype = oam.itoa(config.ServerInstallType()); - if ( PMwithUM == "y" ) - binservertype = "pmwithum"; - - string cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + calpontPackage + " initial " + AmazonInstall + " 1 " + binaryInstallDir + " > " + logFile; - - log.writeLog(__LINE__, "addModule - " + cmd, LOG_TYPE_DEBUG); - - bool passed = false; - for ( int retry = 0 ; retry < 20 ; retry++ ) - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - // if log file size is zero, retry - ifstream in(logFile.c_str()); - in.seekg(0, std::ios::end); - int size = in.tellg(); - if ( size == 0 ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - sleep(5); - continue; - } - else - break; - } - else - { - passed = true; - break; - } - } - - if ( !passed ) - { - log.writeLog(__LINE__, "addModule - ERROR: " + logFile + " failed, retry", LOG_TYPE_DEBUG); - pthread_mutex_unlock(&THREAD_LOCK); - cmd = "/bin/cp -f " + logFile + " " + logFile + "failed"; - system(cmd.c_str()); - processManager.setModuleState(remoteModuleName, oam::FAILED); - return API_FAILURE; - } - } - } - } - } - - //distribute config file - distributeConfigFile("system"); - - //Start new modules by starting up local Process-Monitor - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string remoteModuleName = (*listPT).DeviceName; - - if (manualFlag) - //set new module to disable state if manual add - disableModule(remoteModuleName, true); - - HostConfigList::iterator pt1 = (*listPT).hostConfigList.begin(); - string remoteModuleIP = (*pt1).IPAddr; - string remoteHostName = (*pt1).HostName; - - - // add to monitor list - moduleInfoList.insert(moduleList::value_type(remoteModuleName, 0)); - if (amazon) { - //check and assign Elastic IP Address - int AmazonElasticIPCount = 0; - try{ - oam.getSystemConfig("AmazonElasticIPCount", AmazonElasticIPCount); - } - catch(...) { - AmazonElasticIPCount = 0; - } - - for ( int id = 1 ; id < AmazonElasticIPCount+1 ; id++ ) - { - string AmazonElasticModule = "AmazonElasticModule" + oam.itoa(id); - string ELmoduleName; - try{ - oam.getSystemConfig(AmazonElasticModule, ELmoduleName); - } - catch(...) {} - - if ( ELmoduleName == remoteModuleName ) - { //match found assign Elastic IP Address - string AmazonElasticIPAddr = "AmazonElasticIPAddr" + oam.itoa(id); - string ELIPaddress; - try{ - oam.getSystemConfig(AmazonElasticIPAddr, ELIPaddress); - } - catch(...) {} - - try{ - oam.assignElasticIP(remoteHostName, ELIPaddress); - log.writeLog(__LINE__, "addModule - Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_DEBUG); - } - catch(...) { - log.writeLog(__LINE__, "addModule - Failed to Set Elastic IP Address: " + remoteModuleName + "/" + ELIPaddress, LOG_TYPE_ERROR); - } - break; - } - } - } - } - - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string moduleName = (*listPT).DeviceName; - - processManager.configureModule(moduleName); - sleep(10); - } - - //if amazon, delay to give time for ProcMon to start -// if (amazon) { -// log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to start on new Instance", LOG_TYPE_DEBUG); -// sleep(30); -// } - } - else - { - listPT = devicenetworklist.begin(); - for( ; listPT != devicenetworklist.end() ; listPT++) - { - string moduleName = (*listPT).DeviceName; - - processManager.configureModule(moduleName); - sleep(10); - } - } - log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); @@ -5666,20 +5624,6 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool return API_FAILURE; } - //clear out the known_host file, sometimes causes a failure on amazon during addModule - if ( amazon ) - { - string homedir = "/root"; - if (!rootUser) { - char* p= getenv("HOME"); - if (p && *p) - homedir = p; - } - - string cmd = "sudo unlink " + homedir + ".ssh/know_hosts > /dev/null 2>&1"; - system(cmd.c_str()); - } - pthread_mutex_unlock(&THREAD_LOCK); //check if any removed modules was Standby OAM or Active OAM @@ -6083,40 +6027,6 @@ int ProcessManager::reconfigureModule(oam::DeviceNetworkList devicenetworklist) return API_SUCCESS; } -/****************************************************************************************** -* @brief configureModule -* -* purpose: Configure Module sends message to procmon to setup modulename -* -******************************************************************************************/ -int ProcessManager::configureModule(std::string moduleName) -{ - //distribute config file - distributeConfigFile(moduleName); - - // - //Send Configure msg to Module's Process-Monitor being reconfigured - // - ByteStream msg; - ByteStream::byte requestID = CONFIGURE; - - msg << requestID; - msg << moduleName; - - int returnStatus = sendMsgProcMon( moduleName, msg, requestID ); - - if ( returnStatus == API_SUCCESS) - //log the event - log.writeLog(__LINE__, "configureModule - procmon configure successful", LOG_TYPE_DEBUG); - else - { - log.writeLog(__LINE__, "configureModule - procmon configure failed", LOG_TYPE_ERROR); - return API_FAILURE; - } - - return API_SUCCESS; -} - /****************************************************************************************** * @brief sendMsgProcMon From 6a0bceaa9bed412912691ed775da82d54bf8a6a9 Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 19 Jul 2017 09:49:31 -0500 Subject: [PATCH 107/185] MCOL-787 - add checks before dbbuilder 7 --- procmgr/processmanager.cpp | 9 ++++++++- procmon/processmonitor.cpp | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index ae76401ca..db44342ea 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -6855,7 +6855,14 @@ void startSystemThread(oam::DeviceNetworkList Devicenetworklist) } //run command to build system table if they don't already exist - processManager.buildSystemTables("pm1"); + sleep(5); + int ret = processManager.buildSystemTables("pm1"); + if (ret == oam::API_SUCCESS ) + log.writeLog(__LINE__, "System Catalog Successfully Built by ProcMgr", LOG_TYPE_DEBUG); + else + log.writeLog(__LINE__, "System Catalog Successfully not built by ProcMgr, ret code = " + oam.itoa(ret), LOG_TYPE_DEBUG); + + log.writeLog(__LINE__, "startSystemThread Exit", LOG_TYPE_DEBUG); // exit thread log.writeLog(__LINE__, "startSystemThread Exit", LOG_TYPE_DEBUG); diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 093f92305..8da3a6734 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -3480,6 +3480,17 @@ int ProcessMonitor::buildSystemTables() oam.getSystemConfig("DBRoot1", DBdir); string fileName = DBdir + "/000.dir"; + + //check if postConfigure or dbbuilder is running, return if so + string cmd = "ps aux | grep postConfigure | grep -v grep"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + return API_ALREADY_IN_PROGRESS; + + cmd = "ps aux | grep dbbuilder | grep -v grep"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) == 0) + return API_ALREADY_IN_PROGRESS; if (!IDBPolicy::exists(fileName.c_str())) { string logdir("/var/log/mariadb/columnstore"); @@ -3490,7 +3501,7 @@ int ProcessMonitor::buildSystemTables() log.writeLog(__LINE__, "buildSystemTables: dbbuilder 7 Successfully Launched" , LOG_TYPE_DEBUG); return API_SUCCESS; } - log.writeLog(__LINE__, "buildSystemTables: System Tables Already Exist", LOG_TYPE_ERROR ); + log.writeLog(__LINE__, "buildSystemTables: System Tables Already Exist", LOG_TYPE_DEBUG ); return API_FILE_ALREADY_EXIST; } From a6fe6b134509021f7d0dddeed00c751ce74998fb Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 19 Jul 2017 14:10:12 -0500 Subject: [PATCH 108/185] MCOL-419 - change to not call sudo on root user, causing a problem where service isn't starting up on centos7 --- oam/install_scripts/columnstore | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index 26ec19a25..f4fc48157 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -56,10 +56,9 @@ if [ "x$has_um" = x ]; then has_um=0 fi -user=root +user=`whoami 2>/dev/null` SUDO=" " -if [ "$USER" != "root" ]; then - user=$USER +if [ $user != "root" ]; then SUDO="sudo " fi @@ -81,7 +80,7 @@ start() { exit 0 fi - ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 + ($SUDO mkdir -p /var/lock/subsys && $SUDO chmod 777 /var/lock/subsys && $SUDO touch /var/lock/subsys/columnstore) >/dev/null 2>&1 if [ -x $InstallDir/bin/columnstore.pre-start ]; then $InstallDir/bin/columnstore.pre-start @@ -91,7 +90,7 @@ start() { exit 1 fi fi - checkInstallSetup + #checkInstallSetup CoreFileFlag=`$InstallDir/bin/getConfig -c $InstallDir/etc/Columnstore.xml Installation CoreFileFlag` if [ $CoreFileFlag = "y" ]; then From baf6409aad1c03d63701b0d80228eb552efae87b Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 19 Jul 2017 14:11:14 -0500 Subject: [PATCH 109/185] fixed issue - shared-nonthing pm outage was calling the move dbroot commands --- procmgr/main.cpp | 52 ++++++++++++++++++++------------------ procmgr/processmanager.cpp | 18 +------------ 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/procmgr/main.cpp b/procmgr/main.cpp index a42a62e13..fe00412ba 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -58,6 +58,7 @@ bool HDFS = false; string localHostName; string PMwithUM = "n"; string MySQLRep = "n"; +string DBRootStorageType = "internal"; // pushing the ACTIVE_ALARMS_FILE to all nodes every 10 seconds. const int ACTIVE_ALARMS_PUSHING_INTERVAL = 10; @@ -160,7 +161,6 @@ int main(int argc, char **argv) } //hdfs / hadoop config - string DBRootStorageType; try { oam.getSystemConfig( "DBRootStorageType", DBRootStorageType); } @@ -1281,8 +1281,8 @@ void pingDeviceThread() int status; - // if pm, move dbroots back to pm - if ( ( moduleName.find("pm") == 0 && !amazon ) || + // if shared pm, move dbroots back to pm + if ( ( moduleName.find("pm") == 0 && !amazon && ( DBRootStorageType != "internal") ) || ( moduleName.find("pm") == 0 && amazon && downActiveOAMModule ) || ( moduleName.find("pm") == 0 && amazon && AmazonPMFailover == "y") ) { @@ -1560,8 +1560,9 @@ void pingDeviceThread() aManager.sendAlarmReport(moduleName.c_str(), MODULE_DOWN_AUTO, SET); // if pm, move dbroots back to pm - if ( ( moduleName.find("pm") == 0 && !amazon ) || - ( moduleName.find("pm") == 0 && amazon && downActiveOAMModule ) ) { + if ( ( moduleName.find("pm") == 0 && !amazon && ( DBRootStorageType != "internal") ) || + ( moduleName.find("pm") == 0 && amazon && downActiveOAMModule ) || + ( moduleName.find("pm") == 0 && amazon && AmazonPMFailover == "y") ) { //move dbroots to other modules try { log.writeLog(__LINE__, "Call autoMovePmDbroot", LOG_TYPE_DEBUG); @@ -1667,25 +1668,24 @@ void pingDeviceThread() log.writeLog(__LINE__, "'dbrmctl reload' done", LOG_TYPE_DEBUG); // if pm, move dbroots to other pms - if ( !amazon || - ( amazon && AmazonPMFailover == "y") ) { - if( moduleName.find("pm") == 0 ) { - try { - log.writeLog(__LINE__, "Call autoMovePmDbroot", LOG_TYPE_DEBUG); - oam.autoMovePmDbroot(moduleName); - log.writeLog(__LINE__, "autoMovePmDbroot success", LOG_TYPE_DEBUG); - //distribute config file - processManager.distributeConfigFile("system"); - } - catch (exception& ex) - { - string error = ex.what(); - log.writeLog(__LINE__, "EXCEPTION ERROR on autoMovePmDbroot: " + error, LOG_TYPE_DEBUG); - } - catch(...) - { - log.writeLog(__LINE__, "EXCEPTION ERROR on autoMovePmDbroot: Caught unknown exception!", LOG_TYPE_ERROR); - } + if ( ( moduleName.find("pm") == 0 && !amazon && ( DBRootStorageType != "internal") ) || + ( moduleName.find("pm") == 0 && amazon && downActiveOAMModule ) || + ( moduleName.find("pm") == 0 && amazon && AmazonPMFailover == "y") ) { + try { + log.writeLog(__LINE__, "Call autoMovePmDbroot", LOG_TYPE_DEBUG); + oam.autoMovePmDbroot(moduleName); + log.writeLog(__LINE__, "autoMovePmDbroot success", LOG_TYPE_DEBUG); + //distribute config file + processManager.distributeConfigFile("system"); + } + catch (exception& ex) + { + string error = ex.what(); + log.writeLog(__LINE__, "EXCEPTION ERROR on autoMovePmDbroot: " + error, LOG_TYPE_DEBUG); + } + catch(...) + { + log.writeLog(__LINE__, "EXCEPTION ERROR on autoMovePmDbroot: Caught unknown exception!", LOG_TYPE_ERROR); } } @@ -1864,7 +1864,9 @@ void pingDeviceThread() processManager.removeModule(devicenetworklist, false); // if pm, move dbroots to other pms - if( moduleName.find("pm") == 0 ) { + if ( ( moduleName.find("pm") == 0 && !amazon && ( DBRootStorageType != "internal") ) || + ( moduleName.find("pm") == 0 && amazon && downActiveOAMModule ) || + ( moduleName.find("pm") == 0 && amazon && AmazonPMFailover == "y") ) { try { log.writeLog(__LINE__, "Call autoMovePmDbroot", LOG_TYPE_DEBUG); oam.autoMovePmDbroot(moduleName); diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index db44342ea..6743a04ae 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -55,6 +55,7 @@ extern bool HDFS; extern string localHostName; extern string PMwithUM; extern string AmazonPMFailover; +extern string DBRootStorageType; typedef map moduleList; extern moduleList moduleInfoList; @@ -8442,14 +8443,6 @@ int ProcessManager::switchParentOAMModule(std::string newActiveModuleName) log.writeLog(__LINE__, "switchParentOAMModule Function Started", LOG_TYPE_DEBUG); - string DBRootStorageType = "internal"; - { - try{ - oam.getSystemConfig("DBRootStorageType", DBRootStorageType); - } - catch(...) {} - } - if ( DBRootStorageType == "internal" && GlusterConfig == "n") { log.writeLog(__LINE__, "ERROR: DBRootStorageType = internal", LOG_TYPE_ERROR); pthread_mutex_unlock(&THREAD_LOCK); @@ -8735,15 +8728,6 @@ int ProcessManager::OAMParentModuleChange() log.writeLog(__LINE__, "EXCEPTION ERROR on getSystemConfig: Caught unknown exception!", LOG_TYPE_ERROR); } - // dbroot storage type, do different failover if internal - string DBRootStorageType = "internal"; - { - try{ - oam.getSystemConfig("DBRootStorageType", DBRootStorageType); - } - catch(...) {} - } - string cmdLine = "ping "; string cmdOption = " -c 1 -w 5 >> /dev/null"; string cmd; From 1b43cc8d4ee18819972e0a69e04c485cbe12bfb9 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 20 Jul 2017 17:27:23 -0500 Subject: [PATCH 110/185] MCOL-814 - amazon chnages for failover and query testing --- oam/install_scripts/columnstore | 2 +- oamapps/postConfigure/postConfigure.cpp | 2 +- procmgr/main.cpp | 48 +++++++++++++++++++------ procmgr/processmanager.cpp | 7 ---- procmon/processmonitor.cpp | 4 +-- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/oam/install_scripts/columnstore b/oam/install_scripts/columnstore index f4fc48157..8978afd61 100644 --- a/oam/install_scripts/columnstore +++ b/oam/install_scripts/columnstore @@ -90,7 +90,7 @@ start() { exit 1 fi fi - #checkInstallSetup + checkInstallSetup CoreFileFlag=`$InstallDir/bin/getConfig -c $InstallDir/etc/Columnstore.xml Installation CoreFileFlag` if [ $CoreFileFlag = "y" ]; then diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 590bbafd9..b858f94b3 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -4886,7 +4886,7 @@ bool copyFstab(string moduleName) if ( rootUser) cmd = "/bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; else - cmd = "/sudo bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; + cmd = "sudo /bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; system(cmd.c_str()); diff --git a/procmgr/main.cpp b/procmgr/main.cpp index fe00412ba..8281068d5 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -1261,6 +1261,9 @@ void pingDeviceThread() break; //set query system state not ready + BRM::DBRM dbrm; + dbrm.setSystemQueryReady(false); + processManager.setQuerySystemState(false); processManager.setSystemState(oam::BUSY_INIT); @@ -1276,9 +1279,6 @@ void pingDeviceThread() //send notification oam.sendDeviceNotification(config.moduleName(), MODULE_UP); - //set module to enable state - processManager.enableModule(moduleName, oam::AUTO_OFFLINE); - int status; // if shared pm, move dbroots back to pm @@ -1289,6 +1289,9 @@ void pingDeviceThread() //restart to get the versionbuffer files closed so it can be unmounted processManager.restartProcessType("WriteEngineServer", moduleName); + //set module to enable state + processManager.enableModule(moduleName, oam::AUTO_OFFLINE); + downActiveOAMModule = false; int retry; for ( retry = 0 ; retry < 5 ; retry++ ) @@ -1380,6 +1383,9 @@ void pingDeviceThread() break; } } + else + //set module to enable state + processManager.enableModule(moduleName, oam::AUTO_OFFLINE); //restart module processes int retry = 0; @@ -1480,14 +1486,6 @@ void pingDeviceThread() continue; } - //call dbrm control, need to resume before start so the getdbrmfiles halt doesn't hang - oam.dbrmctl("reload"); - log.writeLog(__LINE__, "'dbrmctl reload' done", LOG_TYPE_DEBUG); - - // resume the dbrm - oam.dbrmctl("resume"); - log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); - // next, startmodule status = processManager.startModule(moduleName, oam::FORCEFUL, oam::AUTO_OFFLINE); if ( status == oam::API_SUCCESS ) @@ -1502,6 +1500,14 @@ void pingDeviceThread() if ( retry < ModuleProcMonWaitCount ) { // module successfully started + //call dbrm control, need to resume before start so the getdbrmfiles halt doesn't hang + oam.dbrmctl("reload"); + log.writeLog(__LINE__, "'dbrmctl reload' done", LOG_TYPE_DEBUG); + + // resume the dbrm + oam.dbrmctl("resume"); + log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); + //distribute config file processManager.distributeConfigFile("system"); sleep(1); @@ -1543,6 +1549,9 @@ void pingDeviceThread() processManager.restartProcessType("DMLProc", moduleName); } + //enable query stats + dbrm.setSystemQueryReady(true); + //set query system state ready processManager.setQuerySystemState(true); @@ -1600,6 +1609,9 @@ void pingDeviceThread() else processManager.setSystemState(oam::ACTIVE); + //enable query stats + dbrm.setSystemQueryReady(true); + //set query system state ready processManager.setQuerySystemState(true); @@ -1638,8 +1650,13 @@ void pingDeviceThread() log.writeLog(__LINE__, "module is down: " + moduleName, LOG_TYPE_CRITICAL); //set query system state not ready + BRM::DBRM dbrm; + dbrm.setSystemQueryReady(false); + processManager.setQuerySystemState(false); + processManager.setSystemState(oam::BUSY_INIT); + processManager.reinitProcessType("cpimport"); // halt the dbrm @@ -1888,6 +1905,9 @@ void pingDeviceThread() //set recycle process processManager.recycleProcess(moduleName); + //enable query stats + dbrm.setSystemQueryReady(true); + //set query system state ready processManager.setQuerySystemState(true); @@ -1902,6 +1922,9 @@ void pingDeviceThread() oam.dbrmctl("resume"); log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); + //enable query stats + dbrm.setSystemQueryReady(true); + //set query system state ready processManager.setQuerySystemState(true); } @@ -1915,6 +1938,9 @@ void pingDeviceThread() //set recycle process processManager.recycleProcess(moduleName); + //enable query stats + dbrm.setSystemQueryReady(true); + //set query system state ready processManager.setQuerySystemState(true); diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index d0f4ff385..b83410e16 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -2945,15 +2945,8 @@ void processMSG(messageqcpp::IOSocket* cfIos) msg >> moduleName; - oam.dbrmctl("halt"); - log.writeLog(__LINE__, "'dbrmctl halt' done", LOG_TYPE_DEBUG); - int ret = processManager.getDBRMData(fIos, moduleName); - oam.dbrmctl("resume"); - log.writeLog(__LINE__, "'dbrmctl resume' done", LOG_TYPE_DEBUG); - - if ( ret == oam::API_SUCCESS ) log.writeLog(__LINE__, "Get DBRM Data Files Completed"); else diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 8da3a6734..e0bcf9a66 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -594,7 +594,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO log.writeLog(__LINE__, "START: process already active " + processName); //Inform Process Manager that Process restart - processRestarted(processName); + //processRestarted(processName); ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) START; @@ -693,7 +693,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO } //Inform Process Manager that Process restart - processRestarted(processName); + //processRestarted(processName); ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) RESTART; From a5132982ae20d7ea33307fc75a6e9616abac4060 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Thu, 20 Jul 2017 18:09:17 -0700 Subject: [PATCH 111/185] MCOL-821 : update udf examples and doc to be more columnstore appropriate --- utils/udfsdk/CMakeLists.txt | 2 +- utils/udfsdk/README.txt | 39 +++++------ utils/udfsdk/udfmysql.cpp | 28 ++++---- utils/udfsdk/{udfinfinidb.cpp => udfsdk.cpp} | 70 ++++++++++---------- utils/udfsdk/udfsdk.h | 54 +++++++-------- 5 files changed, 95 insertions(+), 98 deletions(-) rename utils/udfsdk/{udfinfinidb.cpp => udfsdk.cpp} (85%) diff --git a/utils/udfsdk/CMakeLists.txt b/utils/udfsdk/CMakeLists.txt index 5e4428cd9..809140c7f 100644 --- a/utils/udfsdk/CMakeLists.txt +++ b/utils/udfsdk/CMakeLists.txt @@ -4,7 +4,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ########### next target ############### -set(udfsdk_LIB_SRCS udfinfinidb.cpp) +set(udfsdk_LIB_SRCS udfsdk.cpp) add_definitions(-DMYSQL_DYNAMIC_PLUGIN) diff --git a/utils/udfsdk/README.txt b/utils/udfsdk/README.txt index 3b72ec2f0..83497ca46 100644 --- a/utils/udfsdk/README.txt +++ b/utils/udfsdk/README.txt @@ -1,26 +1,23 @@ -How to use the InfiniDB UDF SDK +How to use the ColumnStore UDF SDK -Make sure you have a working GCC C++ compiler system, version 4.1.2 or later. You -also must have the libxml2-devel package installed. -Obtain the InfiniDB source distribution for your version of InfiniDB -from github.com. -Ideally, the machine you are compiling on and deploying on are the same machine. If this -is not possible, they must have the same InfiniDB software installation. - -Unpack the source tar file +Obtain the MariaDB columnstore source code from https://github.com/mariadb-corporation/mariadb-columnstore-server +and follow the pre-requisite and build instructions. Go into the utils/udfsdk directory. -At this point you can use the idb_add() function template in udfinfinidb.cpp and udfmysql.cpp +At this point you can use the MCS_add() function template in udfsdk.cpp and udfmysql.cpp files to create your own function or just try that function as is. -Make the library -Stop InfiniDB -Copy the libudf_mysql.so.1.0.0 and libudfsdk.so.1.0.0 file to /usr/local/mariadb/columnstore/lib on -every InfiniDB node -Start InfiniDB -In the directory /usr/local/mariadb/columnstore/mysql/lib64/mysql/plugin create a symbolic link called -libudf_msql.so to the file /usr/local/mariadb/columnstore/lib/libudf_msql.so.1.0.0 -In the mysql client add the function (e.g. "create function idb_add returns integer soname -'libudf_msql.so';") -You should now be able to use the idb_add() function in the select and/or where clauses -of SQL statements. +- Make the library + $ make +- Copy the libudf_mysql.so.1.0.0 and libudfsdk.so.1.0.0 file to /usr/local/mariadb/columnstore/lib on + every columnstore node. + $ sudo cp libudf_mysql.so.1.0.0 libudfsdk.so.1.0.0 /usr/local/mariadb/columnstore/lib/ +- Restart ColumnStore + $ mcsadmin restartsystem y +- Using the mcsmysql client add the user defined function, e.g, + $ mcsmysql + > create function mcs_add returns integer soname 'libudf_mysql.so'; + > create function mcs_isnull returns string soname 'libudf_mysql.so'; + +You should now be able to use the mcs_add(arg1, arg2) and mcs_isnull(arg) functions in the select and/or where clauses +of SQL statements. \ No newline at end of file diff --git a/utils/udfsdk/udfmysql.cpp b/utils/udfsdk/udfmysql.cpp index 4d14b2479..e6707278b 100644 --- a/utils/udfsdk/udfmysql.cpp +++ b/utils/udfsdk/udfmysql.cpp @@ -82,8 +82,8 @@ inline string cvtArgToString(int t, const char* v) } /**************************************************************************** - * UDF function interface for MySQL connector to recognize is defined in - * this section. MySQL's UDF function creation guideline needs to be followed. + * UDF function interface for MariaDB connector to recognize is defined in + * this section. MariaDB's UDF function creation guideline needs to be followed. * * Three interface need to be defined on the connector for each UDF function. * @@ -91,12 +91,12 @@ inline string cvtArgToString(int t, const char* v) * the input. * XXX_deinit: To clean up the memory. * XXX: The function implementation. - * Detailed instruction can be found at MySQL source directory: + * Detailed instruction can be found at MariaDB source directory: * ~/sql/udf_example.cc. * * Please note that the implementation of the function defined on the connector * will only be called when all the input arguments are constant. e.g., - * idb_add(2,3). That way, the function does not run in a distributed fashion + * mcs_add(2,3). That way, the function does not run in a distributed fashion * and could be slow. If there is a need for the UDF function to run with * pure constant input, then one needs to put a implementation in the XXX * body, which is very similar to the ones in getXXXval API. If there's no @@ -106,16 +106,16 @@ inline string cvtArgToString(int t, const char* v) extern "C" { /** - * IDB_ADD connector stub + * MCS_ADD connector stub */ #ifdef _MSC_VER __declspec(dllexport) #endif -my_bool idb_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +my_bool mcs_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { if (args->arg_count != 2) { - strcpy(message,"idb_add() requires two argument"); + strcpy(message,"mcs_add() requires two argument"); return 1; } @@ -125,14 +125,14 @@ my_bool idb_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) #ifdef _MSC_VER __declspec(dllexport) #endif -void idb_add_deinit(UDF_INIT* initid) +void mcs_add_deinit(UDF_INIT* initid) { } #ifdef _MSC_VER __declspec(dllexport) #endif -double idb_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +double mcs_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { double op1, op2; @@ -143,17 +143,17 @@ double idb_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) } /** - * IDB_ISNULL connector stub + * MCS_ISNULL connector stub */ #ifdef _MSC_VER __declspec(dllexport) #endif -my_bool idb_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +my_bool mcs_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { if (args->arg_count != 1) { - strcpy(message,"idb_isnull() requires one argument"); + strcpy(message,"mcs_isnull() requires one argument"); return 1; } @@ -163,14 +163,14 @@ my_bool idb_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) #ifdef _MSC_VER __declspec(dllexport) #endif -void idb_isnull_deinit(UDF_INIT* initid) +void mcs_isnull_deinit(UDF_INIT* initid) { } #ifdef _MSC_VER __declspec(dllexport) #endif -long long idb_isnull(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +long long mcs_isnull(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { return 0; } diff --git a/utils/udfsdk/udfinfinidb.cpp b/utils/udfsdk/udfsdk.cpp similarity index 85% rename from utils/udfsdk/udfinfinidb.cpp rename to utils/udfsdk/udfsdk.cpp index 892979bda..c341680d3 100644 --- a/utils/udfsdk/udfinfinidb.cpp +++ b/utils/udfsdk/udfsdk.cpp @@ -53,9 +53,9 @@ UDFSDK::~UDFSDK() /** * All UDF functions should be registered in the function map. They will be - * picked up by the InfiniDB F&E framework when the servers are started. - * That will make sure the UDF functions runs distributedly in InfiniDB - * engines just like the internal InfiniDB functions. + * picked up by the MariaDB ColumnStore F&E framework when the servers are started. + * That will make sure the UDF functions runs distributedly in ColumnStore + * engines just like the internal ColumnStore functions. */ FuncMap UDFSDK::UDFMap() const { @@ -64,23 +64,23 @@ FuncMap UDFSDK::UDFMap() const // first: function name // second: Function pointer // please use lower case for the function name. Because the names might be - // case-insensitive in MySQL depending on the setting. In such case, + // case-insensitive in MariaDB depending on the setting. In such case, // the function names passed to the interface is always in lower case. - fm["idb_add"] = new IDB_add(); - fm["idb_isnull"] = new IDB_isnull(); + fm["mcs_add"] = new MCS_add(); + fm["mcs_isnull"] = new MCS_isnull(); return fm; } /*************************************************************************** - * IDB_ADD implementation + * MCS_ADD implementation * * OperationType() definition */ -CalpontSystemCatalog::ColType IDB_add::operationType (FunctionParm& fp, +CalpontSystemCatalog::ColType MCS_add::operationType (FunctionParm& fp, CalpontSystemCatalog::ColType& resultType) { - // operation type of idb_add is determined by the argument types + // operation type of MCS_add is determined by the argument types assert (fp.size() == 2); CalpontSystemCatalog::ColType rt; if (fp[0]->data()->resultType() == fp[1]->data()->resultType()) @@ -135,7 +135,7 @@ CalpontSystemCatalog::ColType IDB_add::operationType (FunctionParm& fp, * * This API is called when an double value is needed to return from the UDF function */ -double IDB_add::getDoubleVal(Row& row, +double MCS_add::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -190,7 +190,7 @@ double IDB_add::getDoubleVal(Row& row, return 0; } -float IDB_add::getFloatVal(Row& row, +float MCS_add::getFloatVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -203,11 +203,11 @@ float IDB_add::getFloatVal(Row& row, * * This API is called when an integer value is needed to return from the UDF function * - * Because the result type idb_add is double(real), all the other API can simply call + * Because the result type MCS_add is double(real), all the other API can simply call * getDoubleVal and apply the conversion. This method may not fit for all the UDF * implementation. */ -int64_t IDB_add::getIntVal(Row& row, +int64_t MCS_add::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -215,7 +215,7 @@ int64_t IDB_add::getIntVal(Row& row, return (int64_t)getDoubleVal(row, parm, isNull, op_ct); } -string IDB_add::getStrVal(Row& row, +string MCS_add::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -227,7 +227,7 @@ string IDB_add::getStrVal(Row& row, return oss.str(); } -IDB_Decimal IDB_add::getDecimalVal(Row& row, +IDB_Decimal MCS_add::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -239,26 +239,26 @@ IDB_Decimal IDB_add::getDecimalVal(Row& row, } /** - * This API should never be called for IDB_add, because the latter + * This API should never be called for MCS_add, because the latter * is not for date/datetime values addition. In such case, one can * either not implement this API and an IDB-5001 error will be thrown, * or throw a customized exception here. */ -int32_t IDB_add::getDateIntVal(Row& row, +int32_t MCS_add::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) { - throw logic_error("Invalid API called for IDB_ADD"); + throw logic_error("Invalid API called for MCS_ADD"); } /** - * This API should never be called for IDB_add, because the latter + * This API should never be called for MCS_add, because the latter * is not for date/datetime values addition. In such case, one can * either not implement this API and an IDB-5001 error will be thrown, * or throw a customized exception here. */ -int64_t IDB_add::getDatetimeIntVal(Row& row, +int64_t MCS_add::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -266,7 +266,7 @@ int64_t IDB_add::getDatetimeIntVal(Row& row, return (int64_t)getDoubleVal(row, parm, isNull, op_ct); } -bool IDB_add::getBoolVal(Row& row, +bool MCS_add::getBoolVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -275,14 +275,14 @@ bool IDB_add::getBoolVal(Row& row, } /*************************************************************************** - * IDB_ISNULL implementation + * MCS_ISNULL implementation * * OperationType() definition */ -CalpontSystemCatalog::ColType IDB_isnull::operationType (FunctionParm& fp, +CalpontSystemCatalog::ColType MCS_isnull::operationType (FunctionParm& fp, CalpontSystemCatalog::ColType& resultType) { - // operation type of idb_isnull should be the same as the argument type + // operation type of MCS_isnull should be the same as the argument type assert (fp.size() == 1); return fp[0]->data()->resultType(); } @@ -290,9 +290,9 @@ CalpontSystemCatalog::ColType IDB_isnull::operationType (FunctionParm& fp, /** * getBoolVal API definition * - * This would be the most commonly called API for idb_isnull function + * This would be the most commonly called API for MCS_isnull function */ -bool IDB_isnull::getBoolVal(Row& row, +bool MCS_isnull::getBoolVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -304,7 +304,7 @@ bool IDB_isnull::getBoolVal(Row& row, // in parameter isNull will be set if the parameter is evaluated NULL. // Please note that before this function returns, isNull should be set to // false, otherwise the result of the function would be considered NULL, - // which is not possible for idb_isnull(). + // which is not possible for MCS_isnull(). case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: parm[0]->data()->getDecimalVal(row, isNull); @@ -327,7 +327,7 @@ bool IDB_isnull::getBoolVal(Row& row, * * This API is called when a double value is needed to return from the UDF function */ -double IDB_isnull::getDoubleVal(Row& row, +double MCS_isnull::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -335,7 +335,7 @@ double IDB_isnull::getDoubleVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -float IDB_isnull::getFloatVal(Row& row, +float MCS_isnull::getFloatVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -348,11 +348,11 @@ float IDB_isnull::getFloatVal(Row& row, * * This API is called when an integer value is needed to return from the UDF function * - * Because the result type idb_add is double(real), all the other API can simply call + * Because the result type MCS_add is double(real), all the other API can simply call * getDoubleVal and apply the conversion. This method may not fit for all the UDF * implementations. */ -int64_t IDB_isnull::getIntVal(Row& row, +int64_t MCS_isnull::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -360,7 +360,7 @@ int64_t IDB_isnull::getIntVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -string IDB_isnull::getStrVal(Row& row, +string MCS_isnull::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -371,7 +371,7 @@ string IDB_isnull::getStrVal(Row& row, } -IDB_Decimal IDB_isnull::getDecimalVal(Row& row, +IDB_Decimal MCS_isnull::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -382,7 +382,7 @@ IDB_Decimal IDB_isnull::getDecimalVal(Row& row, return dec; } -int32_t IDB_isnull::getDateIntVal(Row& row, +int32_t MCS_isnull::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -390,7 +390,7 @@ int32_t IDB_isnull::getDateIntVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -int64_t IDB_isnull::getDatetimeIntVal(Row& row, +int64_t MCS_isnull::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) diff --git a/utils/udfsdk/udfsdk.h b/utils/udfsdk/udfsdk.h index 659cb837c..d472fe91e 100644 --- a/utils/udfsdk/udfsdk.h +++ b/utils/udfsdk/udfsdk.h @@ -23,7 +23,7 @@ ***********************************************************************/ /** - * InfiniDB interface for writing a user defined function (UDF). + * MariaDB ColumnStore interface for writing a user defined function (UDF). * * The basic steps are: * @@ -32,13 +32,13 @@ * 3. add the connector stub for this UDF function in udfsdk.cpp * 4. build the dynamic library libudfsdk * 5. put the library in /usr/local/mariadb/columnstore/lib of all modules - * 6. restart all the InfiniDB servers and MySQL server - * 7. notify mysqld about the new functions with the commands like: + * 6. restart MariaDB ColumnStore + * 7. Register the new functions with the commands like: * - * CREATE FUNCTION idb_add returns REAL soname 'libudfsdk.so'; - * CREATE FUNCTION idb_isnull returns BOOL soname 'libudfsdk.so'; + * CREATE FUNCTION mcs_add returns REAL soname 'libudfsdk.so'; + * CREATE FUNCTION mcs_isnull returns BOOL soname 'libudfsdk.so'; * - * The UDF functions run distributedly in the InfiniDB engine. The evaluation + * The UDF functions run distributedly in the ColumnStore engine. The evaluation * is row by row. Aggregate UDF is currently not supported. Two examples are * given in this file to demonstrate the steps that it takes to create a UDF * function. More examples can be found in utils/funcexp/func_*.cpp. @@ -78,9 +78,9 @@ private: }; /** - * Example: IDB_add (args1, args2) + * Example: MCS_add (args1, args2) * - * IDB_add takes two arguments of any data type. It returns a double result. + * MCS_add takes two arguments of any data type. It returns a double result. * * The function interface is defined here. All UDF functions are derived from * class funcexp::Func. A set of getXXXval interface APIs are declared in the @@ -90,30 +90,30 @@ private: * the function is expected to return. * * For example, given the following two queries, different APIs will be called - * to evaluate the function idb_add. + * to evaluate the function MCS_add. * - * select idb_add(int1, int2) from t1; - * getDoubleVal() is called, because the result type of idb_add is DOUBLE(real). + * select MCS_add(int1, int2) from t1; + * getDoubleVal() is called, because the result type of MCS_add is DOUBLE(real). * - * select substr(string1, int1, idb_add(int1+int2)); - * getIntVal() will be called, because idb_add() is passed as the third argument + * select substr(string1, int1, MCS_add(int1+int2)); + * getIntVal() will be called, because MCS_add() is passed as the third argument * to substr function, and an integer result is expected. * * If one API is not implemented but called for a function, IDB-5001 error will * be returned. */ -class IDB_add : public funcexp::Func +class MCS_add : public funcexp::Func { public: /* * Constructor. Pass the function name to the base constructor. */ - IDB_add() : Func("idb_add") {} + MCS_add() : Func("mcs_add") {} /* - * Destructor. IDB_add does not need to do anything here to clean up. + * Destructor. MCS_add does not need to do anything here to clean up. */ - virtual ~IDB_add() {} + virtual ~MCS_add() {} /** * Decide on the function's operation type @@ -152,7 +152,7 @@ public: * the same reference is passed to all the function argument * evaluations. One always need to know if any argument is NULL * to decide the result of the function. It's explained in detail - * in idb_isnull() function example. + * in MCS_isnull() function example. * @parm op_ct the operation type that is determined in operationType(). * */ @@ -205,7 +205,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a date result of the function. + * Returns an integer representation of a date result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -216,7 +216,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a datetime result of the function. + * Returns an integer representation of a datetime result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -228,22 +228,22 @@ public: }; /** - * Example: IDB_isnull(arg1) + * Example: MCS_isnull(arg1) * * The purpose of this example is to demostrate the NULL handling in the UDF interface */ -class IDB_isnull : public funcexp::Func +class MCS_isnull : public funcexp::Func { public: /* * Constructor. Pass the function name to the base constructor. */ - IDB_isnull() : Func("idb_isnull") {} + MCS_isnull() : Func("mcs_isnull") {} /* - * Destructor. IDB_add does not need to do anything here to clean up. + * Destructor. MCS_add does not need to do anything here to clean up. */ - virtual ~IDB_isnull() {} + virtual ~MCS_isnull() {} /** * Decide on the function's operation type @@ -301,7 +301,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a date result of the function. + * Returns an integer representation of a date result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -312,7 +312,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a datetime result of the function. + * Returns an integer representation of a datetime result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. From 93794c9c3ffd02b5907622d38a7e5af013f2b120 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 24 Jul 2017 10:09:04 -0500 Subject: [PATCH 112/185] MCOL-814 - more changes for failover query handling --- oam/install_scripts/module_installer.sh | 2 +- oamapps/postConfigure/postConfigure.cpp | 16 +++++----- procmgr/processmanager.cpp | 39 ++++++++++++------------- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 5822c4082..181112a9f 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -92,7 +92,7 @@ if [ $module = "um" ]; then echo "Setup UM Volume Mount" device=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMVolumeDeviceName$mid` mkdir -p $COLUMNSTORE_INSTALL_DIR/mysql/db > /dev/null 2>&1 - mount $device $COLUMNSTORE_INSTALL_DIR/mysql/db -t ext2 -o defaults + sudo mount $device $COLUMNSTORE_INSTALL_DIR/mysql/db -t ext2 -o noatime,nodiratime,noauto,user chown mysql:mysql -R $COLUMNSTORE_INSTALL_DIR/mysql > /dev/null 2>&1 fi fi diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index b858f94b3..5d2040807 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2052,11 +2052,6 @@ int main(int argc, char *argv[]) if( !makeRClocal(moduleType , newModuleName, IserverTypeInstall) ) cout << "makeRClocal error" << endl; - //if cloud, copy fstab in module tmp dir - if ( amazonInstall && moduleType == "pm") - if( !copyFstab(newModuleName) ) - cout << "copyFstab error" << endl; - //setup DBRM Processes if ( newModuleName == parentOAMModuleName ) sysConfig->setConfig("DBRM_Controller", "IPAddr", newModuleIPAddr); @@ -2592,6 +2587,12 @@ int main(int argc, char *argv[]) exit(1); } + //if cloud, copy fstab in module tmp dir + if ( amazonInstall) + if( !copyFstab("pm1") ) + cout << "copyFstab error" << endl; + + //check 'files per parition' with number of dbroots checkFilesPerPartion(DBRootCount, sysConfig); @@ -4883,10 +4884,7 @@ void setSystemName() bool copyFstab(string moduleName) { string cmd; - if ( rootUser) - cmd = "/bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; - else - cmd = "sudo /bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; + cmd = "/bin/cp -f /etc/fstab " + installDir + "/local/etc/" + moduleName + "/. > /dev/null 2>&1"; system(cmd.c_str()); diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index b83410e16..b6fea4c5d 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -451,7 +451,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) sysConfig->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); sysConfig->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -1281,7 +1281,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) sysConfig->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); sysConfig->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -1356,7 +1356,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) sysConfig->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); sysConfig->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -4545,7 +4545,7 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str pthread_mutex_unlock(&THREAD_LOCK); return API_FILE_OPEN_ERROR; } - log.writeLog(__LINE__, "addModule - Calpont Package found:" + calpontPackage, LOG_TYPE_DEBUG); + log.writeLog(__LINE__, "addModule - Columnstore Package found:" + calpontPackage, LOG_TYPE_DEBUG); // // Verify Host IP and Password @@ -4566,6 +4566,12 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str if (rpw != oam::UnassignedName) password = rpw; } + + if ( amazon ) { + //remove know_host which shows up if you addmodule/removemodule/addmodule + string file = homedir + "/.ssh/known_hosts"; + unlink (file.c_str()); + } listPT = devicenetworklist.begin(); for( ; listPT != devicenetworklist.end() ; listPT++) @@ -4687,13 +4693,6 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str string cmd = installDir + "/bin/remote_command.sh " + IPAddr + " " + password + " 'ls' 1 > /tmp/login_test.log"; system(cmd.c_str()); if (!oam.checkLogStatus("/tmp/login_test.log", "README")) { - //check for RSA KEY ISSUE and fix - if (oam.checkLogStatus("/tmp/login_test.log", "Offending")) { - log.writeLog(__LINE__, "addModule - login failed, Offending key issue, try fixing: " + moduleName, LOG_TYPE_DEBUG); - string file = "/tmp/login_test.log"; - oam.fixRSAkey(file); - } - log.writeLog(__LINE__, "addModule - login failed, retry login test: " + moduleName, LOG_TYPE_DEBUG); sleep(10); continue; @@ -4896,7 +4895,7 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } } - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -5263,7 +5262,7 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str string remoteHostName = (*pt1).HostName; //send start service commands - string cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/columnstore restart;" + installDir + "/mysql/mysqld-Calpont restart' 0"; + string cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/columnstore restart;" + installDir + "/mysql/mysqld-Columnstore restart' 0"; system(cmd.c_str()); log.writeLog(__LINE__, "addModule - restart columnstore service " + remoteModuleName, LOG_TYPE_DEBUG); @@ -5595,7 +5594,7 @@ int ProcessManager::removeModule(oam::DeviceNetworkList devicenetworklist, bool log.writeLog(__LINE__, "removeModule - Updated DBRoot paramaters", LOG_TYPE_DEBUG); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -5838,7 +5837,7 @@ int ProcessManager::reconfigureModule(oam::DeviceNetworkList devicenetworklist) log.writeLog(__LINE__, "reconfigureModule - Updated Process Ports", LOG_TYPE_DEBUG); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -5930,7 +5929,7 @@ int ProcessManager::reconfigureModule(oam::DeviceNetworkList devicenetworklist) log.writeLog(__LINE__, "reconfigureModule - Updated Process Ports", LOG_TYPE_DEBUG); - //update Calpont Config table + //update Columnstore Config table try { sysConfig->write(); } @@ -7581,7 +7580,7 @@ int ProcessManager::updatePMSconfig( bool check ) nicID = 1; } - //update Calpont Config table + //update Columnstore Config table try { sysConfig1->write(); pthread_mutex_unlock(&THREAD_LOCK); @@ -8022,7 +8021,7 @@ int ProcessManager::setPMProcIPs( std::string moduleName, std::string processNam /****************************************************************************************** * @brief distributeConfigFile * -* purpose: Distribute Calpont Config File to system modules +* purpose: Distribute Columnstore Config File to system modules * ******************************************************************************************/ int ProcessManager::distributeConfigFile(std::string name, std::string file) @@ -8530,7 +8529,7 @@ int ProcessManager::switchParentOAMModule(std::string newActiveModuleName) sysConfig4->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); sysConfig4->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); - //update Calpont Config table + //update Columnstore Config table try { sysConfig4->write(); } @@ -9100,7 +9099,7 @@ int ProcessManager::OAMParentModuleChange() sysConfig4->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); sysConfig4->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); - //update Calpont Config table + //update Columnstore Config table try { sysConfig4->write(); } From 655660c6af817cb7613bc4091bace8a2e05385c0 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 25 Jul 2017 11:57:16 -0500 Subject: [PATCH 113/185] add log to output status --- procmon/processmonitor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index e0bcf9a66..724650f08 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -5655,6 +5655,8 @@ bool ProcessMonitor::amazonVolumeCheck(int dbrootID) } string status = oam.getEC2VolumeStatus(volumeName); + log.writeLog(__LINE__, "amazonVolumeCheck volume status: " + status, LOG_TYPE_DEBUG); + if ( status == "attached" ) { log.writeLog(__LINE__, "amazonVolumeCheck function successfully completed, volume attached: " + volumeName, LOG_TYPE_DEBUG); return true; From 13cb37466bfa9bdbe19df01b137fcb9e09fcb21a Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 25 Jul 2017 12:58:37 -0500 Subject: [PATCH 114/185] Update README --- README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index b5545b633..1de3bd95e 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.0.8 -MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely +This is MariaDB ColumnStore 1.0.10 +MariaDB ColumnStore 1.0.10 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.25 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.0.8 is an GA release. This is the first MariaDB +MariaDB ColumnStore 1.0.10 is an GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. From 6a276600f70412fa418c63991b8429844ce26eb4 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 25 Jul 2017 12:59:11 -0500 Subject: [PATCH 115/185] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b30bf9338..b9407eb81 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.0.8 -MariaDB ColumnStore 1.0.8 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely +#MariaDB ColumnStore Storage/Execution engine 1.0.10 +MariaDB ColumnStore 1.0.10 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.25 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.0.8 is an GA release. +#MariaDB ColumnStore 1.0.10 is an GA release. This is the first MariaDB ColumnStore release. #Building From 3825ea96812bf828422853ece0be1e6dcc773e1c Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 25 Jul 2017 15:25:05 -0500 Subject: [PATCH 116/185] tweaked to correct a failing attach at startup --- oam/oamcpp/liboamcpp.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index 02c985b6a..b7384d638 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -7872,12 +7872,24 @@ namespace oam std::string Oam::getEC2VolumeStatus(std::string volumeName) { - // run script to get Volume Status - string cmd = InstallDir + "/bin/MCSVolumeCmds.sh describe " + volumeName + " > /tmp/getVolumeStatus_" + volumeName; - int ret = system(cmd.c_str()); - if (WEXITSTATUS(ret) != 0 ) - return "failed"; - + bool pass = true; + for ( int retry = 0 ; retry < 5 ; retry++ ) + { + // run script to get Volume Status + string cmd = InstallDir + "/bin/MCSVolumeCmds.sh describe " + volumeName + " > /tmp/getVolumeStatus_" + volumeName; + int ret = system(cmd.c_str()); + if (WEXITSTATUS(ret) == 0 ) + break; + else + { + sleep(1); + pass = false; + } + } + + if (!pass) + return "failed"; + // get status string status; string file = "/tmp/getVolumeStatus_" + volumeName; From b990a26996bb76d55935fccffe99799135d59414 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 26 Jul 2017 11:50:26 +0100 Subject: [PATCH 117/185] MCOL-834 Cleanup BPP threads on ExeMgr disconnect If ExeMgr disconnects (such as a crash) whilst queries are being executed some BPP threads get orphaned. This patch tracks the BPP usage for each threads and cleans up appropriately. --- primitives/primproc/primitiveserver.cpp | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/primitives/primproc/primitiveserver.cpp b/primitives/primproc/primitiveserver.cpp index deaae576e..f9597d27e 100644 --- a/primitives/primproc/primitiveserver.cpp +++ b/primitives/primproc/primitiveserver.cpp @@ -1145,6 +1145,30 @@ struct BPPHandler { BPPHandler(PrimitiveServer* ps) : fPrimitiveServerPtr(ps) { } + // Keep a list of keys so that if connection fails we don't leave BPP + // threads lying around + std::vector bppKeys; + std::vector::iterator bppKeysIt; + + ~BPPHandler() + { + for (bppKeysIt = bppKeys.begin() ; bppKeysIt != bppKeys.end(); ++bppKeysIt) + { + uint32_t key = *bppKeysIt; + BPPMap::iterator it; + + mutex::scoped_lock scoped(bppLock); + it = bppMap.find(key); + if (it != bppMap.end()) { + it->second->abort(); + bppMap.erase(it); + } + scoped.unlock(); + fPrimitiveServerPtr->getProcessorThreadPool()->removeJobs(key); + OOBPool->removeJobs(key); + } + } + struct BPPHandlerFunctor : public PriorityThreadPool::Functor { BPPHandlerFunctor(boost::shared_ptr r, SBS b) : bs(b) { @@ -1200,6 +1224,10 @@ struct BPPHandler bs.advance(sizeof(ISMPacketHeader)); bs >> key; + bppKeysIt = std::find(bppKeys.begin(), bppKeys.end(), key); + if (bppKeysIt != bppKeys.end()) { + bppKeys.erase(bppKeysIt); + } mutex::scoped_lock scoped(bppLock); it = bppMap.find(key); if (it != bppMap.end()) { @@ -1273,6 +1301,7 @@ struct BPPHandler } } key = bpp->getUniqueID(); + bppKeys.push_back(key); mutex::scoped_lock scoped(bppLock); bool newInsert; newInsert = bppMap.insert(pair(key, bppv)).second; @@ -1403,6 +1432,11 @@ struct BPPHandler mutex::scoped_lock lk(djLock); mutex::scoped_lock scoped(bppLock); + bppKeysIt = std::find(bppKeys.begin(), bppKeys.end(), uniqueID); + if (bppKeysIt != bppKeys.end()) { + bppKeys.erase(bppKeysIt); + } + it = bppMap.find(uniqueID); if (it != bppMap.end()) { boost::shared_ptr bppv = it->second; From 2aacb56bc608d5315231e8ab9c705a974727a0cd Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 27 Jul 2017 14:59:10 +0100 Subject: [PATCH 118/185] MCOL-830 Allow cross engine to work with UTF8 UTF8 characters just showed as question marks. This patch makes them retrieve correctly. --- dbcon/joblist/crossenginestep.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dbcon/joblist/crossenginestep.cpp b/dbcon/joblist/crossenginestep.cpp index 505b17de4..4026255a1 100644 --- a/dbcon/joblist/crossenginestep.cpp +++ b/dbcon/joblist/crossenginestep.cpp @@ -103,7 +103,13 @@ int DrizzleMySQL::init(const char* h, unsigned int p, const char* u, const char* { ret = drizzle_con_connect(fDrzcp); if (ret != 0) + { fErrStr = "fatal error in drizzle_con_connect()"; + } + else + { + drizzle_query_str(fDrzcp, NULL, "SET NAMES UTF8;", NULL); + } } else { From 668133d9157d905f4436607fb01af119d3197fb6 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 27 Jul 2017 16:13:01 +0100 Subject: [PATCH 119/185] MCOL-812 Escape cross engine filters Quote marks in cross engine where conditions need to be escaped --- dbcon/execplan/simplefilter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dbcon/execplan/simplefilter.cpp b/dbcon/execplan/simplefilter.cpp index 692da7513..646a8f6eb 100644 --- a/dbcon/execplan/simplefilter.cpp +++ b/dbcon/execplan/simplefilter.cpp @@ -26,6 +26,7 @@ #include #include using namespace std; +#include #include "returnedcolumn.h" #include "constantcolumn.h" @@ -179,7 +180,7 @@ const string SimpleFilter::data() const fRhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY || fRhs->resultType().colDataType == CalpontSystemCatalog::DATE || fRhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)) - rhs = "'" + fRhs->data() + "'"; + rhs = "'" + boost::replace_all_copy(fRhs->data(), "'", "\\'") + "'"; else rhs = fRhs->data(); if (dynamic_cast(fLhs) && @@ -188,7 +189,7 @@ const string SimpleFilter::data() const fLhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY || fLhs->resultType().colDataType == CalpontSystemCatalog::DATE || fLhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)) - lhs = "'" + fLhs->data() + "'"; + lhs = "'" + boost::replace_all_copy(fRhs->data(), "'", "\\'") + "'"; else lhs = fLhs->data(); return lhs + " " + fOp->data() + " " + rhs; From b39a8c2fbc8e740c017fb15b100030ac3424dd5a Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 27 Jul 2017 16:26:34 +0100 Subject: [PATCH 120/185] MCOL-812 fix typo --- dbcon/execplan/simplefilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/execplan/simplefilter.cpp b/dbcon/execplan/simplefilter.cpp index 646a8f6eb..54251f3b8 100644 --- a/dbcon/execplan/simplefilter.cpp +++ b/dbcon/execplan/simplefilter.cpp @@ -189,7 +189,7 @@ const string SimpleFilter::data() const fLhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY || fLhs->resultType().colDataType == CalpontSystemCatalog::DATE || fLhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)) - lhs = "'" + boost::replace_all_copy(fRhs->data(), "'", "\\'") + "'"; + lhs = "'" + boost::replace_all_copy(fLhs->data(), "'", "\\'") + "'"; else lhs = fLhs->data(); return lhs + " " + fOp->data() + " " + rhs; From 4bd6e1959ea93ae41f8076be7eead256612ffd1e Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 27 Jul 2017 11:13:48 -0500 Subject: [PATCH 121/185] chmod of logrotate file --- oam/install_scripts/post-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index bb8edf5c8..fbff1c6a3 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -234,7 +234,7 @@ fi # install Columnstore Log Rotate File $SUDO cp $installdir/bin/columnstoreLogRotate /etc/logrotate.d/columnstore > /dev/null 2>&1 -$SUDO chmod 666 /etc/logrotate.d/columnstore +$SUDO chmod 644 /etc/logrotate.d/columnstore #check if MariaDB Columnstore system logging was setup cat /tmp/syslog_install.log | grep 'No System Logging' >/dev/null 2>&1 From be7b83f89a7121ce12329de7fb8698b81608efba Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 27 Jul 2017 23:22:45 +0100 Subject: [PATCH 122/185] MCOL-834 Fix crashes introduced * Fix race condition in cleanup * Fix mutex cleanup crash --- primitives/primproc/batchprimitiveprocessor.cpp | 2 ++ primitives/primproc/batchprimitiveprocessor.h | 2 +- primitives/primproc/primitiveserver.cpp | 15 ++++++++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/primitives/primproc/batchprimitiveprocessor.cpp b/primitives/primproc/batchprimitiveprocessor.cpp index f934e5e2a..ab2d5cd7b 100644 --- a/primitives/primproc/batchprimitiveprocessor.cpp +++ b/primitives/primproc/batchprimitiveprocessor.cpp @@ -1765,6 +1765,8 @@ int BatchPrimitiveProcessor::operator()() vssCache.clear(); #ifndef __FreeBSD__ + if (sendThread->aborted()) + objLock.try_lock(); objLock.unlock(); #endif freeLargeBuffers(); diff --git a/primitives/primproc/batchprimitiveprocessor.h b/primitives/primproc/batchprimitiveprocessor.h index c7d8d815c..c57479ef9 100644 --- a/primitives/primproc/batchprimitiveprocessor.h +++ b/primitives/primproc/batchprimitiveprocessor.h @@ -121,7 +121,7 @@ class BatchPrimitiveProcessor // these two functions are used by BPPV to create BPP instances // on demand. TRY not to use unlock() for anything else. - void unlock() { objLock.unlock(); } + void unlock() { objLock.try_lock(); objLock.unlock(); } bool hasJoin() { return doJoin; } private: BatchPrimitiveProcessor(); diff --git a/primitives/primproc/primitiveserver.cpp b/primitives/primproc/primitiveserver.cpp index f9597d27e..c8719352e 100644 --- a/primitives/primproc/primitiveserver.cpp +++ b/primitives/primproc/primitiveserver.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef _MSC_VER #include typedef int pthread_t; @@ -1152,21 +1153,21 @@ struct BPPHandler ~BPPHandler() { + mutex::scoped_lock scoped(bppLock); for (bppKeysIt = bppKeys.begin() ; bppKeysIt != bppKeys.end(); ++bppKeysIt) { uint32_t key = *bppKeysIt; BPPMap::iterator it; - mutex::scoped_lock scoped(bppLock); it = bppMap.find(key); if (it != bppMap.end()) { it->second->abort(); bppMap.erase(it); } - scoped.unlock(); fPrimitiveServerPtr->getProcessorThreadPool()->removeJobs(key); OOBPool->removeJobs(key); } + scoped.unlock(); } struct BPPHandlerFunctor : public PriorityThreadPool::Functor { @@ -1224,11 +1225,11 @@ struct BPPHandler bs.advance(sizeof(ISMPacketHeader)); bs >> key; + mutex::scoped_lock scoped(bppLock); bppKeysIt = std::find(bppKeys.begin(), bppKeys.end(), key); if (bppKeysIt != bppKeys.end()) { bppKeys.erase(bppKeysIt); } - mutex::scoped_lock scoped(bppLock); it = bppMap.find(key); if (it != bppMap.end()) { it->second->abort(); @@ -1300,9 +1301,9 @@ struct BPPHandler bppv->add(dup); } } - key = bpp->getUniqueID(); + mutex::scoped_lock scoped(bppLock); + key = bpp->getUniqueID(); bppKeys.push_back(key); - mutex::scoped_lock scoped(bppLock); bool newInsert; newInsert = bppMap.insert(pair(key, bppv)).second; //cout << "creating BPP # " << key << endl; @@ -2209,6 +2210,10 @@ boost::shared_ptr BPPV::next() void BPPV::abort() { sendThread->abort(); + BOOST_FOREACH( boost::shared_ptr bpp, v ) + { + bpp->unlock(); + } } bool BPPV::aborted() From 73d1dcde4a0ce50cd7c8872794637b391efaffb9 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 3 Aug 2017 09:46:36 -0500 Subject: [PATCH 123/185] MCOL-850 --- VERSION | 2 +- oam/oamcpp/liboamcpp.cpp | 45 +++++++++++++++++------ oam/oamcpp/liboamcpp.h | 1 + oamapps/serverMonitor/cpuMonitor.cpp | 12 +++---- oamapps/serverMonitor/diskMonitor.cpp | 12 +++---- oamapps/serverMonitor/main.cpp | 24 +++++++++++++ oamapps/serverMonitor/memoryMonitor.cpp | 24 ++++++------- oamapps/serverMonitor/serverMonitor.h | 6 ++++ procmgr/main.cpp | 48 ++++++++++++++++++------- procmgr/processmanager.cpp | 18 ++++++++-- 10 files changed, 141 insertions(+), 51 deletions(-) diff --git a/VERSION b/VERSION index e737f4599..91d2f876b 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 COLUMNSTORE_VERSION_PATCH=10 -COLUMNSTORE_VERSION_RELEASE=1 +COLUMNSTORE_VERSION_RELEASE=2 diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index b7384d638..aa8dd4804 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -2536,25 +2536,48 @@ namespace oam Oam::getAlarmConfig(alarmid, name, returnValue); - // only allow user to change these levels - if ( name != "Threshold" && - name != "Occurrences" && - name != "LastIssueTime" ) + // only allow user to change these levels + if ( name != "Threshold" && + name != "Occurrences" && + name != "LastIssueTime" ) exceptionControl("setAlarmConfig", API_READONLY_PARAMETER); + string fileName = AlarmConfigFile; + + int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0644); + + // Aquire an exclusive lock + if (flock(fd,LOCK_EX) == -1) { + throw runtime_error ("Lock file error: " + fileName); + } + // write parameter to disk Config* alaConfig = Config::makeConfig(AlarmConfigFile.c_str()); alaConfig->setConfig(Section, name, value); - try + + try + { + alaConfig->write(); + } + catch(...) + { + // Release lock + if (flock(fd,LOCK_UN)==-1) { - alaConfig->write(); - } - catch(...) - { - exceptionControl("setAlarmConfig", API_FAILURE); + throw runtime_error ("Release lock file error: " + fileName); } + exceptionControl("setAlarmConfig", API_FAILURE); + } + + // Release lock + if (flock(fd,LOCK_UN)==-1) + { + throw runtime_error ("Release lock file error: " + fileName); + } + + close(fd); } /******************************************************************** @@ -6967,7 +6990,7 @@ namespace oam //current amazon max dbroot id support = 190; string PMdeviceName = "/dev/sd"; - string deviceLetter[] = {"g","h","i","j","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","end"}; + string deviceLetter[] = {"g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","end"}; /*************************************************************************** * diff --git a/oam/oamcpp/liboamcpp.h b/oam/oamcpp/liboamcpp.h index 5f4d7f7a7..78f24f6ed 100644 --- a/oam/oamcpp/liboamcpp.h +++ b/oam/oamcpp/liboamcpp.h @@ -38,6 +38,7 @@ #include #endif #include +#include #include "bytestream.h" #include "configcpp.h" diff --git a/oamapps/serverMonitor/cpuMonitor.cpp b/oamapps/serverMonitor/cpuMonitor.cpp index f469abac4..a03d88433 100644 --- a/oamapps/serverMonitor/cpuMonitor.cpp +++ b/oamapps/serverMonitor/cpuMonitor.cpp @@ -333,26 +333,26 @@ void ServerMonitor::checkCPUAlarm(string alarmItem, ALARMS alarmID) switch (alarmID) { case ALARM_NONE: // clear all alarms set if any found - if ( oam.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_HIGH); - if ( oam.checkActiveAlarm(CPU_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_MED); - if ( oam.checkActiveAlarm(CPU_USAGE_LOW, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_LOW, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_LOW); break; case CPU_USAGE_LOW: // clear high and medium alarms set if any found - if ( oam.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_HIGH); - if ( oam.checkActiveAlarm(CPU_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_MED); break; case CPU_USAGE_MED: // clear high alarms set if any found - if ( oam.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(CPU_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, CPU_USAGE_HIGH); break; diff --git a/oamapps/serverMonitor/diskMonitor.cpp b/oamapps/serverMonitor/diskMonitor.cpp index 8264c82e3..4fe5e6f09 100644 --- a/oamapps/serverMonitor/diskMonitor.cpp +++ b/oamapps/serverMonitor/diskMonitor.cpp @@ -645,26 +645,26 @@ void ServerMonitor::checkDiskAlarm(string alarmItem, ALARMS alarmID) switch (alarmID) { case ALARM_NONE: // clear all alarms set if any found - if ( oam.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_HIGH); - if ( oam.checkActiveAlarm(DISK_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_MED); - if ( oam.checkActiveAlarm(DISK_USAGE_LOW, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_LOW, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_LOW); break; case DISK_USAGE_LOW: // clear high and medium alarms set if any found - if ( oam.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_HIGH); - if ( oam.checkActiveAlarm(DISK_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_MED); break; case DISK_USAGE_MED: // clear high alarms set if any found - if ( oam.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(DISK_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, DISK_USAGE_HIGH); break; diff --git a/oamapps/serverMonitor/main.cpp b/oamapps/serverMonitor/main.cpp index 3d51a067a..10903d6a4 100644 --- a/oamapps/serverMonitor/main.cpp +++ b/oamapps/serverMonitor/main.cpp @@ -291,3 +291,27 @@ int main (int argc, char** argv) return 0; } +// common functions + +// +// Check Active alarms +// +// Use a mutex to limit the number of calls +// + +pthread_mutex_t THREAD_LOCK; + + +bool ServerMonitor::checkActiveAlarm(const int alarmid, const std::string moduleName, const std::string deviceName) +{ + Oam oam; + + pthread_mutex_lock(&THREAD_LOCK); + + bool status = oam.checkActiveAlarm(alarmid, moduleName, deviceName); + + pthread_mutex_unlock(&THREAD_LOCK); + + return status; +} + diff --git a/oamapps/serverMonitor/memoryMonitor.cpp b/oamapps/serverMonitor/memoryMonitor.cpp index a1de4540f..2ada69022 100644 --- a/oamapps/serverMonitor/memoryMonitor.cpp +++ b/oamapps/serverMonitor/memoryMonitor.cpp @@ -289,26 +289,26 @@ void ServerMonitor::checkMemoryAlarm(string alarmItem, ALARMS alarmID) switch (alarmID) { case ALARM_NONE: // clear all alarms set if any found - if ( oam.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_HIGH); - if ( oam.checkActiveAlarm(MEMORY_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_MED); - if ( oam.checkActiveAlarm(MEMORY_USAGE_LOW, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_LOW, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_LOW); break; case MEMORY_USAGE_LOW: // clear high and medium alarms set if any found - if ( oam.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_HIGH); - if ( oam.checkActiveAlarm(MEMORY_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_MED); break; case MEMORY_USAGE_MED: // clear high alarms set if any found - if ( oam.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(MEMORY_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, MEMORY_USAGE_HIGH); break; @@ -342,26 +342,26 @@ void ServerMonitor::checkSwapAlarm(string alarmItem, ALARMS alarmID) switch (alarmID) { case ALARM_NONE: // clear all alarms set if any found - if ( oam.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_HIGH); - if ( oam.checkActiveAlarm(SWAP_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_MED); - if ( oam.checkActiveAlarm(SWAP_USAGE_LOW, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_LOW, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_LOW); break; case SWAP_USAGE_LOW: // clear high and medium alarms set if any found - if ( oam.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_HIGH); - if ( oam.checkActiveAlarm(SWAP_USAGE_MED, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_MED, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_MED); break; case SWAP_USAGE_MED: // clear high alarms set if any found - if ( oam.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) + if ( serverMonitor.checkActiveAlarm(SWAP_USAGE_HIGH, serverName, alarmItem) ) // alarm set, clear it clearAlarm(alarmItem, SWAP_USAGE_HIGH); break; diff --git a/oamapps/serverMonitor/serverMonitor.h b/oamapps/serverMonitor/serverMonitor.h index 1ff947589..4c1a1b37c 100644 --- a/oamapps/serverMonitor/serverMonitor.h +++ b/oamapps/serverMonitor/serverMonitor.h @@ -235,6 +235,12 @@ public: * @brief db health check */ int healthCheck(bool action = true); + + /** + * @brief Check Active Alarm + */ + bool checkActiveAlarm(const int alarmid, const std::string moduleName, const std::string deviceName); + }; // end of class diff --git a/procmgr/main.cpp b/procmgr/main.cpp index 8281068d5..8f353eeed 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -59,6 +59,7 @@ string localHostName; string PMwithUM = "n"; string MySQLRep = "n"; string DBRootStorageType = "internal"; +int requestCount; // pushing the ACTIVE_ALARMS_FILE to all nodes every 10 seconds. const int ACTIVE_ALARMS_PUSHING_INTERVAL = 10; @@ -421,10 +422,21 @@ static void messageThread(Configuration config) { } + // Number of Max requests +// int ProcessManagerRequest = 10; + +// try { +// oam.getSystemConfig("ProcessManagerRequest", ProcessManagerRequest); +// } +// catch (...) { +// ProcessManagerRequest = 10; +// } + // //waiting for request // IOSocket fIos; + requestCount = 0; for (;;) { @@ -446,23 +458,33 @@ static void messageThread(Configuration config) catch(...) {} + requestCount++; + //log.writeLog(__LINE__, "requestCount = " + oam.itoa(requestCount), LOG_TYPE_ERROR); + + // loop until count decreases + //while(true) + //{ + // if ( requestCount < ProcessManagerRequest ) + // break; + // log.writeLog(__LINE__, "in loop", LOG_TYPE_ERROR); + //} } } - catch (exception& ex) - { - string error = ex.what(); - log.writeLog(__LINE__, "EXCEPTION ERROR on MessageQueueServer for ProcMgr:" + error, LOG_TYPE_ERROR); + catch (exception& ex) + { + string error = ex.what(); + log.writeLog(__LINE__, "EXCEPTION ERROR on MessageQueueServer for ProcMgr:" + error, LOG_TYPE_ERROR); - // takes 2 - 4 minites to free sockets, sleep and retry - sleep(60); - } - catch(...) - { - log.writeLog(__LINE__, "EXCEPTION ERROR on MessageQueueServer for ProcMgr: Caught unknown exception!", LOG_TYPE_ERROR); + // takes 2 - 4 minites to free sockets, sleep and retry + sleep(60); + } + catch(...) + { + log.writeLog(__LINE__, "EXCEPTION ERROR on MessageQueueServer for ProcMgr: Caught unknown exception!", LOG_TYPE_ERROR); - // takes 2 - 4 minites to free sockets, sleep and retry - sleep(60); - } + // takes 2 - 4 minites to free sockets, sleep and retry + sleep(60); + } } return; } diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index b6fea4c5d..1079699fb 100644 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -56,6 +56,7 @@ extern string localHostName; extern string PMwithUM; extern string AmazonPMFailover; extern string DBRootStorageType; +extern int requestCount; typedef map moduleList; extern moduleList moduleInfoList; @@ -2987,12 +2988,19 @@ void processMSG(messageqcpp::IOSocket* cfIos) break; } - sleep(5); +// sleep(5); + +// requestCount--; +// log.writeLog(__LINE__, "requestCount = " + oam.itoa(requestCount), LOG_TYPE_ERROR); + fIos.close(); pthread_detach (ThreadId); pthread_exit(0); } + pthread_mutex_t ALARM_LOCK; + + /****************************************************************************************** * @brief getAlarmData * @@ -3003,6 +3011,9 @@ int ProcessManager::getAlarmData(messageqcpp::IOSocket fIos, int type, std::stri { ByteStream msg; Oam oam; + + pthread_mutex_lock(&ALARM_LOCK); + int returnStatus = oam::API_SUCCESS; AlarmList alarmList; @@ -3022,6 +3033,7 @@ int ProcessManager::getAlarmData(messageqcpp::IOSocket fIos, int type, std::stri } catch(...) {} + pthread_mutex_unlock(&ALARM_LOCK); return oam::API_FAILURE; } } @@ -3041,6 +3053,7 @@ int ProcessManager::getAlarmData(messageqcpp::IOSocket fIos, int type, std::stri } catch(...) {} + pthread_mutex_unlock(&ALARM_LOCK); return oam::API_FAILURE; } } @@ -3071,6 +3084,7 @@ int ProcessManager::getAlarmData(messageqcpp::IOSocket fIos, int type, std::stri } catch(...) {} + pthread_mutex_unlock(&ALARM_LOCK); return returnStatus; } @@ -6245,7 +6259,7 @@ void ProcessManager::saveBRM(bool skipSession, bool clearshm) if ( skipSession ) skip = "-s"; - string cmd = startup::StartUp::installDir() + "/bin/reset_locks " + skip + " > + logdir + /reset_locks.log1 2>&1"; + string cmd = startup::StartUp::installDir() + "/bin/reset_locks " + skip + " > " + logdir + "/reset_locks.log1 2>&1"; int rtnCode = system(cmd.c_str()); log.writeLog(__LINE__, "Ran reset_locks", LOG_TYPE_DEBUG); From 3d3142e29a32170e393ad620c212cde3d1809045 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 3 Aug 2017 17:47:56 +0100 Subject: [PATCH 124/185] MCOL-857 Fix thread leak on ByteStream exception ByteStream::advance can throw an exception if there isn't enough data in the buffer yet. PrimProc's BPP processor would not catch this causing a thread to be leaked every time. This was happening on BPP destroy and abort. --- primitives/primproc/primitiveserver.cpp | 31 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/primitives/primproc/primitiveserver.cpp b/primitives/primproc/primitiveserver.cpp index c8719352e..1bc17567e 100644 --- a/primitives/primproc/primitiveserver.cpp +++ b/primitives/primproc/primitiveserver.cpp @@ -1223,8 +1223,17 @@ struct BPPHandler uint32_t key; BPPMap::iterator it; - bs.advance(sizeof(ISMPacketHeader)); - bs >> key; + try + { + bs.advance(sizeof(ISMPacketHeader)); + bs >> key; + } + catch(...) + { + // MCOL-857 We don't have the full packet yet + bs.rewind(); + return -1; + } mutex::scoped_lock scoped(bppLock); bppKeysIt = std::find(bppKeys.begin(), bppKeys.end(), key); if (bppKeysIt != bppKeys.end()) { @@ -1425,10 +1434,20 @@ struct BPPHandler uint32_t uniqueID, sessionID, stepID; BPPMap::iterator it; - bs.advance(sizeof(ISMPacketHeader)); - bs >> sessionID; - bs >> stepID; - bs >> uniqueID; + try + { + + bs.advance(sizeof(ISMPacketHeader)); + bs >> sessionID; + bs >> stepID; + bs >> uniqueID; + } + catch(...) + { + // MCOL-857 We don't appear to have the full packet yet! + bs.rewind(); + return -1; + } mutex::scoped_lock lk(djLock); mutex::scoped_lock scoped(bppLock); From eaf491c1a402fe4b7f654273608c8326153160a6 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 3 Aug 2017 20:35:38 +0100 Subject: [PATCH 125/185] MCOL-812 Escape slash as well as single quote Previous attempt at fix only escaped quote --- dbcon/execplan/simplefilter.cpp | 20 +++++++++++++++++--- dbcon/execplan/simplefilter.h | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/dbcon/execplan/simplefilter.cpp b/dbcon/execplan/simplefilter.cpp index 54251f3b8..bead8ece5 100644 --- a/dbcon/execplan/simplefilter.cpp +++ b/dbcon/execplan/simplefilter.cpp @@ -26,7 +26,6 @@ #include #include using namespace std; -#include #include "returnedcolumn.h" #include "constantcolumn.h" @@ -171,6 +170,21 @@ void SimpleFilter::rhs(ReturnedColumn* rhs) convertConstant(); } +std::string SimpleFilter::escapeString(const std::string& input) +{ + std::ostringstream ss; + for (std::string::const_iterator iter = input.begin(); iter != input.end(); iter++) + { + switch (*iter) + { + case '\\': ss << "\\\\"; break; + case '\'': ss << "\\'"; break; + default: ss << *iter; break; + } + } + return ss.str(); +} + const string SimpleFilter::data() const { string rhs, lhs; @@ -180,7 +194,7 @@ const string SimpleFilter::data() const fRhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY || fRhs->resultType().colDataType == CalpontSystemCatalog::DATE || fRhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)) - rhs = "'" + boost::replace_all_copy(fRhs->data(), "'", "\\'") + "'"; + rhs = "'" + SimpleFilter::escapeString(fRhs->data()) + "'"; else rhs = fRhs->data(); if (dynamic_cast(fLhs) && @@ -189,7 +203,7 @@ const string SimpleFilter::data() const fLhs->resultType().colDataType == CalpontSystemCatalog::VARBINARY || fLhs->resultType().colDataType == CalpontSystemCatalog::DATE || fLhs->resultType().colDataType == CalpontSystemCatalog::DATETIME)) - lhs = "'" + boost::replace_all_copy(fLhs->data(), "'", "\\'") + "'"; + lhs = "'" + SimpleFilter::escapeString(fLhs->data()) + "'"; else lhs = fLhs->data(); return lhs + " " + fOp->data() + " " + rhs; diff --git a/dbcon/execplan/simplefilter.h b/dbcon/execplan/simplefilter.h index 944c5e25a..d68d27873 100644 --- a/dbcon/execplan/simplefilter.h +++ b/dbcon/execplan/simplefilter.h @@ -180,6 +180,8 @@ public: virtual void replaceRealCol(std::vector&); + static std::string escapeString(const std::string& input); + private: SOP fOp; /// operator ReturnedColumn *fLhs; /// left operand From a7553930676b9b2b24d645201a1a257c5f91096c Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 4 Aug 2017 15:07:32 +0100 Subject: [PATCH 126/185] MCOL-515 Fix cross engine for FE2/3 modes When subqueries and group by are used in CrossEngine the first row group is either corrupted or ignored. This is related to MCOL-430 which fixed the case for FE1 mode. --- dbcon/joblist/crossenginestep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbcon/joblist/crossenginestep.cpp b/dbcon/joblist/crossenginestep.cpp index 4026255a1..c548ecfdd 100644 --- a/dbcon/joblist/crossenginestep.cpp +++ b/dbcon/joblist/crossenginestep.cpp @@ -225,7 +225,7 @@ void CrossEngineStep::setFcnExpGroup3(const vector& fe) void CrossEngineStep::setFE23Output(const rowgroup::RowGroup& rg) { - fRowGroupFe3 = fRowGroupDelivered = rg; + fRowGroupFe3 = fRowGroupDelivered = fRowGroupAdded = rg; } From 194993328e34c67294ffeb203820ff602ab5d893 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 7 Aug 2017 08:59:49 -0500 Subject: [PATCH 127/185] MCOL-850 --- oam/cloud/MCSVolumeCmds.sh | 8 +++---- oam/install_scripts/module_installer.sh | 13 +++++++---- oamapps/postConfigure/postConfigure.cpp | 30 +++++++++++-------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/oam/cloud/MCSVolumeCmds.sh b/oam/cloud/MCSVolumeCmds.sh index ff9b1681a..291d27e44 100755 --- a/oam/cloud/MCSVolumeCmds.sh +++ b/oam/cloud/MCSVolumeCmds.sh @@ -215,7 +215,7 @@ detachvolume() { sleep 1 done test -f /usr/local/mariadb/columnstore/post/functions && . /usr/local/mariadb/columnstore/post/functions - $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "detachvolume failed: $STATUS" + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 6 "MCSVolume: detachvolume failed: $STATUS" echo "failed" exit 1 fi @@ -226,7 +226,7 @@ detachvolume() { fi test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions - $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "detachvolume failed status: $STATUS" + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 6 "MCSVolume: detachvolume failed status: $STATUS" echo $STATUS exit 1 } @@ -250,7 +250,7 @@ attachvolume() { sleep 1 done test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions - $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "attachvolume failed: $STATUS" + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 6 "MCSVolume: attachvolume failed: $STATUS" echo "failed" exit 1 fi @@ -261,7 +261,7 @@ attachvolume() { fi test -f $COLUMNSTORE_INSTALL_DIR/post/functions && . $COLUMNSTORE_INSTALL_DIR/post/functions - $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 100 "attachvolume failed: $STATUS" + $COLUMNSTORE_INSTALL_DIR/bin/cplogger -w 6 "MCSVolume: attachvolume failed: $STATUS" echo $STATUS exit 1 } diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 181112a9f..7f302819d 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -92,8 +92,13 @@ if [ $module = "um" ]; then echo "Setup UM Volume Mount" device=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMVolumeDeviceName$mid` mkdir -p $COLUMNSTORE_INSTALL_DIR/mysql/db > /dev/null 2>&1 - sudo mount $device $COLUMNSTORE_INSTALL_DIR/mysql/db -t ext2 -o noatime,nodiratime,noauto,user - chown mysql:mysql -R $COLUMNSTORE_INSTALL_DIR/mysql > /dev/null 2>&1 + if [ $user = "root" ]; then + mount $device $COLUMNSTORE_INSTALL_DIR/mysql/db -t ext2 -o noatime,nodiratime,noauto + chown mysql:mysql -R $COLUMNSTORE_INSTALL_DIR/mysql > /dev/null 2>&1 + else + sudo mount $device $COLUMNSTORE_INSTALL_DIR/mysql/db -t ext2 -o noatime,nodiratime,noauto,user + sudo chown $user:$user -R $COLUMNSTORE_INSTALL_DIR/mysql > /dev/null 2>&1 + fi fi fi fi @@ -155,13 +160,13 @@ fi # if um, run mysql install scripts if [ $module = "um" ]; then echo "Run post-mysqld-install" - $COLUMNSTORE_INSTALL_DIR/bin/post-mysqld-install > /tmp/post-mysqld-install.log 2>&1 + $COLUMNSTORE_INSTALL_DIR/bin/post-mysqld-install --installdir=$COLUMNSTORE_INSTALL_DIR > /tmp/post-mysqld-install.log 2>&1 if [ $? -ne 0 ]; then echo "ERROR: post-mysqld-install failed: check /tmp/post-mysqld-install.log" exit 1 fi echo "Run post-mysql-install" - $COLUMNSTORE_INSTALL_DIR/bin/post-mysql-install > /tmp/post-mysql-install.log 2>&1 + $COLUMNSTORE_INSTALL_DIR/bin/post-mysql-install --installdir=$COLUMNSTORE_INSTALL_DIR > /tmp/post-mysql-install.log 2>&1 if [ $? -ne 0 ]; then echo "ERROR: post-mysql-install failed: check /tmp/post-mysql-install.log" exit 1 diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 5d2040807..4390db2f5 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -4996,27 +4996,23 @@ bool attachVolume(string instanceName, string volumeName, string deviceName, str { Oam oam; - //just return of debug set, called from amazonInstaller - if( thread_remote_installer ) - return true; - - cout << "Checking if Volume " << volumeName << " is attached , please wait..." << endl; +// cout << "Checking if Volume " << volumeName << " is attached , please wait..." << endl; string status = oam.getEC2VolumeStatus(volumeName); if ( status == "attached" ) { - cout << "Volume " << volumeName << " is attached " << endl; - cout << "Make sure it's device " << deviceName << " is mounted to DBRoot directory " << dbrootPath << endl; + cout << " Volume " << volumeName << " is attached " << endl; +// cout << "Make sure it's device " << deviceName << " is mounted to DBRoot directory " << dbrootPath << endl; return true; } if ( status != "available" ) { - cout << "ERROR: Volume " << volumeName << " status is " << status << endl; - cout << "Please resolve and re-run postConfigure" << endl; + cout << " ERROR: Volume " << volumeName << " status is " << status << endl; + cout << " Please resolve and re-run postConfigure" << endl; return false; } else { - cout << endl; +/* cout << endl; string temp = "y"; while(true) { @@ -5037,26 +5033,26 @@ bool attachVolume(string instanceName, string volumeName, string deviceName, str } if ( temp == "y" ) { - cout << "Attaching, please wait..." << endl; +*/ cout << " Attaching, please wait..." << endl; if(oam.attachEC2Volume(volumeName, deviceName, instanceName)) { - cout << "Volume " << volumeName << " is now attached " << endl; - cout << "Make sure it's device " << deviceName << " is mounted to DBRoot directory " << dbrootPath << endl; + cout << " Volume " << volumeName << " is now attached " << endl; +// cout << "Make sure it's device " << deviceName << " is mounted to DBRoot directory " << dbrootPath << endl; return true; } else { - cout << "ERROR: Volume " << volumeName << " failed to attach" << endl; - cout << "Please resolve and re-run postConfigure" << endl; + cout << " ERROR: Volume " << volumeName << " failed to attach" << endl; + cout << " Please resolve and re-run postConfigure" << endl; return false; } - } +/* } else { cout << "Volume " << volumeName << " will need to be attached before completing the install" << endl; cout << "Please resolve and re-run postConfigure" << endl; return false; } - } +*/ } } bool singleServerDBrootSetup() From 06199595763c363dc36a6bd8d1c1d52a1eb2071c Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 9 Aug 2017 13:53:54 -0500 Subject: [PATCH 128/185] change to 1.0.11 --- VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 91d2f876b..a405d8f12 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=0 -COLUMNSTORE_VERSION_PATCH=10 -COLUMNSTORE_VERSION_RELEASE=2 +COLUMNSTORE_VERSION_PATCH=11 +COLUMNSTORE_VERSION_RELEASE=1 From f90ab4c8e6e7be785cf1bfe744e7ceec19359c82 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 10 Aug 2017 19:45:46 -0500 Subject: [PATCH 129/185] MCP-750 --- cpackEngineRPM.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpackEngineRPM.cmake b/cpackEngineRPM.cmake index f567aa40d..0920201ad 100644 --- a/cpackEngineRPM.cmake +++ b/cpackEngineRPM.cmake @@ -163,8 +163,7 @@ SET(CPACK_RPM_platform_USER_FILELIST "/usr/local/mariadb/columnstore/bin/transactionLogArchiver.sh" "/usr/local/mariadb/columnstore/bin/installer" "/usr/local/mariadb/columnstore/bin/module_installer.sh" -"/usr/local/mariadb/columnstore/bin/user_installer.sh" -"/usr/local/mariadb/columnstore/bin/performance_installer.sh" +"/usr/local/mariadb/columnstore/bin/package_installer.sh" "/usr/local/mariadb/columnstore/bin/startupTests.sh" "/usr/local/mariadb/columnstore/bin/os_check.sh" "/usr/local/mariadb/columnstore/bin/remote_scp_put.sh" From 05d934f0ab3f97e5341b78df7501a287ec1f97eb Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 11 Aug 2017 07:17:07 +0100 Subject: [PATCH 130/185] MCOL-744 Fix BPP mutex crash Whilst very rare we can hit a case where we attempt to unlock objLock when it is already unlocked. With the Boost version in Ubuntu 16.04 this triggers an abort() effectively crashing PrimProc. In this patch we switch to a pthread mutex instead which does not have this limitation. At a later date we can look into refactoring how BPP and this mutex works. --- .../primproc/batchprimitiveprocessor.cpp | 23 ++++++++++--------- primitives/primproc/batchprimitiveprocessor.h | 9 ++++++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/primitives/primproc/batchprimitiveprocessor.cpp b/primitives/primproc/batchprimitiveprocessor.cpp index ab2d5cd7b..ede99fefc 100644 --- a/primitives/primproc/batchprimitiveprocessor.cpp +++ b/primitives/primproc/batchprimitiveprocessor.cpp @@ -112,6 +112,7 @@ BatchPrimitiveProcessor::BatchPrimitiveProcessor() : { pp.setLogicalBlockMode(true); pp.setBlockPtr((int *) blockData); + pthread_mutex_init(&objLock,NULL); } BatchPrimitiveProcessor::BatchPrimitiveProcessor(ByteStream &b, double prefetch, @@ -153,6 +154,7 @@ BatchPrimitiveProcessor::BatchPrimitiveProcessor(ByteStream &b, double prefetch, pp.setLogicalBlockMode(true); pp.setBlockPtr((int *) blockData); sendThread = bppst; + pthread_mutex_init(&objLock, NULL); initBPP(b); // cerr << "made a BPP\n"; } @@ -175,6 +177,7 @@ BatchPrimitiveProcessor::~BatchPrimitiveProcessor() counterLock.lock(); } counterLock.unlock(); + pthread_mutex_destroy(&objLock); } /** @@ -233,7 +236,7 @@ void BatchPrimitiveProcessor::initBPP(ByteStream &bs) } if (doJoin) { - objLock.lock(); + pthread_mutex_lock(&objLock); if (ot == ROW_GROUP) { bs >> joinerCount; // cout << "joinerCount = " << joinerCount << endl; @@ -325,7 +328,7 @@ void BatchPrimitiveProcessor::initBPP(ByteStream &bs) joiner.reset(new Joiner((bool) tmp8)); } #ifdef __FreeBSD__ - objLock.unlock(); + pthread_mutex_unlock(&objLock); #endif } @@ -389,7 +392,7 @@ void BatchPrimitiveProcessor::resetBPP(ByteStream &bs, const SP_UM_MUTEX& w, uint32_t i; vector preloads; - objLock.lock(); + pthread_mutex_lock(&objLock); writelock = w; sock = s; @@ -440,7 +443,7 @@ void BatchPrimitiveProcessor::resetBPP(ByteStream &bs, const SP_UM_MUTEX& w, buildVSSCache(count); #ifdef __FreeBSD__ - objLock.unlock(); + pthread_mutex_unlock(&objLock); #endif } @@ -587,7 +590,7 @@ int BatchPrimitiveProcessor::endOfJoiner() #endif #ifndef __FreeBSD__ - objLock.unlock(); + pthread_mutex_unlock(&objLock); #endif return 0; } @@ -1474,7 +1477,7 @@ void BatchPrimitiveProcessor::execute() #endif #ifndef __FreeBSD__ - objLock.unlock(); + pthread_mutex_unlock(&objLock); #endif throw n; // need to pass this through to BPPSeeder } @@ -1765,9 +1768,7 @@ int BatchPrimitiveProcessor::operator()() vssCache.clear(); #ifndef __FreeBSD__ - if (sendThread->aborted()) - objLock.try_lock(); - objLock.unlock(); + pthread_mutex_unlock(&objLock); #endif freeLargeBuffers(); #ifdef PRIMPROC_STOPWATCH @@ -1866,7 +1867,7 @@ SBPP BatchPrimitiveProcessor::duplicate() } bpp->doJoin = doJoin; if (doJoin) { - bpp->objLock.lock(); + pthread_mutex_lock(&bpp->objLock); bpp->joinerSize = joinerSize; if (ot == ROW_GROUP) { /* There are add'l join vars, but only these are necessary for processing @@ -1906,7 +1907,7 @@ SBPP BatchPrimitiveProcessor::duplicate() else bpp->joiner = joiner; #ifdef __FreeBSD__ - bpp->objLock.unlock(); + pthread_mutex_unlock(&bpp->objLock); #endif } diff --git a/primitives/primproc/batchprimitiveprocessor.h b/primitives/primproc/batchprimitiveprocessor.h index c57479ef9..ca782b3c7 100644 --- a/primitives/primproc/batchprimitiveprocessor.h +++ b/primitives/primproc/batchprimitiveprocessor.h @@ -121,7 +121,7 @@ class BatchPrimitiveProcessor // these two functions are used by BPPV to create BPP instances // on demand. TRY not to use unlock() for anything else. - void unlock() { objLock.try_lock(); objLock.unlock(); } + void unlock() { pthread_mutex_unlock(&objLock); } bool hasJoin() { return doJoin; } private: BatchPrimitiveProcessor(); @@ -200,7 +200,12 @@ class BatchPrimitiveProcessor messageqcpp::SBS serialized; SP_UM_MUTEX writelock; - boost::mutex objLock; + // MCOL-744 using pthread mutex instead of Boost mutex because + // in it is possible that this lock could be unlocked when it is + // already unlocked. In Ubuntu 16.04's Boost this triggers a + // crash. Whilst it is very hard to hit this it is still bad. + // Longer term TODO: fix/remove objLock and/or refactor BPP + pthread_mutex_t objLock; bool LBIDTrace; bool fBusy; From a38c65b65c2e1cead7172286e973114f5eaeacc1 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 11 Aug 2017 10:06:13 +0100 Subject: [PATCH 131/185] MCOL-835 Fix use-after-free crash in ExeMgr It is possible that DistributedEngineComm can get the Stats object from an MQE object and the MQE object freed before it's stats object is passed to InetStreamSocket. This patch makes sure that DistributedEngineComm gets a reference to MQE instead of the pointer to the Stats object in another reference. Therefore making sure that the Stats object still exists in InetStreamSocket. --- dbcon/joblist/distributedenginecomm.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dbcon/joblist/distributedenginecomm.cpp b/dbcon/joblist/distributedenginecomm.cpp index c1345f6d0..0e58794bf 100644 --- a/dbcon/joblist/distributedenginecomm.cpp +++ b/dbcon/joblist/distributedenginecomm.cpp @@ -765,12 +765,15 @@ void DistributedEngineComm::write(messageqcpp::ByteStream &msg, uint32_t connect mutex::scoped_lock lk(fMlock, defer_lock_t()); MessageQueueMap::iterator it; + // This keeps mqe's stats from being freed until end of function + boost::shared_ptr mqe; Stats *senderStats = NULL; lk.lock(); it = fSessionMessages.find(senderID); if (it != fSessionMessages.end()) - senderStats = &(it->second->stats); + mqe = it->second; + senderStats = &(mqe->stats); lk.unlock(); newClients[connection]->write(msg, NULL, senderStats); @@ -829,6 +832,8 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin { mutex::scoped_lock lk(fMlock, defer_lock_t()); MessageQueueMap::iterator it; + // Keep mqe's stats from being freed early + boost::shared_ptr mqe; Stats *senderStats = NULL; uint32_t interleaver = 0; @@ -839,7 +844,8 @@ int DistributedEngineComm::writeToClient(size_t index, const ByteStream& bs, uin lk.lock(); it = fSessionMessages.find(sender); if (it != fSessionMessages.end()) { - senderStats = &(it->second->stats); + mqe = it->second; + senderStats = &(mqe->stats); if (doInterleaving) interleaver = it->second->interleaver[index % it->second->pmCount]++; } From bfe54eb91c1746d3230464270b3e2d851eaf0ded Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 11 Aug 2017 10:12:56 +0100 Subject: [PATCH 132/185] MCOL-835 Fix non-braced 'if' --- dbcon/joblist/distributedenginecomm.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbcon/joblist/distributedenginecomm.cpp b/dbcon/joblist/distributedenginecomm.cpp index 0e58794bf..3d63f26f1 100644 --- a/dbcon/joblist/distributedenginecomm.cpp +++ b/dbcon/joblist/distributedenginecomm.cpp @@ -772,8 +772,10 @@ void DistributedEngineComm::write(messageqcpp::ByteStream &msg, uint32_t connect lk.lock(); it = fSessionMessages.find(senderID); if (it != fSessionMessages.end()) + { mqe = it->second; senderStats = &(mqe->stats); + } lk.unlock(); newClients[connection]->write(msg, NULL, senderStats); From c2ed1fb3360bae16e3c84c07ade08e816ecd5dc9 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 14 Aug 2017 13:43:48 -0500 Subject: [PATCH 133/185] Update README change version --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 1de3bd95e..3055d0c50 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ This is MariaDB ColumnStore 1.0.10 MariaDB ColumnStore 1.0.10 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.25 and adding entirely +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.26 and adding entirely new features not found anywhere else. MariaDB ColumnStore 1.0.10 is an GA release. This is the first MariaDB From ce8f8420b0b052dc5d87077697bcd9d423dcfe14 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 14 Aug 2017 13:44:23 -0500 Subject: [PATCH 134/185] Update README.md changed version --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b9407eb81..e9bfed6d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#MariaDB ColumnStore Storage/Execution engine 1.0.10 -MariaDB ColumnStore 1.0.10 is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.25 and adding entirely +#MariaDB ColumnStore Storage/Execution engine 1.0.11 +MariaDB ColumnStore 1.0.11 is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.26 and adding entirely new features not found anywhere else. #MariaDB ColumnStore 1.0.10 is an GA release. From ddc0a17924185bf610704452c59c4be2c9386011 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 14 Aug 2017 15:53:09 -0500 Subject: [PATCH 135/185] MCOL-792 debian 9 support --- .../clusterTester/columnstoreClusterTester.sh | 73 ++++++++++++++++++- utils/clusterTester/os_detect.sh | 2 +- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index 1265a3620..f1cfaf928 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -10,7 +10,7 @@ CHECK=true REPORTPASS=true LOGFILE="" -OS_LIST=("centos6" "centos7" "debian8" "suse12" "ubuntu16") +OS_LIST=("centos6" "centos7" "debian8" "debian9" "suse12" "ubuntu16") NODE_IPADDRESS="" @@ -71,7 +71,7 @@ helpPrint () { echo " -h,--help Help" echo " --ipaddr=[ipaddresses] Remote Node IP-Addresses/Hostnames, if not provide, will only check local node" echo " examples: 192.168.1.1,192.168.1.2 or serverum1,serverpm2" - echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, suse12, ubuntu16)" + echo " --os=[os] Optional: Set OS Version (centos6, centos7, debian8, debian9, suse12, ubuntu16)" echo " --password=[password] Provide a user password. (Default: ssh-keys setup will be assumed)" echo " -c,--continue Continue on failures" echo " --logfile=[fileName] Output results to a log file" @@ -841,7 +841,7 @@ checkPackages() fi fi - declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline-dev" "rsync" "snappy" "net-tools" "libdbd-mysql-perl") + declare -a UBUNTU_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline-dev" "rsync" "libsnappy1V5" "net-tools" "libdbd-mysql-perl") if [ "$OS" == "ubuntu16" ] ; then if [ ! `which dpkg 2>/dev/null` ] ; then @@ -970,6 +970,73 @@ checkPackages() done fi fi + + declare -a DEBIAN9_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline5" "rsync" "libsnappy1V5" "net-tools") + + if [ "$OS" == "debian9" ]; then + if [ ! `which dpkg 2>/dev/null` ] ; then + echo "${bold}Failed${normal}, Local Node ${bold}rpm${normal} package not installed" + pass=false + REPORTPASS=false + else + pass=true + #check centos packages on local node + for PKG in "${DEBIAN9_PKG[@]}"; do + `dpkg -s "$PKG" > /tmp/pkg_check 2>&1` + `cat /tmp/pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, Local Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + REPORTPASS=false + fi + done + + if $pass; then + echo "Local Node - Passed, all dependency packages are installed" + else + checkContinue + fi + fi + + echo "" + pass=true + if [ "$IPADDRESSES" != "" ]; then + for ipadd in "${NODE_IPADDRESS[@]}"; do + for PKG in "${DEBIAN9_PKG[@]}"; do + `./remote_command.sh $ipadd $PASSWORD "dpkg -s '$PKG' > /tmp/pkg_check 2>&1" 1 > /tmp/remote_command_check 2>&1` + `./remote_scp_get.sh $ipadd $PASSWORD /tmp/pkg_check > /tmp/remote_scp_get_check 2>&1` + if [ "$?" -ne 0 ]; then + echo "Error running remote_scp_get.sh to $ipadd Node, check /tmp/remote_scp_get_check" + else + `cat /tmp/remote_command_check | grep 'command not found' > /dev/null 2>&1` + if [ "$?" -eq 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node ${bold}dpkg${normal} package not installed" + pass=false + break + else + `cat pkg_check | grep 'install ok installed' > /dev/null 2>&1` + if [ "$?" -ne 0 ]; then + echo "${bold}Failed${normal}, $ipadd Node package ${bold}${PKG}${normal} is not installed, please install" + pass=false + fi + + `rm -f pkg_check` + fi + fi + done + + if $pass; then + echo "$ipadd Node - Passed, all dependency packages are installed" + else + checkContinue + pass=true + fi + echo "" + done + fi + fi + + } echo "" diff --git a/utils/clusterTester/os_detect.sh b/utils/clusterTester/os_detect.sh index 1f76a3716..7930c0daf 100755 --- a/utils/clusterTester/os_detect.sh +++ b/utils/clusterTester/os_detect.sh @@ -29,7 +29,7 @@ detectOS () { echo Operating System name: $osPrettyName echo Operating System tag: $osTag case "$osTag" in - centos6|centos7|ubuntu16|debian8|suse12) + centos6|centos7|ubuntu16|debian8|suse12|debian9) ;; *) echo OS not supported From 1cae6db09da6481dac18fb534d9573790759dcbf Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 15 Aug 2017 13:29:50 -0500 Subject: [PATCH 136/185] MCOL-860 - remove comment to delete files from /tmp in post-install --- oam/install_scripts/post-install | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index fbff1c6a3..638f77eaa 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -154,8 +154,6 @@ mkdir -p $installdir/data/bulk/tmpjob >/dev/null 2>&1 rm -f $installdir/data/bulk/tmpjob/* >/dev/null 2>&1 #create columnstore temp file directory -$SUDO chmod 777 /tmp -$SUDO rm -f /tmp/* > /dev/null 2>&1 mkdir -p /tmp/columnstore_tmp_files >/dev/null 2>&1 #setup core file directory and link @@ -221,8 +219,8 @@ else $SUDO cp $installdir/bin/columnstore.def /etc/default/columnstore sed -i -e s@prefix=/home/quest@prefix=$prefix@g $installdir/bin/* - - $SUDO rm -f /tmp/* > /dev/null 2>&1 + + $SUDO chmod 777 /tmp $installdir/bin/syslogSetup.sh --installdir=$installdir install > /tmp/syslog_install.log 2>&1 $SUDO chown $user:$user $installdir/etc/Columnstore.xml $SUDO chmod -R 777 /dev/shm From 83c850266b4c74d3aad8d304c52939f425d0e92b Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 15 Aug 2017 14:06:04 -0500 Subject: [PATCH 137/185] MCOL-400 remove the delayed keyword --- utils/querystats/querystats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/querystats/querystats.cpp b/utils/querystats/querystats.cpp index ef593b3fc..86417aee8 100644 --- a/utils/querystats/querystats.cpp +++ b/utils/querystats/querystats.cpp @@ -227,7 +227,7 @@ void QueryStats::insert() drizzle_escape_string(query.get(), fQuery.length()*2, fQuery.c_str(), fQuery.length()); ostringstream insert; - insert << "insert delayed into querystats values (0, "; + insert << "insert into querystats values (0, "; insert << fSessionID << ", "; insert << "'" << fHost << "', "; insert << "'" << fUser << "', "; From 03c66e983f4a067c88dadf4edebd906bb7649737 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 15 Aug 2017 14:13:26 -0500 Subject: [PATCH 138/185] add libioa1 to debian 9 packages --- utils/clusterTester/columnstoreClusterTester.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/clusterTester/columnstoreClusterTester.sh b/utils/clusterTester/columnstoreClusterTester.sh index f1cfaf928..89f0e34c8 100755 --- a/utils/clusterTester/columnstoreClusterTester.sh +++ b/utils/clusterTester/columnstoreClusterTester.sh @@ -971,7 +971,7 @@ checkPackages() fi fi - declare -a DEBIAN9_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline5" "rsync" "libsnappy1V5" "net-tools") + declare -a DEBIAN9_PKG=("libboost-all-dev" "expect" "libdbi-perl" "perl" "openssl" "file" "sudo" "libreadline5" "rsync" "libsnappy1V5" "net-tools" "libioa1") if [ "$OS" == "debian9" ]; then if [ ! `which dpkg 2>/dev/null` ] ; then From 953e748790efa3227597dff12464c326225dab10 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 17 Aug 2017 14:47:26 -0500 Subject: [PATCH 139/185] 1.0.11 install stabilize fix --- oam/install_scripts/binary_installer.sh | 487 +++++++++++-------- oam/install_scripts/performance_installer.sh | 391 ++++++++------- oam/install_scripts/user_installer.sh | 432 ++++++++-------- 3 files changed, 757 insertions(+), 553 deletions(-) diff --git a/oam/install_scripts/binary_installer.sh b/oam/install_scripts/binary_installer.sh index 1b71aee94..b83b1a9d0 100644 --- a/oam/install_scripts/binary_installer.sh +++ b/oam/install_scripts/binary_installer.sh @@ -38,68 +38,162 @@ if { $UNM != "" } { set USERNAME $UNM } -set BASH "/bin/bash " -if { $DEBUG == "1" } { - set BASH "/bin/bash -x " -} - log_user $DEBUG spawn -noecho /bin/bash # -if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { - # - # remove MariaDB Columnstore files - # - send_user "Uninstall MariaDB Columnstore Package " - send " \n" - send date\n - send "ssh $USERNAME@$SERVER 'rm -f /etc/init.d/columnstore /etc/init.d/mysql-Columnstore $INSTALLDIR/releasenum >/dev/null 2>&1'\n" - set timeout 20 - expect { - "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1} - "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1} - "authenticity" { send "yes\n" - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - "MariaDB Columnstore uninstall completed" { send_user "DONE" } +#check and see if remote server has ssh keys setup, set PASSWORD if so +send_user " " +send "ssh -v $USERNAME@$SERVER 'time'\n" +set timeout 20 +expect { + "authenticity" { send "yes\n" + expect { + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } } + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} +send_user "\n" + +send_user "Stop ColumnStore service " +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/columnstore stop'\n" +if { $PASSWORD != "ssh" } { set timeout 30 expect { - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "MariaDB Columnstore uninstall completed" { send_user "DONE" } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } } - send_user "\n" } -if { $INSTALLTYPE == "uninstall" } { - exit 0 +set timeout 60 +# check return +expect { + "No such file or directory" { send_user "DONE" } + "Exit status 0" { send_user "DONE" } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "DONE" } } -sleep 10 +send_user "\n" + +# +# remove MariaDB Columnstore files +# +send_user "Uninstall MariaDB Columnstore Package " +send " \n" +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/pre-uninstall --installdir=$INSTALLDIR >/dev/null 2>&1'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 30 +expect { + "No such file or directory" { send_user "DONE" } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1} + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1} + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "MariaDB Columnstore uninstall completed" { send_user "DONE" } + "Exit status 0" { send_user "DONE" } + "Exit status 127" { send_user "DONE" } + timeout { send_user "DONE" } +} +send_user "\n" + +if { $INSTALLTYPE == "uninstall" } { exit 0 } + # # send the MariaDB Columnstore package # send_user "Copy New MariaDB Columnstore Package to Module " send " \n" -send date\n -send "scp $CALPONTPKG $USERNAME@$SERVER:$CALPONTPKG\n" -set timeout 10 -expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } +send "scp -v $CALPONTPKG $USERNAME@$SERVER:$CALPONTPKG\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } } -set timeout 120 +set timeout 180 expect { - "100%" { send_user "DONE" } - "scp:" { send_user "ERROR\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } + "Exit status 0" { send_user "DONE" } + "scp :" { send_user "ERROR\n" ; + send_user "\n*** Installation ERROR\n" ; + exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "No such file or directory" { send_user "ERROR: Invalid package\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} @@ -109,24 +203,22 @@ expect { timeout { send_user "ERROR: Timeout\n" ; exit 1 } } send_user "\n" -#sleep to make sure it's finished -sleep 5 # # install package # send_user "Install MariaDB Columnstore Package on Module " send " \n" -send date\n -send "ssh $USERNAME@$SERVER 'tar -C $PREFIX --exclude db -zxf $CALPONTPKG;cat $INSTALLDIR/releasenum'\n" -set timeout 10 -expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } +send "ssh -v $USERNAME@$SERVER 'tar -C $PREFIX --exclude db -zxf $CALPONTPKG'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } } set timeout 120 expect { - "release=" { send_user "DONE" } - "No such file" { send_user "ERROR: Binary Install Failed, binary/releasenum not found\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } @@ -134,174 +226,187 @@ expect { "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } timeout { send_user "ERROR: Timeout\n" ; exit 1 } } -#sleep to give time for cat MariaDB Columnstore/releasenum to complete -sleep 5 - send_user "\n" + send_user "Run post-install script " send " \n" -send date\n -send "ssh $USERNAME@$SERVER '$INSTALLDIR/bin/post-install --installdir=$INSTALLDIR'\n" -set timeout 10 -expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/post-install --installdir=$INSTALLDIR'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } } set timeout 60 # check return expect { - "MariaDB Columnstore syslog logging not working" { send_user "ERROR: MariaDB Columnstore System logging not setup\n" ; exit 1 } + "No such file" { send_user "ERROR: post-install Not Found\n" ; exit 1 } + "MariaDB Columnstore syslog logging not working" { send_user "WARNING: MariaDB Columnstore System logging not setup\n" } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - "postConfigure" { send_user "DONE" } + #"columnstore start" { send_user "DONE" } + "Exit status 0" { send_user "DONE" } } send_user "\n" -sleep 10 + # -if { $INSTALLTYPE == "initial"} { - # - # copy over calpont config file - # - send_user "Copy MariaDB Columnstore Config file to Module " - send " \n" - send date\n - send "scp $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc\n" - set timeout 10 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } +# copy over calpont config file +# +send_user "Copy MariaDB Columnstore Config file to Module " +send " \n" +send date\n +send "scp -v $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc\n" +if { $PASSWORD != "ssh" } { set timeout 30 expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } } - send_user "\n" - # - # copy over custom OS tmp files - # - send_user "Copy Custom OS files to Module " - send " \n" - send date\n - send "scp -r $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local\n" - set timeout 10 +} +set timeout 60 +expect { + "Exit status 0" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } +} +send_user "\n" +# +# copy over custom OS tmp files +# +send_user "Copy Custom OS files to Module " +send " \n" +send date\n +send "scp -rv $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local\n" +if { $PASSWORD != "ssh" } { + set timeout 30 expect { "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } } - set timeout 60 - expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - } - send_user "\n" - # - # copy over calpont OS files - # - send_user "Copy MariaDB Columnstore OS files to Module " - send " \n" - send date\n - send "scp $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local\n" - set timeout 10 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - } - set timeout 60 - expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - } - send_user "\n" - # - # Start module installer to setup Customer OS files - # - send_user "Run Module Installer " - send " \n" - send date\n - send "ssh $USERNAME@$SERVER '$INSTALLDIR/bin/module_installer.sh --module=$MODULETYPE --port=$MYSQLPORT --installdir=$INSTALLDIR'\n" - set timeout 10 +} +set timeout 60 +expect { + "Exit status 0" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } +} +send_user "\n" +# +# copy over calpont OS files +# +send_user "Copy MariaDB Columnstore OS files to Module " +send " \n" +send date\n +send "scp -v $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local\n" +if { $PASSWORD != "ssh" } { + set timeout 30 expect { "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } } - set timeout 60 - expect { - "!!!Module" { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing module file\n" ; exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } - } - send_user "\n" - sleep 10 - if { $MODULETYPE == "um" || $SERVERTYPE == "2" || $SERVERTYPE == "pmwithum" } { - # - # run mysql setup scripts - # - send_user "Run MySQL Setup Scripts on Module " - send " \n" - send date\n - send "ssh $USERNAME@$SERVER '$INSTALLDIR/bin/post-mysqld-install --installdir=$INSTALLDIR'\n" - set timeout 10 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - set timeout 60 - expect { - "ERROR" { send_user "ERROR: Daemon failed to run"; - exit 1 } - "FAILED" { send_user "ERROR: Daemon failed to run"; - exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - } +} +set timeout 60 +expect { + "Exit status 0" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } +} +send_user "\n" - send " \n" - send date\n - send "ssh $USERNAME@$SERVER '$INSTALLDIR/bin/post-mysql-install --installdir=$INSTALLDIR'\n" - set timeout 10 +# +# Start module installer to setup Customer OS files +# +send_user "Run Module Installer " +send " \n" +send date\n +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/module_installer.sh --module=$MODULETYPE --port=$MYSQLPORT --installdir=$INSTALLDIR'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "!!!Module" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "FAILED" { send_user "ERROR: missing module file\n" ; exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } + "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } + "Exit status 0" { send_user "DONE" } +} +send_user "\n" + +if { $MODULETYPE == "um" || $SERVERTYPE == "2" || $SERVERTYPE == "pmwithum" } { + # + # run mysql setup scripts + # + send_user "Run MySQL Setup Scripts on Module " + send " \n" + send date\n + send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/post-mysqld-install --installdir=$INSTALLDIR'\n" + if { $PASSWORD != "ssh" } { + set timeout 30 expect { "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } } - set timeout 60 - expect { - "Shutting down mysql." { send_user "DONE" } - timeout { send_user "DONE" } - "ERROR" { send_user "ERROR: Daemon failed to run"; - exit 1 } - "FAILED" { send_user "ERROR: Daemon failed to run"; - exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - } - send_user "\n" } + set timeout 60 + expect { + "Exit status 0" { send_user "DONE" } + "ERROR" { send_user "ERROR: Daemon failed to run"; + exit 1 } + "FAILED" { send_user "ERROR: Daemon failed to run"; + exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + } + + send " \n" + send date\n + send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/post-mysql-install --installdir=$INSTALLDIR'\n" + if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } + } + set timeout 60 + expect { + "Exit status 0" { send_user "DONE" } + "Shutting down mysql." { send_user "DONE" } + timeout { send_user "DONE" } + "ERROR" { send_user "ERROR: Daemon failed to run"; + exit 1 } + "FAILED" { send_user "ERROR: Daemon failed to run"; + exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + } + send_user "\n" } diff --git a/oam/install_scripts/performance_installer.sh b/oam/install_scripts/performance_installer.sh index 302576455..74593c75b 100644 --- a/oam/install_scripts/performance_installer.sh +++ b/oam/install_scripts/performance_installer.sh @@ -60,63 +60,135 @@ if { $PKGTYPE == "rpm" } { } } -# check and see if remote server has ssh keys setup, set PASSWORD if so +#check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " -send "ssh $USERNAME@$SERVER 'time'\n" +send "ssh -v $USERNAME@$SERVER 'time'\n" set timeout 20 expect { + "authenticity" { send "yes\n" + expect { + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } - "authenticity" { send "yes\n" - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - "sys" { set PASSWORD "ssh" } - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } -set timeout 10 +send_user "\n" + +send_user "Stop ColumnStore service " +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/columnstore stop'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +# check return expect { - -re {[$#] } { } - "sys" { } + "No such file or directory" { send_user "DONE" } + "Exit status 0" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "DONE" } } send_user "\n" -#BUG 5749 - SAS: didn't work on their system until I added the sleep 60 -#sleep 60 -if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { - # - # erase package - # - send_user "Erase MariaDB Columnstore Packages on Module " - send "ssh $USERNAME@$SERVER '$PKGERASE ;$PKGERASE1 dummy'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 120 +# +# erase package +# +send_user "Erase MariaDB Columnstore Packages on Module " +send "ssh -v $USERNAME@$SERVER '$PKGERASE '\n" +if { $PASSWORD != "ssh" } { + set timeout 30 expect { - "error: --purge needs at least one package" { send_user "DONE" } - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } } - send_user "\n" } +set timeout 120 +expect { + "error: --purge needs at least one package" { send_user "DONE" } + "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + timeout { send_user "DONE" } +} +send_user "\n" if { $INSTALLTYPE == "uninstall" } { exit 0 } @@ -124,9 +196,8 @@ if { $INSTALLTYPE == "uninstall" } { exit 0 } # send the package # set timeout 30 -#expect -re {[$#] } send_user "Copy New MariaDB Columnstore Package to Module " -send "ssh $USERNAME@$SERVER 'rm -f /root/mariadb-columnstore-*.$PKGTYPE'\n" +send "ssh -v $USERNAME@$SERVER 'rm -f /root/mariadb-columnstore-*.$PKGTYPE'\n" if { $PASSWORD != "ssh" } { set timeout 30 expect { @@ -135,18 +206,14 @@ if { $PASSWORD != "ssh" } { } } expect { - -re {[$#] } { } + "Exit status 0" { send_user "DONE" } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } } set timeout 30 -expect { - -re {[$#] } { } -} - -send "scp $HOME/mariadb-columnstore*$VERSION*$PKGTYPE $USERNAME@$SERVER:.;$PKGERASE1 dummy\n" -if { $PASSWORD != "ssh" } { +send "scp -v $HOME/mariadb-columnstore*$VERSION*$PKGTYPE $USERNAME@$SERVER:.\n" +if { $PASSWORD != "ssh"} { set timeout 30 expect { "word: " { send "$PASSWORD\n" } @@ -155,144 +222,130 @@ if { $PASSWORD != "ssh" } { } set timeout 180 expect { - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "directory" { send_user "ERROR\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } send_user "\n" -#sleep to make sure it's finished -sleep 5 +# +# install package +# +send_user "Install MariaDB Columnstore Packages on Module " + +send "ssh -v $USERNAME@$SERVER '$PKGINSTALL '\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 180 +expect { + "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; + send_user "\n*** Installation ERROR\n" ; + exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "needs" { send_user "ERROR: disk space issue\n" ; exit 1 } + "conflicts" { send_user "ERROR: File Conflict issue\n" ; exit 1 } + "MariaDB Columnstore syslog logging not working" { send_user "WARNING: MariaDB Columnstore System logging not setup\n" } + "Exit status 0" { send_user "DONE" } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} + +send_user "\n" # -if { $INSTALLTYPE == "initial"} { - # - # install package - # - send_user "Install MariaDB Columnstore Packages on Module " - - send "ssh $USERNAME@$SERVER '$PKGINSTALL ;$PKGERASE1 dummy'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 180 +# copy over MariaDB Columnstore config file +# +send_user "Copy MariaDB Columnstore Config file to Module " +send "scp -v $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc/.\n" +if { $PASSWORD != "ssh" } { + set timeout 30 expect { - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "needs" { send_user "ERROR: disk space issue\n" ; exit 1 } - "conflicts" { send_user "ERROR: File Conflict issue\n" ; exit 1 } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } } - +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } send_user "\n" -#sleep to make sure it's finished -sleep 5 -set timeout 30 -#expect -re {[$#] } -if { $INSTALLTYPE == "initial"} { - # - # copy over MariaDB Columnstore config file - # - send_user "Copy MariaDB Columnstore Config file to Module " - send "scp $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } + + +# copy over custom OS tmp files +# +send_user "Copy Custom OS files to Module " +send "scp -rv $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local/.\n" +if { $PASSWORD != "ssh" } { set timeout 30 expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } } - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # copy over custom OS tmp files - # - send_user "Copy Custom OS files to Module " - send "scp -r $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 30 - expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # copy over MariaDB Columnstore OS files - # - send_user "Copy MariaDB Columnstore OS files to Module " - send "scp $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 30 - expect { - -re {[$#] } { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - # - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # Start module installer to setup Custom OS files - # - send_user "Run Module Installer " - send "ssh $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=pm'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 30 - expect { - "!!!Module" { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } - } - send_user "\n" +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } +send_user "\n" + # -# check MariaDB Columnstore syslog functionality +# copy over MariaDB Columnstore OS files # +send_user "Copy MariaDB Columnstore OS files to Module " +send "scp -v $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local/.\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} +# +send_user "\n" + +# Start module installer to setup Custom OS files +# +send_user "Run Module Installer " +send "ssh -v $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=pm'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + "!!!Module" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } + "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } +} +send_user "\n" # send_user "\nInstallation Successfully Completed on '$MODULE'\n" diff --git a/oam/install_scripts/user_installer.sh b/oam/install_scripts/user_installer.sh index 3cf649459..72f4ac8e8 100644 --- a/oam/install_scripts/user_installer.sh +++ b/oam/install_scripts/user_installer.sh @@ -36,11 +36,6 @@ if { $MYSQLPW == "none" } { set MYSQLPW " " } -set BASH "/bin/bash " -#if { $DEBUG == "1" } { -# set BASH "/bin/bash -x " -#} - set HOME "$env(HOME)" log_user $DEBUG @@ -64,91 +59,116 @@ if { $PKGTYPE == "rpm" } { } } -# check and see if remote server has ssh keys setup, set PASSWORD if so +#check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " -send "ssh $USERNAME@$SERVER 'time'\n" +send "ssh -v $USERNAME@$SERVER 'time'\n" set timeout 20 expect { - "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } - "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } "authenticity" { send "yes\n" expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } } - "sys" { set PASSWORD "ssh" } - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } + "word: " { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + } + } + "passphrase" { send "$PASSWORD\n" + expect { + "Exit status 0" { send_user "DONE" } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + } + } + "Exit status 0" { set PASSWORD "ssh" } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } + "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } -set timeout 10 -expect { - -re {[$#] } { } - "sys" { } -} send_user "\n" -#BUG 5749 - SAS: didn't work on their system until I added the sleep 60 -#sleep 60 -if { $INSTALLTYPE == "initial" || $INSTALLTYPE == "uninstall" } { - # - # erase MariaDB Columnstore packages - # - send_user "Erase MariaDB Columnstore Packages on Module " - send "ssh $USERNAME@$SERVER '$PKGERASE ;$PKGERASE1 dummy'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 120 - expect { - "error: --purge needs at least one package" { send_user "DONE" } - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - send_user "\n" -} - -if { $INSTALLTYPE == "uninstall" } { exit 0 } - -# -# send the MariaDB ColumnStore package -# -set timeout 30 -#expect -re {[$#] } -send_user "Copy new MariaDB Columnstore Packages to Module " -send "ssh $USERNAME@$SERVER 'rm -f /root/mariadb-columnstore-*.$PKGTYPE'\n" +send_user "Stop ColumnStore service " +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/columnstore stop'\n" if { $PASSWORD != "ssh" } { set timeout 30 expect { "word: " { send "$PASSWORD\n" } "passphrase" { send "$PASSWORD\n" } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } } } +set timeout 60 +# check return expect { - -re {[$#] } { } - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } -} -set timeout 30 -expect { - -re {[$#] } { } + "No such file or directory" { send_user "DONE" } + "Exit status 0" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + timeout { send_user "DONE" } } +send_user "\n" -send "scp $HOME/mariadb-columnstore*$VERSION*$PKGTYPE $USERNAME@$SERVER:.;$PKGERASE1 dummy\n" +# +# erase package +# +send_user "Erase MariaDB Columnstore Packages on Module " +send "ssh -v $USERNAME@$SERVER '$PKGERASE '\n" if { $PASSWORD != "ssh" } { set timeout 30 expect { @@ -158,147 +178,173 @@ if { $PASSWORD != "ssh" } { } set timeout 120 expect { - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "directory" { send_user "ERROR\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "error: --purge needs at least one package" { send_user "DONE" } + "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + timeout { send_user "DONE" } } send_user "\n" -#sleep to make sure it's finished -sleep 5 +if { $INSTALLTYPE == "uninstall" } { exit 0 } + +# +# send the package # set timeout 30 -expect -re {[$#] } -if { $INSTALLTYPE == "initial"} { - # - # install package - # - send_user "Install MariaDB ColumnStore Packages on Module " - send "ssh $USERNAME@$SERVER '$PKGINSTALL ;$PKGERASE1 dummy'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 180 - expect { - "dummy is not installed" { send_user "DONE" } - "dummy which isn't installed" { send_user "DONE" } - "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "needs" { send_user "ERROR: disk space issue\n" ; exit 1 } - "conflicts" { send_user "ERROR: File Conflict issue\n" ; exit 1 } - } - send_user "\n" - +send_user "Copy New MariaDB Columnstore Package to Module " +send "ssh -v $USERNAME@$SERVER 'rm -f /root/mariadb-columnstore-*.$PKGTYPE'\n" +if { $PASSWORD != "ssh" } { set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } } -#sleep to make sure it's finished -sleep 5 +expect { + "Exit status 0" { send_user "DONE" } + "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } +} +set timeout 30 +send "scp -v $HOME/mariadb-columnstore*$VERSION*$PKGTYPE $USERNAME@$SERVER:.\n" +if { $PASSWORD != "ssh"} { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 180 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} +send_user "\n" + # -if { $INSTALLTYPE == "initial"} { - # - # copy over MariaDB Columnstore config file - # - send_user "Copy MariaDB Columnstore Config file to Module " - send "scp $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } +# install package +# +send_user "Install MariaDB Columnstore Packages on Module " + +send "ssh -v $USERNAME@$SERVER '$PKGINSTALL '\n" +if { $PASSWORD != "ssh" } { set timeout 30 expect { - "directory" { send_user "ERROR\n" ; + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 180 +expect { + "error: Failed dependencies" { send_user "ERROR: Failed dependencies\n" ; send_user "\n*** Installation ERROR\n" ; - exit 1 } - -re {[$#] } { send_user "DONE" } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # copy over custom OS tmp files - # - send_user "Copy Custom OS files to Module " - send "scp -r $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 30 - expect { - "directory" { send_user "ERROR\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } - -re {[$#] } { send_user "DONE" } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # copy over MariaDB Columnstore OS files - # - send_user "Copy MariaDB Columnstore OS files to Module " - send "scp $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local/.\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 30 - expect { - "directory" { send_user "ERROR\n" ; - send_user "\n*** Installation ERROR\n" ; - exit 1 } - -re {[$#] } { send_user "DONE" } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - } - send_user "\n" - #sleep to make sure it's finished - sleep 5 - # - # Start module installer to setup Custom OS files - # - send_user "Run Module Installer " - send "ssh $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=um --port=$MYSQLPORT'\n" - if { $PASSWORD != "ssh" } { - set timeout 30 - expect { - "word: " { send "$PASSWORD\n" } - "passphrase" { send "$PASSWORD\n" } - } - } - set timeout 200 - expect { - "!!!Module" { send_user "DONE" } - "ERROR" { send_user "ERROR: check /tmp logs\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } - } - send_user "\n" - set timeout 30 - #expect -re {[$#] } + exit 1 } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "needs" { send_user "ERROR: disk space issue\n" ; exit 1 } + "conflicts" { send_user "ERROR: File Conflict issue\n" ; exit 1 } + "MariaDB Columnstore syslog logging not working" { send_user "WARNING: MariaDB Columnstore System logging not setup\n" } + "Exit status 0" { send_user "DONE" } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } } +send_user "\n" + +# +# copy over MariaDB Columnstore config file +# +send_user "Copy MariaDB Columnstore Config file to Module " +send "scp -v $INSTALLDIR/etc/* $USERNAME@$SERVER:$INSTALLDIR/etc/.\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} +send_user "\n" + + +# copy over custom OS tmp files +# +send_user "Copy Custom OS files to Module " +send "scp -rv $INSTALLDIR/local/etc $USERNAME@$SERVER:$INSTALLDIR/local/.\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} + +send_user "\n" + +# +# copy over MariaDB Columnstore OS files +# +send_user "Copy MariaDB Columnstore OS files to Module " +send "scp -v $INSTALLDIR/local/etc/$MODULE/* $USERNAME@$SERVER:$INSTALLDIR/local/.\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } +} +# +send_user "\n" + +# Start module installer to setup Custom OS files +# +send_user "Run Module Installer " +send "ssh -v $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=um --port=$MYSQLPORT'\n" +if { $PASSWORD != "ssh" } { + set timeout 30 + expect { + "word: " { send "$PASSWORD\n" } + "passphrase" { send "$PASSWORD\n" } + } +} +set timeout 60 +expect { + "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + "!!!Module" { send_user "DONE" } + "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } + "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } + "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } + "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } + "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } +} +send_user "\n" send_user "\nInstallation Successfully Completed on '$MODULE'\n" exit 0 From eb7d2291444ca2991533583b70bc53b5652a83ff Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 17 Aug 2017 15:44:56 -0500 Subject: [PATCH 140/185] 1.0.11 install stabilize fix --- oam/install_scripts/binary_installer.sh | 4 ++-- oam/install_scripts/performance_installer.sh | 4 ++-- oam/install_scripts/user_installer.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/oam/install_scripts/binary_installer.sh b/oam/install_scripts/binary_installer.sh index b83b1a9d0..49cfc6d1d 100644 --- a/oam/install_scripts/binary_installer.sh +++ b/oam/install_scripts/binary_installer.sh @@ -45,7 +45,7 @@ spawn -noecho /bin/bash #check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " send "ssh -v $USERNAME@$SERVER 'time'\n" -set timeout 20 +set timeout 60 expect { "authenticity" { send "yes\n" expect { @@ -188,7 +188,7 @@ if { $PASSWORD != "ssh" } { "passphrase" { send "$PASSWORD\n" } } } -set timeout 180 +set timeout 360 expect { "Exit status 0" { send_user "DONE" } "scp :" { send_user "ERROR\n" ; diff --git a/oam/install_scripts/performance_installer.sh b/oam/install_scripts/performance_installer.sh index 74593c75b..bb6191c33 100644 --- a/oam/install_scripts/performance_installer.sh +++ b/oam/install_scripts/performance_installer.sh @@ -63,7 +63,7 @@ if { $PKGTYPE == "rpm" } { #check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " send "ssh -v $USERNAME@$SERVER 'time'\n" -set timeout 20 +set timeout 60 expect { "authenticity" { send "yes\n" expect { @@ -326,7 +326,7 @@ send_user "\n" # Start module installer to setup Custom OS files # send_user "Run Module Installer " -send "ssh -v $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=pm'\n" +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/module_installer.sh --module=pm'\n" if { $PASSWORD != "ssh" } { set timeout 30 expect { diff --git a/oam/install_scripts/user_installer.sh b/oam/install_scripts/user_installer.sh index 72f4ac8e8..98da8c953 100644 --- a/oam/install_scripts/user_installer.sh +++ b/oam/install_scripts/user_installer.sh @@ -62,7 +62,7 @@ if { $PKGTYPE == "rpm" } { #check and see if remote server has ssh keys setup, set PASSWORD if so send_user " " send "ssh -v $USERNAME@$SERVER 'time'\n" -set timeout 20 +set timeout 60 expect { "authenticity" { send "yes\n" expect { @@ -325,7 +325,7 @@ send_user "\n" # Start module installer to setup Custom OS files # send_user "Run Module Installer " -send "ssh -v $USERNAME@$SERVER '$BASH $INSTALLDIR/bin/module_installer.sh --module=um --port=$MYSQLPORT'\n" +send "ssh -v $USERNAME@$SERVER '$INSTALLDIR/bin/module_installer.sh --module=um --port=$MYSQLPORT'\n" if { $PASSWORD != "ssh" } { set timeout 30 expect { From 6cd2955c83f7abacee7aaf5391c679ec0a68a588 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 17 Aug 2017 16:50:39 -0500 Subject: [PATCH 141/185] removed file not found error on module_installer --- oam/install_scripts/binary_installer.sh | 13 +++---------- oam/install_scripts/performance_installer.sh | 5 ----- oam/install_scripts/user_installer.sh | 5 ----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/oam/install_scripts/binary_installer.sh b/oam/install_scripts/binary_installer.sh index 49cfc6d1d..dc63c91ee 100644 --- a/oam/install_scripts/binary_installer.sh +++ b/oam/install_scripts/binary_installer.sh @@ -216,7 +216,7 @@ if { $PASSWORD != "ssh" } { "passphrase" { send "$PASSWORD\n" } } } -set timeout 120 +set timeout 360 expect { "Exit status 0" { send_user "DONE" } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } @@ -341,16 +341,9 @@ if { $PASSWORD != "ssh" } { } set timeout 60 expect { - "!!!Module" { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing module file\n" ; exit 1 } - "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } "Exit status 0" { send_user "DONE" } + "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } + "!!!Module" { send_user "DONE" } } send_user "\n" diff --git a/oam/install_scripts/performance_installer.sh b/oam/install_scripts/performance_installer.sh index bb6191c33..86513ef47 100644 --- a/oam/install_scripts/performance_installer.sh +++ b/oam/install_scripts/performance_installer.sh @@ -339,11 +339,6 @@ expect { "Exit status 0" { send_user "DONE" } "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } "!!!Module" { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } } send_user "\n" diff --git a/oam/install_scripts/user_installer.sh b/oam/install_scripts/user_installer.sh index 98da8c953..b233ea4b8 100644 --- a/oam/install_scripts/user_installer.sh +++ b/oam/install_scripts/user_installer.sh @@ -338,11 +338,6 @@ expect { "Exit status 0" { send_user "DONE" } "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } "!!!Module" { send_user "DONE" } - "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } - "FAILED" { send_user "ERROR: missing OS file\n" ; exit 1 } - "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } - "No such file" { send_user "ERROR: File Not Found\n" ; exit 1 } - "WARNING" { send_user "WARNING: SYSLOG setup failed\n" } } send_user "\n" From 52b682c046e3914ab79255d1bc216973cc91460b Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 17 Aug 2017 18:14:46 -0500 Subject: [PATCH 142/185] Added a recursive to chown --- oam/install_scripts/syslogSetup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oam/install_scripts/syslogSetup.sh b/oam/install_scripts/syslogSetup.sh index 684b90fb6..3fcdd0bae 100755 --- a/oam/install_scripts/syslogSetup.sh +++ b/oam/install_scripts/syslogSetup.sh @@ -169,7 +169,7 @@ if [ ! -z "$syslog_conf" ] ; then if [ $rsyslog7 == 1 ]; then $SUDO rm -f /etc/rsyslog.d/49-columnstore.conf $SUDO cp ${columnstoreSyslogFile7} ${syslog_conf} - $SUDO chown syslog:adm /var/log/mariadb/columnstore >/dev/null 2>&1 + $SUDO chown -R syslog:adm /var/log/mariadb/columnstore >/dev/null 2>&1 else $SUDO cp ${columnstoreSyslogFile} ${syslog_conf} fi From 46f4b0cc8498a63a4fb70dbe95747721cc362025 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 17 Aug 2017 20:58:14 -0500 Subject: [PATCH 143/185] Added a recursive to chown --- oam/install_scripts/post-install | 2 +- oam/install_scripts/syslogSetup.sh | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 638f77eaa..bc19e3677 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -126,7 +126,7 @@ test -d /var/log/mariadb || $SUDO mkdir /var/log/mariadb >/dev/null 2>&1 test -d /var/log/mariadb/columnstore || $SUDO mkdir /var/log/mariadb/columnstore >/dev/null 2>&1 if [ $user != "root" ]; then - $SUDO chmod -R 755 /var/log/mariadb >/dev/null 2>&1 + $SUDO chmod -R 777 /var/log/mariadb >/dev/null 2>&1 $SUDO chown -R $user:$user /var/log/mariadb >/dev/null 2>&1 fi diff --git a/oam/install_scripts/syslogSetup.sh b/oam/install_scripts/syslogSetup.sh index 3fcdd0bae..1e481a109 100755 --- a/oam/install_scripts/syslogSetup.sh +++ b/oam/install_scripts/syslogSetup.sh @@ -169,11 +169,14 @@ if [ ! -z "$syslog_conf" ] ; then if [ $rsyslog7 == 1 ]; then $SUDO rm -f /etc/rsyslog.d/49-columnstore.conf $SUDO cp ${columnstoreSyslogFile7} ${syslog_conf} - $SUDO chown -R syslog:adm /var/log/mariadb/columnstore >/dev/null 2>&1 else $SUDO cp ${columnstoreSyslogFile} ${syslog_conf} fi fi + + if [ $rsyslog7 == 1 ]; then + $SUDO chown -R syslog:adm /var/log/mariadb/columnstore >/dev/null 2>&1 + fi restartSyslog fi From f1fbd42c57453977f717a89ed46ac52876c9e410 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 18 Aug 2017 14:07:29 -0500 Subject: [PATCH 144/185] Update README release update --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 3055d0c50..291da0ab7 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.0.10 -MariaDB ColumnStore 1.0.10 is the development version of MariaDB ColumnStore. +This is MariaDB ColumnStore 1.0.11 +MariaDB ColumnStore 1.0.11 is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.26 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.0.10 is an GA release. This is the first MariaDB +MariaDB ColumnStore 1.0.11 is an GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. From 42d97be88ed29016883d96a3baecafd49d996abd Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 18 Aug 2017 14:08:08 -0500 Subject: [PATCH 145/185] Update README.md release update --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e9bfed6d1..397a1b1d8 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ MariaDB ColumnStore 1.0.11 is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.26 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.0.10 is an GA release. -This is the first MariaDB ColumnStore release. +#MariaDB ColumnStore 1.0.11 is an GA release. #Building This repository is not meant to be built independently outside of the server. This repository is integrated into http://mariadb-corporation/mariadb-columnstore-server (ie, the *server*) as a git submodule. As such, you can find complete build instructions on *the server* page. From 6277371669953e000ae91ea92466d0f4907722f4 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 30 Oct 2017 13:42:31 -0500 Subject: [PATCH 146/185] MCOL-938 - fixed server-id setup on combo systems --- oam/install_scripts/rsync.sh | 40 ++++++++++++++++--------------- oamapps/postConfigure/helpers.cpp | 26 ++++++++++++++------ procmgr/processmanager.cpp | 9 ++++--- procmon/processmonitor.cpp | 15 ++++++++---- 4 files changed, 54 insertions(+), 36 deletions(-) diff --git a/oam/install_scripts/rsync.sh b/oam/install_scripts/rsync.sh index 7bbe29641..660057582 100755 --- a/oam/install_scripts/rsync.sh +++ b/oam/install_scripts/rsync.sh @@ -30,7 +30,7 @@ set COMMAND "rsync -vopgr -e ssh --exclude=mysql/ --exclude=test/ --exclude=infi # # run command # -set timeout 60 +set timeout 20 send "$COMMAND\n" expect { -re "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit -1} @@ -57,25 +57,27 @@ expect { set HOME "$env(HOME)" -set COMMAND "rsync -vopgr -e ssh $HOME/.my.cnf $USERNAME@$SERVER:$HOME/" +if {[file exist $HOME/.my.cnf]} { -# -# run command -# -set timeout 20 -send "$COMMAND\n" -expect { - -re "word: " { send "$PASSWORD\n" } - -re "passphrase" { send "$PASSWORD\n" } - -re "total size" {} abort - -re "failed" { exit 0 } - timeout { exit 0 } -} -expect { - -re "total size" {} abort - -re "failed" { exit 0 } - timeout { exit 0 } -} + set COMMAND "rsync -vopgr -e ssh $HOME/.my.cnf $USERNAME@$SERVER:$HOME/" + # + # run command + # + set timeout 10 + send "$COMMAND\n" + expect { + -re "word: " { send "$PASSWORD\n" } + -re "passphrase" { send "$PASSWORD\n" } + -re "total size" {} abort + -re "failed" { exit 0 } + timeout { exit 0 } + } + expect { + -re "total size" {} abort + -re "failed" { exit 0 } + timeout { exit 0 } + } +} exit 0 diff --git a/oamapps/postConfigure/helpers.cpp b/oamapps/postConfigure/helpers.cpp index 0bce99a7c..07507acf1 100644 --- a/oamapps/postConfigure/helpers.cpp +++ b/oamapps/postConfigure/helpers.cpp @@ -459,7 +459,9 @@ int sendReplicationRequest(int IserverTypeInstall, std::string password, std::st { // set for slave repl request // don't do PMs unless PMwithUM flag is set string moduleType = (*pt).DeviceName.substr(0,MAX_MODULE_TYPE_SIZE); - if ( moduleType == "pm" && !pmwithum ) { + + if ( ( moduleType == "pm" && !pmwithum ) && + ( IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM ) ) { pt++; continue; } @@ -678,15 +680,19 @@ void checkMysqlPort( std::string& mysqlPort, Config* sysConfig ) if ( size != 0 ) { if ( noPrompting ) { cout << endl << "The MariaDB ColumnStore port of '" + mysqlPort + "' is already in-use" << endl; - cout << "For No-prompt install, use the command line argument of 'port' to enter a different number" << endl; + cout << "Either use the command line argument of 'port' to enter a different number" << endl; + cout << "or stop the process that is using port '" + mysqlPort + "'" << endl; + cout << "For No-prompt install, exiting" << endl; exit(1); } cout << "The MariaDB ColumnStore port of '" + mysqlPort + "' is already in-use on local server" << endl; - + cout << "Either enter a different port to use" << endl; + cout << "or stop the process that is using port '" + mysqlPort + "' and enter '" + mysqlPort + "' to continue" << endl; + while(true) { - prompt = "Enter a different port number > "; + prompt = "Enter port number > "; pcommand = callReadline(prompt.c_str()); if (pcommand) { @@ -756,7 +762,9 @@ void checkSystemMySQLPort(std::string& mysqlPort, Config* sysConfig, std::string if ( size != 0 ) { if ( noPrompting ) { cout << endl << "The MariaDB ColumnStore port of '" + mysqlPort + "' is already in-use" << endl; - cout << "For No-prompt install, use the command line argument of 'port' to enter a different number" << endl; + cout << "Either use the command line argument of 'port' to enter a different number" << endl; + cout << "or stop the process that is using port '" + mysqlPort + "'" << endl; + cout << "For No-prompt install, exiting" << endl; exit(1); } else @@ -787,7 +795,9 @@ void checkSystemMySQLPort(std::string& mysqlPort, Config* sysConfig, std::string if (WEXITSTATUS(rtnCode) == 0) { if ( noPrompting ) { cout << endl << "The MariaDB ColumnStore port of '" + mysqlPort + "' is already in-use on " << remoteModuleName << endl; - cout << "For No-prompt install, use the command line argument of 'port' to enter a different number" << endl; + cout << "Either use the command line argument of 'port' to enter a different number" << endl; + cout << "or stop the process that is using port '" + mysqlPort + "'" << endl; + cout << "For No-prompt install, exiting" << endl; cout << "exiting..." << endl; exit(1); } @@ -805,10 +815,12 @@ void checkSystemMySQLPort(std::string& mysqlPort, Config* sysConfig, std::string if ( inUse ) { cout << endl << "The MariaDB ColumnStore port of '" + mysqlPort + "' is already in-use on " << inUseServer << endl; + cout << "Either enter a different port to use" << endl; + cout << "or stop the process that is using port '" + mysqlPort + "' and enter '" + mysqlPort + "' to continue" << endl; while(true) { - prompt = "Enter a different port number > "; + prompt = "Enter a port number > "; pcommand = callReadline(prompt.c_str()); if (pcommand) { diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index b7def2ac9..623281c6e 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -5440,12 +5440,11 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } //delay to give time for ProcMon to start after the config is sent and procmon restarts - log.writeLog(__LINE__, "addModule - sleep 10 - give ProcMon time to CONFIGURE and restart", LOG_TYPE_DEBUG); - sleep(10); + log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to CONFIGURE and restart", LOG_TYPE_DEBUG); + sleep(30); -// sleep(5); -// log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); -// processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); + log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); + processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); return API_SUCCESS; } diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index a4b5711bd..9e484c8c5 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -1791,7 +1791,8 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO string masterLogFile = oam::UnassignedName; string masterLogPos = oam::UnassignedName; - if ( (PMwithUM == "n") && (config.moduleType() == "pm") && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) { ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) MASTERREP; @@ -1864,7 +1865,8 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO string port; msg >> port; - if ( (PMwithUM == "n") && (config.moduleType() == "pm") && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) { ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) SLAVEREP; @@ -1911,7 +1913,8 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO string module; msg >> module; - if ( (PMwithUM == "n") && (config.moduleType() == "pm") && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) { ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) MASTERDIST; @@ -5008,7 +5011,8 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master string moduleType = systemModuleTypeConfig.moduletypeconfig[i].ModuleType; - if ( (PMwithUM == "n") && (moduleType == "pm") && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) continue; HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); @@ -5304,7 +5308,8 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul string moduleType = systemModuleTypeConfig.moduletypeconfig[i].ModuleType; - if ( (PMwithUM == "n") && (moduleType == "pm") && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) continue; DeviceNetworkList::iterator pt = systemModuleTypeConfig.moduletypeconfig[i].ModuleNetworkList.begin(); From 97eb46213b7b2b77f33963020157d5f4b1676f02 Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 30 Oct 2017 18:05:19 -0500 Subject: [PATCH 147/185] MCOL-963 reset infinidb_vtable.isNewQuery upon error. Add redo (REDO_PHASE1) counter. --- dbcon/mysql/ha_calpont_execplan.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 494763c35..a0d8ed8b1 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -2032,7 +2032,7 @@ void setError(THD* thd, uint32_t errcode, string errmsg) errcode = ER_UNKNOWN_ERROR; } thd->raise_error_printf(errcode, errmsg.c_str()); - thd->infinidb_vtable.mysql_optimizer_off = false; + thd->infinidb_vtable.isNewQuery = true; thd->infinidb_vtable.override_largeside_estimate = false; // reset expressionID if (!(thd->infinidb_vtable.cal_conn_info)) @@ -6369,8 +6369,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i } } - // populate string to be added to the select list for order by - redo = (redo || fieldVec.size() != 0); + redo = (redo || fieldVec.size() != 0); + // populate string to be added to the select list for order by for (uint32_t i = 0; i < fieldVec.size(); i++) { SimpleColumn* sc = buildSimpleColumn(fieldVec[i], gwi); @@ -6483,11 +6483,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i if (!isUnion && !gwi.hasWindowFunc && gwi.subSelectType == CalpontSelectExecutionPlan::MAIN_SELECT) { std::ostringstream vtb; - vtb << "infinidb_vtable.$vtable_" << gwi.thd->thread_id; - //vtb << "$vtable_" << gwi.thd->thread_id; + vtb << "infinidb_vtable.$vtable_" << gwi.thd->thread_id; + //vtb << "$vtable_" << gwi.thd->thread_id; // re-construct the select query and redo phase 1 if (redo) { + ++gwi.thd->infinidb_vtable.redo_count; // select now() from region case. returnedCols should have minSc. if (sel_cols_in_create.length() == 0) { From 21e031798cded4961e6daaa14f6f0b51c3fe9b7d Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 30 Oct 2017 18:07:27 -0500 Subject: [PATCH 148/185] MCOL-963 only set isNewQuery on INFINIDB_CREATE_VTABLE --- dbcon/mysql/ha_calpont_impl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 0b14822b6..5ff9002ad 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -2838,7 +2838,10 @@ int ha_calpont_impl_rnd_init(TABLE* table) // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - thd->infinidb_vtable.isNewQuery = false; + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) + { + thd->infinidb_vtable.isNewQuery = false; + } // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; @@ -3074,7 +3077,7 @@ int ha_calpont_impl_rnd_end(TABLE* table) thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; // flip back to normal state return rc; } - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 && thd->infinidb_vtable.mysql_optimizer_off) + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) return rc; if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) From aca653782a083e20f04f9cc1387a12c06d83a940 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 31 Oct 2017 11:48:48 -0500 Subject: [PATCH 149/185] change to handle both etc/rc.local and etc/rc.d/rc.local --- oam/install_scripts/module_installer.sh | 51 ++++++++++++++----------- oam/install_scripts/post-install | 27 ++++++++----- oamapps/postConfigure/installer.cpp | 2 +- oamapps/postConfigure/postConfigure.cpp | 1 - 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 514943989..07303d686 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -59,8 +59,6 @@ cloud=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation Cloud` if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then echo "Amazon setup on Module" cp $COLUMNSTORE_INSTALL_DIR/local/etc/credentials $HOME/.aws/. > /dev/null 2>&1 - sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local - sudo chmod 777 /etc/rc.d/rc.local if [ $module = "pm" ]; then if test -f $COLUMNSTORE_INSTALL_DIR/local/etc/pm1/fstab ; then @@ -88,6 +86,8 @@ mid=`module_id` #if um, cloud, separate system type, external um storage, then setup mount if [ $module = "um" ]; then if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then + $SUDO sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1 + systemtype=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation ServerTypeInstall` if [ $systemtype = "1" ]; then umstoragetype=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMStorageType` @@ -179,35 +179,42 @@ if [ $? -ne 0 ]; then fi #setup rc.local +if [ -f /etc/rc.d ]; then + RCFILE=/etc/rc.d/rc.local +else + RCFILE=/etc/rc.local +fi +touch $RCFILE + if [ $module = "um" ]; then if [ $user = "root" ]; then - echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - echo "done" >> /etc/rc.local + echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + echo "done" >> $RCFILE else - sudo chmod 666 /etc/rc.local - sudo echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - sudo echo "done" >> /etc/rc.local + sudo chmod 666 $RCFILE + sudo echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + sudo echo "done" >> $RCFILE fi else if [ $user = "root" ]; then - echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - echo "done" >> /etc/rc.local + echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + echo "done" >> $RCFILE - echo "for scsi_dev in \`mount | awk '/columnstore\\/data/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - echo "done" >> /etc/rc.local + echo "for scsi_dev in \`mount | awk '/columnstore\\/data/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + echo "done" >> $RCFILE else - sudo chmod 666 /etc/rc.local - sudo echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - sudo echo "done" >> /etc/rc.local + sudo chmod 666 $RCFILE + sudo echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + sudo echo "done" >> $RCFILE - sudo echo "for scsi_dev in \`mount | awk '/columnstore\\/data/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> /etc/rc.local - sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> /etc/rc.local - sudo echo "done" >> /etc/rc.local + sudo echo "for scsi_dev in \`mount | awk '/columnstore\\/data/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE + sudo echo "echo deadline > /sys/block/$scsi_dev/queue/scheduler" >> $RCFILE + sudo echo "done" >> $RCFILE fi fi diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index 9bf703751..ea0daba6f 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -177,14 +177,24 @@ $installdir/bin/clearShm > /dev/null 2>&1 systemctl=`which systemctl 2>/dev/null` #check and create rc.local file if missing -if [ ! -f /etc/rc.d/rc.local ]; then - printf '%s\n' '#!/bin/bash' "#" | $SUDO tee -a /etc/rc.local > /dev/null 2>&1 - $SUDO chmod +x /etc/rc.d/rc.local - - if [ -n "$systemctl" ]; then - systemctl restart rc-local >/dev/null 2>&1 - systemctl enable rc-local >/dev/null 2>&1 - fi +if [ -f /etc/rc.d ]; then + RCFILE=/etc/rc.d/rc.local +else + RCFILE=/etc/rc.local +fi + +touch $RCFILE + +if [ $user = "root" ]; then + chmod +x $RCFILE +else + $SUDO chmod 777 $RCFILE + printf '%s\n' '#!/bin/bash' "#" | $SUDO tee -a $RCFILEl > /dev/null 2>&1 +fi + +if [ -n "$systemctl" ]; then + systemctl restart rc-local >/dev/null 2>&1 + systemctl enable rc-local >/dev/null 2>&1 fi #setup the columnstore service script @@ -241,7 +251,6 @@ else $SUDO chmod 777 /var/lock/subsys > /dev/null 2>&1 $SUDO rm -f /var/lock/subsys/mysql-Columnstore $SUDO chmod 666 /etc/fstab - $SUDO chmod 777 /etc/rc.d/rc.local fi # install Columnstore Log Rotate File diff --git a/oamapps/postConfigure/installer.cpp b/oamapps/postConfigure/installer.cpp index 043af6e12..b000da61b 100644 --- a/oamapps/postConfigure/installer.cpp +++ b/oamapps/postConfigure/installer.cpp @@ -1097,7 +1097,7 @@ bool makeRClocal(string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - string fileName = "etc/rc.local"; + string fileName = "etc/rc.d/rc.local"; ofstream newFile (fileName.c_str()); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index e09e99f94..093209721 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -609,7 +609,6 @@ int main(int argc, char *argv[]) if ( !rootUser ) { system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); - system("sudo chmod 777 /etc/rc.d/rc.local >/dev/null 2>&1"); } cout << endl; From 646f330bf7ccaffa456c97a2bcf2f1a5d7d28ffb Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 31 Oct 2017 13:41:48 -0500 Subject: [PATCH 150/185] another for for rc.local --- oamapps/postConfigure/installer.cpp | 12 +++++++-- oamapps/postConfigure/postConfigure.cpp | 33 +++++++++++++------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/oamapps/postConfigure/installer.cpp b/oamapps/postConfigure/installer.cpp index b000da61b..d165e7756 100644 --- a/oamapps/postConfigure/installer.cpp +++ b/oamapps/postConfigure/installer.cpp @@ -1097,10 +1097,18 @@ bool makeRClocal(string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - string fileName = "etc/rc.d/rc.local"; + string fileName = "/etc/rc.d/rc.local"; ofstream newFile (fileName.c_str()); - + if (!newFile) + { + fileName = "/etc/rc.local"; + + ofstream newFile (fileName.c_str()); + if (!newFile) + return true; + } + //create new file int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0666); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 093209721..a88007654 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -604,13 +604,7 @@ int main(int argc, char *argv[]) if ( DistributedInstall == "n" ) nonDistribute = true; } - - // setup to start on reboot, for non-root amazon installs - if ( !rootUser ) - { - system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); - } - + cout << endl; cout << "===== Setup System Server Type Configuration =====" << endl << endl; @@ -1060,6 +1054,12 @@ int main(int argc, char *argv[]) } } + // setup to start on reboot, for non-root amazon installs + if ( !rootUser ) + { + system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); + } + if ( !writeConfig(sysConfig) ) { cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; exit(1); @@ -4000,24 +4000,25 @@ bool makeRClocal(string moduleType, string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - string fileName = "/tmp/rc.local"; + string fileName = "/etc/rc.d/rc.local"; ofstream newFile (fileName.c_str()); + if (!newFile) + { + fileName = "/etc/rc.local"; + + ofstream newFile (fileName.c_str()); + if (!newFile) + return true; + } //create new file - int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0664); + int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0666); copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); newFile.close(); close(fd); - - if (rootUser) - system("cat /tmp/rc.local >> /etc/rc.d/rc.local > /dev/null"); - else - system("sudo cat /tmp/rc.local >> /etc/rc.d/rc.local > /dev/null"); - - unlink(fileName.c_str()); return true; } From f9bdec3225cf383811fbdd6aa61754473a950221 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 2 Nov 2017 16:32:38 -0500 Subject: [PATCH 151/185] MCOL-943 - change to use defauly mysql password logic, reading from the .my.cnf file. changesfrom defaults-file to defulats-extra-file --- dbcon/mysql/install_calpont_mysql.sh | 15 ++-- .../disable-rep-columnstore.sh | 4 +- oam/install_scripts/disable-rep-infinidb.sh | 4 +- oam/install_scripts/master-rep-columnstore.sh | 8 +- oam/install_scripts/master-rep-infinidb.sh | 8 +- oam/install_scripts/module_installer.sh | 7 +- oam/install_scripts/post-mysql-install | 35 ++------- oam/install_scripts/post-mysqld-install | 2 +- oam/install_scripts/slave-rep-columnstore.sh | 8 +- oam/install_scripts/slave-rep-infinidb.sh | 8 +- oam/oamcpp/liboamcpp.cpp | 3 + oamapps/calpontSupport/approximateRowCount.sh | 2 +- oamapps/calpontSupport/getMinMax.sh | 2 +- oamapps/calpontSupport/minMaxCheck.sh | 2 +- oamapps/calpontSupport/sqlLogs.sh | 2 +- .../columnstoreSupport/approximateRowCount.sh | 2 +- .../columnstoreSupport/columnstoreSupport.cpp | 7 +- oamapps/columnstoreSupport/getMinMax.sh | 2 +- oamapps/columnstoreSupport/minMaxCheck.sh | 2 +- oamapps/columnstoreSupport/sqlLogs.sh | 2 +- oamapps/mcsadmin/mcsadmin.cpp | 2 + oamapps/postConfigure/getMySQLpw.cpp | 6 +- oamapps/postConfigure/postConfigure.cpp | 4 +- procmgr/processmanager.cpp | 51 +++++++++++- procmon/processmonitor.cpp | 78 +------------------ utils/scenarios/common/sh/execSQLScript_m.sh | 2 +- utils/scenarios/common/sh/testExecEngine.sh | 2 +- utils/scenarios/perf/sh/pfExeSQLscript.sh | 2 +- 28 files changed, 113 insertions(+), 159 deletions(-) diff --git a/dbcon/mysql/install_calpont_mysql.sh b/dbcon/mysql/install_calpont_mysql.sh index 611b50ef3..aaa17473a 100755 --- a/dbcon/mysql/install_calpont_mysql.sh +++ b/dbcon/mysql/install_calpont_mysql.sh @@ -14,9 +14,6 @@ for arg in "$@"; do installdir=$prefix/mariadb/columnstore elif [ `expr -- "$arg" : '--rpmmode='` -eq 10 ]; then rpmmode="`echo $arg | awk -F= '{print $2}'`" - elif [ `expr -- "$arg" : '--password='` -eq 11 ]; then - password="`echo $arg | awk -F= '{print $2}'`" - pwprompt="--password=$password" elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then installdir="`echo $arg | awk -F= '{print $2}'`" prefix=`dirname $installdir` @@ -27,7 +24,7 @@ done df=$installdir/mysql/my.cnf -$installdir/mysql/bin/mysql --defaults-file=$df --force --user=root $pwprompt mysql 2>/tmp/mysql_install.log </tmp/mysql_install.log </dev/null <$installdir/mysql/syscatalog_mysql.sql -$installdir/mysql/bin/mysql --defaults-file=$df --user=root $pwprompt mysql 2>/dev/null <$installdir/mysql/calsetuserpriority.sql -$installdir/mysql/bin/mysql --defaults-file=$df --user=root $pwprompt mysql 2>/dev/null <$installdir/mysql/calremoveuserpriority.sql -$installdir/mysql/bin/mysql --defaults-file=$df --user=root $pwprompt mysql 2>/dev/null <$installdir/mysql/calshowprocesslist.sql -$installdir/mysql/bin/mysql --defaults-file=$df --user=root $pwprompt mysql 2>/dev/null <$installdir/mysql/columnstore_info.sql +$installdir/mysql/bin/mysql --defaults-extra-file=$df --user=root mysql 2>/dev/null <$installdir/mysql/syscatalog_mysql.sql +$installdir/mysql/bin/mysql --defaults-extra-file=$df --user=root mysql 2>/dev/null <$installdir/mysql/calsetuserpriority.sql +$installdir/mysql/bin/mysql --defaults-extra-file=$df --user=root mysql 2>/dev/null <$installdir/mysql/calremoveuserpriority.sql +$installdir/mysql/bin/mysql --defaults-extra-file=$df --user=root mysql 2>/dev/null <$installdir/mysql/calshowprocesslist.sql +$installdir/mysql/bin/mysql --defaults-extra-file=$df --user=root mysql 2>/dev/null <$installdir/mysql/columnstore_info.sql sed -i 's/infinidb_compression_type=1/infinidb_compression_type=2/' $installdir/mysql/my.cnf >/dev/null 2>&1 diff --git a/oam/install_scripts/disable-rep-columnstore.sh b/oam/install_scripts/disable-rep-columnstore.sh index 7824304ad..0a8c9b17f 100644 --- a/oam/install_scripts/disable-rep-columnstore.sh +++ b/oam/install_scripts/disable-rep-columnstore.sh @@ -47,7 +47,7 @@ EOD cat /tmp/idb_disable-rep.sql >>/tmp/disable-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/disable-rep-status.log 2>&1 @@ -63,7 +63,7 @@ EOD cat /tmp/idb_disable-rep.sql >>/tmp/disable-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/disable-rep-status.log 2>&1 diff --git a/oam/install_scripts/disable-rep-infinidb.sh b/oam/install_scripts/disable-rep-infinidb.sh index 7da2c202e..5aacc82a2 100644 --- a/oam/install_scripts/disable-rep-infinidb.sh +++ b/oam/install_scripts/disable-rep-infinidb.sh @@ -47,7 +47,7 @@ EOD cat /tmp/idb_disable-rep.sql >>/tmp/disable-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/disable-rep-status.log @@ -63,7 +63,7 @@ EOD cat /tmp/idb_disable-rep.sql >>/tmp/disable-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/disable-rep-status.log diff --git a/oam/install_scripts/master-rep-columnstore.sh b/oam/install_scripts/master-rep-columnstore.sh index e8ccc4f4d..b811f572a 100644 --- a/oam/install_scripts/master-rep-columnstore.sh +++ b/oam/install_scripts/master-rep-columnstore.sh @@ -53,7 +53,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 @@ -71,7 +71,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 @@ -87,7 +87,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 @@ -100,7 +100,7 @@ EOD cat /tmp/idb_master-rep.sql >/tmp/show-master-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/show-master-status.log diff --git a/oam/install_scripts/master-rep-infinidb.sh b/oam/install_scripts/master-rep-infinidb.sh index 3420ac39e..cd4054773 100644 --- a/oam/install_scripts/master-rep-infinidb.sh +++ b/oam/install_scripts/master-rep-infinidb.sh @@ -53,7 +53,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log @@ -71,7 +71,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log @@ -87,7 +87,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/master-rep-status-$hostipaddr.log @@ -100,7 +100,7 @@ EOD cat /tmp/idb_master-rep.sql >/tmp/show-master-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/show-master-status.log diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 07303d686..343d022c0 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -156,12 +156,7 @@ if [ $module = "um" ] || ( [ $module = "pm" ] && [ $PMwithUM = "y" ] ) || [ $Ser fi echo "Run post-mysql-install" - password=`$COLUMNSTORE_INSTALL_DIR/bin/getMySQLpw` - if [ $password = "unassigned" ]; then - password="" - fi - - $COLUMNSTORE_INSTALL_DIR/bin/post-mysql-install --installdir=$COLUMNSTORE_INSTALL_DIR --password=$password > /tmp/post-mysql-install.log 2>&1 + $COLUMNSTORE_INSTALL_DIR/bin/post-mysql-install --installdir=$COLUMNSTORE_INSTALL_DIR > /tmp/post-mysql-install.log 2>&1 if [ $? -ne 0 ]; then echo "ERROR: post-mysql-install failed: check /tmp/post-mysql-install.log" exit 1 diff --git a/oam/install_scripts/post-mysql-install b/oam/install_scripts/post-mysql-install index f46f78bf5..08c38b84e 100755 --- a/oam/install_scripts/post-mysql-install +++ b/oam/install_scripts/post-mysql-install @@ -9,25 +9,11 @@ checkForError() { # check for password error grep "ERROR 1045" /tmp/mysql_install.log > /tmp/error.check if [ `cat /tmp/error.check | wc -c` -ne 0 ]; then - if test -f $HOME/.my.cnf ; then - password=`cat $HOME/.my.cnf | grep password | awk '{gsub(/^[ \t]+|[ \t]+$/,"");print $3}'` - if [ ! -z $password ]; then - pwprompt="-p$password" - return 1; - else - echo "MySQL Password file missing or incorrect, check .my.cnf file" - rm -f /tmp/error.check - $installdir/mysql/mysql-Columnstore stop - sleep 2 - exit 2; - fi - else - echo "MySQL Password file missing or incorrect, check .my.cnf file" - rm -f /tmp/error.check - $installdir/mysql/mysql-Columnstore stop - sleep 2 - exit 2; - fi + echo "MySQL Password file missing or incorrect, check .my.cnf file" + rm -f /tmp/error.check + $installdir/mysql/mysql-Columnstore stop + sleep 2 + exit 2; fi rm -f /tmp/error.check @@ -37,7 +23,7 @@ checkForError() { #--------------------------------------------------------------------------- echo "checking for engine columnstore..." $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ --execute='show engines;' \ calpontsys | grep -i columnstore @@ -66,11 +52,6 @@ for arg in "$@"; do installdir=$prefix/mariadb/columnstore elif [ $(expr -- "$arg" : '--rpmmode=') -eq 10 ]; then rpmmode="$(echo $arg | awk -F= '{print $2}')" - elif [ $(expr -- "$arg" : '--password=') -eq 11 ]; then - password="$(echo $arg | awk -F= '{print $2}')" - if [ ! -z $password ]; then - pwprompt="-p$password" - fi elif [ $(expr -- "$arg" : '--installdir=') -eq 13 ]; then installdir="$(echo $arg | awk -F= '{print $2}')" prefix=$(dirname $installdir) @@ -119,11 +100,11 @@ if [ -x $installdir/mysql/mysql-Columnstore ]; then sleep 5 # Install various Calpont stuff... - $installdir/mysql/install_calpont_mysql.sh --password=$password --installdir=$installdir + $installdir/mysql/install_calpont_mysql.sh --installdir=$installdir checkForError if [ $? -ne 0 ]; then # retry - $installdir/mysql/install_calpont_mysql.sh --password=$password --installdir=$installdir + $installdir/mysql/install_calpont_mysql.sh --installdir=$installdir checkForError if [ $? -ne 0 ]; then echo "ERROR: Invalid password in .my.cnf, or Columnstore plugin install missing" diff --git a/oam/install_scripts/post-mysqld-install b/oam/install_scripts/post-mysqld-install index 2624b3322..58f2b3d65 100755 --- a/oam/install_scripts/post-mysqld-install +++ b/oam/install_scripts/post-mysqld-install @@ -69,7 +69,7 @@ fi test -x /usr/local/bin/idb-testing-mysql-pre-start && /usr/local/bin/idb-testing-mysql-pre-start $installdir/mysql ### Don't give the user the notes, we'll fix them ourselves... -$installdir/mysql/scripts/mysql_install_db --rpm --user=$user --defaults-file=$installdir/mysql/my.cnf --basedir=$installdir/mysql >/dev/null +$installdir/mysql/scripts/mysql_install_db --rpm --user=$user --defaults-extra-file=$installdir/mysql/my.cnf --basedir=$installdir/mysql >/dev/null # Change permissions again to fix any new files. chown -R $user:$user $mysql_datadir diff --git a/oam/install_scripts/slave-rep-columnstore.sh b/oam/install_scripts/slave-rep-columnstore.sh index e3318f8a2..612427f46 100644 --- a/oam/install_scripts/slave-rep-columnstore.sh +++ b/oam/install_scripts/slave-rep-columnstore.sh @@ -58,7 +58,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log 2>&1 @@ -81,7 +81,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log 2>&1 @@ -97,7 +97,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log 2>&1 @@ -113,7 +113,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log 2>&1 diff --git a/oam/install_scripts/slave-rep-infinidb.sh b/oam/install_scripts/slave-rep-infinidb.sh index f48f84527..d9d41def6 100644 --- a/oam/install_scripts/slave-rep-infinidb.sh +++ b/oam/install_scripts/slave-rep-infinidb.sh @@ -58,7 +58,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log @@ -80,7 +80,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log @@ -94,7 +94,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log @@ -108,7 +108,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ - --defaults-file=$installdir/mysql/my.cnf \ + --defaults-extra-file=$installdir/mysql/my.cnf \ --user=root $pwprompt \ calpontsys >/tmp/slave-rep-status.log diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index 9a92ec9c3..d0c3764eb 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -8770,6 +8770,9 @@ namespace oam ******************************************************************************************/ std::string Oam::getMySQLPassword() { + + return oam::UnassignedName; + string mysqlUser = "root"; string USER = "root"; diff --git a/oamapps/calpontSupport/approximateRowCount.sh b/oamapps/calpontSupport/approximateRowCount.sh index a1a2bfc62..13cea4582 100755 --- a/oamapps/calpontSupport/approximateRowCount.sh +++ b/oamapps/calpontSupport/approximateRowCount.sh @@ -11,7 +11,7 @@ if [ -z "$MYSQLCMD" ]; then INSTALLDIR="/usr/local/mariadb/columnstore" MYSQLCNF=$INSTALLDIR/mysql/my.cnf - MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-file=$MYSQLCNF -u root" + MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-extra-file=$MYSQLCNF -u root" fi # diff --git a/oamapps/calpontSupport/getMinMax.sh b/oamapps/calpontSupport/getMinMax.sh index aab502da1..9a95e518d 100755 --- a/oamapps/calpontSupport/getMinMax.sh +++ b/oamapps/calpontSupport/getMinMax.sh @@ -11,7 +11,7 @@ if [ -z "$MYSQLCMD" ]; then INSTALLDIR="/usr/local/mariadb/columnstore" MYSQLCNF=$INSTALLDIR/mysql/my.cnf - MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-file=$MYSQLCNF -u root" + MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-extra-file=$MYSQLCNF -u root" fi # diff --git a/oamapps/calpontSupport/minMaxCheck.sh b/oamapps/calpontSupport/minMaxCheck.sh index 4aab0f31e..4e36db272 100755 --- a/oamapps/calpontSupport/minMaxCheck.sh +++ b/oamapps/calpontSupport/minMaxCheck.sh @@ -45,7 +45,7 @@ # if [ -z "$MYSQLCMD" ]; then - MYSQLCMD="/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root" + MYSQLCMD="/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root" fi if [ -z "$INSTALLDIR" ]; then diff --git a/oamapps/calpontSupport/sqlLogs.sh b/oamapps/calpontSupport/sqlLogs.sh index bc8b5b1c4..a1a9a403c 100755 --- a/oamapps/calpontSupport/sqlLogs.sh +++ b/oamapps/calpontSupport/sqlLogs.sh @@ -19,7 +19,7 @@ fi if [ -z "$MYSQLCMD" ]; then - MYSQLCMD="$COLUMNSTORE_INSTALL_DIR/mysql/bin/mysql --defaults-file=$COLUMNSTORE_INSTALL_DIR/mysql/my.cnf -u root" + MYSQLCMD="$COLUMNSTORE_INSTALL_DIR/mysql/bin/mysql --defaults-extra-file=$COLUMNSTORE_INSTALL_DIR/mysql/my.cnf -u root" export MYSQLCMD fi diff --git a/oamapps/columnstoreSupport/approximateRowCount.sh b/oamapps/columnstoreSupport/approximateRowCount.sh index 9b5a356be..db1deb425 100755 --- a/oamapps/columnstoreSupport/approximateRowCount.sh +++ b/oamapps/columnstoreSupport/approximateRowCount.sh @@ -11,7 +11,7 @@ if [ -z "$MYSQLCMD" ]; then INSTALLDIR="/usr/local/mariadb/columnstore" MYSQLCNF=$INSTALLDIR/mysql/my.cnf - MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-file=$MYSQLCNF -u root" + MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-extra-file=$MYSQLCNF -u root" fi # diff --git a/oamapps/columnstoreSupport/columnstoreSupport.cpp b/oamapps/columnstoreSupport/columnstoreSupport.cpp index ca514fc41..c09280ad1 100644 --- a/oamapps/columnstoreSupport/columnstoreSupport.cpp +++ b/oamapps/columnstoreSupport/columnstoreSupport.cpp @@ -423,7 +423,7 @@ int main(int argc, char *argv[]) cout << "It should be run on the server with the DBRM front-end." << endl; cout << "Check the Admin Guide for additional information." << endl; cout << endl; - cout << "Usage: columnstoreSupport [-h][-a][-hw][-s][-c][-db][-r][-l][-bl][-lc][-p 'root-password'][-mp 'mariadb-columnstore-root-password'][-de]"; + cout << "Usage: columnstoreSupport [-h][-a][-hw][-s][-c][-db][-r][-l][-bl][-lc][-p 'root-password'][-de]"; // if hdfs set up print the hadoop option if (!DataFilePlugin.empty()) cout << "[-hd]"; @@ -439,7 +439,6 @@ int main(int argc, char *argv[]) cout << " -bl Output Columnstore Bulk Log Reports only" << endl; cout << " -lc Output Reports for Local Server only" << endl; cout << " -p password (multi-server systems), root-password or 'ssh' to use 'ssh keys'" << endl; - cout << " -mp MariaDB Columnstore root user password" << endl; cout << " -de Debug Flag" << endl; // if hdfs set up print the hadoop option if (!DataFilePlugin.empty()) @@ -783,7 +782,7 @@ int main(int argc, char *argv[]) else { // check if mysql is supported and get info - string columnstoreMysql = installDir + "/mysql/bin/mysql --defaults-file=" + installDir + "/mysql/my.cnf -u root "; + string columnstoreMysql = installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root "; string cmd = columnstoreMysql + " -e 'status' > /tmp/idbmysql.log 2>&1"; system(cmd.c_str()); @@ -846,7 +845,7 @@ int main(int argc, char *argv[]) if (!FAILED) { // check if mysql is supported and get info - string columnstoreMysql = installDir + "/mysql/bin/mysql --defaults-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt; + string columnstoreMysql = installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt; string cmd = columnstoreMysql + " -V > /dev/null 2>&1"; int ret = system(cmd.c_str()); if ( WEXITSTATUS(ret) == 0) { diff --git a/oamapps/columnstoreSupport/getMinMax.sh b/oamapps/columnstoreSupport/getMinMax.sh index 58faeeb3c..90434680d 100755 --- a/oamapps/columnstoreSupport/getMinMax.sh +++ b/oamapps/columnstoreSupport/getMinMax.sh @@ -11,7 +11,7 @@ if [ -z "$MYSQLCMD" ]; then INSTALLDIR="/usr/local/mariadb/columnstore" MYSQLCNF=$INSTALLDIR/mysql/my.cnf - MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-file=$MYSQLCNF -u root" + MYSQLCMD="$INSTALLDIR/mysql/bin/mysql --defaults-extra-file=$MYSQLCNF -u root" fi # diff --git a/oamapps/columnstoreSupport/minMaxCheck.sh b/oamapps/columnstoreSupport/minMaxCheck.sh index 4aab0f31e..4e36db272 100755 --- a/oamapps/columnstoreSupport/minMaxCheck.sh +++ b/oamapps/columnstoreSupport/minMaxCheck.sh @@ -45,7 +45,7 @@ # if [ -z "$MYSQLCMD" ]; then - MYSQLCMD="/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root" + MYSQLCMD="/usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root" fi if [ -z "$INSTALLDIR" ]; then diff --git a/oamapps/columnstoreSupport/sqlLogs.sh b/oamapps/columnstoreSupport/sqlLogs.sh index 5a06a76ea..385b2d912 100755 --- a/oamapps/columnstoreSupport/sqlLogs.sh +++ b/oamapps/columnstoreSupport/sqlLogs.sh @@ -19,7 +19,7 @@ fi if [ -z "$MYSQLCMD" ]; then - MYSQLCMD="$COLUMNSTORE_INSTALL_DIR/mysql/bin/mysql --defaults-file=$COLUMNSTORE_INSTALL_DIR/mysql/my.cnf -u root" + MYSQLCMD="$COLUMNSTORE_INSTALL_DIR/mysql/bin/mysql --defaults-extra-file=$COLUMNSTORE_INSTALL_DIR/mysql/my.cnf -u root" export MYSQLCMD fi diff --git a/oamapps/mcsadmin/mcsadmin.cpp b/oamapps/mcsadmin/mcsadmin.cpp index 0671bff19..93dd701df 100644 --- a/oamapps/mcsadmin/mcsadmin.cpp +++ b/oamapps/mcsadmin/mcsadmin.cpp @@ -6122,6 +6122,8 @@ int processCommand(string* arguments) { cout << endl << "**** disableRep Failed : " << e.what() << endl; } + + cout << endl; break; } diff --git a/oamapps/postConfigure/getMySQLpw.cpp b/oamapps/postConfigure/getMySQLpw.cpp index c47774af5..56c52078b 100644 --- a/oamapps/postConfigure/getMySQLpw.cpp +++ b/oamapps/postConfigure/getMySQLpw.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2014 InfiniDB, Inc. - + Copyright (C) 2017 MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of @@ -56,6 +56,10 @@ using namespace oam; int main(int argc, char *argv[]) { Oam oam; + + cout << oam::UnassignedName << endl; + + exit (0); string USER = "root"; char* p= getenv("USER"); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index a88007654..571c7ded6 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2971,7 +2971,7 @@ int main(int argc, char *argv[]) } //try to login - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) != 0) { cout << endl << "Error returned from remote_command.sh" << endl; @@ -3003,7 +3003,7 @@ int main(int argc, char *argv[]) pwprompt = "--password=" + mysqlpw; } - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) != 0) { cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 623281c6e..c99662d3a 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -2567,7 +2567,7 @@ void processMSG(messageqcpp::IOSocket* cfIos) // target = root password oam::DeviceNetworkList devicenetworklist; - status = processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, target, false); + status = processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, false, target, false); log.writeLog(__LINE__, "Disable MySQL Replication status: " + oam.itoa(status) ); @@ -3439,6 +3439,9 @@ void ProcessManager::recycleProcess(string module) //restart ExeMgrs/mysql if module is a pm if ( moduleType == "pm" ) { +// restartProcessType("DBRMWorkerNode"); +// restartProcessType("PrimProc"); +// restartProcessType("WriteEngineServer"); restartProcessType("ExeMgr"); restartProcessType("mysql"); } @@ -3448,20 +3451,60 @@ void ProcessManager::recycleProcess(string module) if ( PrimaryUMModuleName == module ) { restartProcessType("DDLProc", module); -// restartProcessType("DDLProc", module, false); sleep(1); restartProcessType("DMLProc", module); -// restartProcessType("DMLProc", module, false); } if( moduleType == "pm" && PrimaryUMModuleName != module) { +// restartProcessType("DBRMControllerNode", module); +// sleep(1); reinitProcessType("DDLProc"); sleep(1); restartProcessType("DMLProc", module); -// restartProcessType("DMLProc", module, false); } + + //wait for DMLProc to go ACTIVE +/* uint16_t rtn = 0; + bool bfirst = true; + while (rtn == 0) + { + ProcessStatus DMLprocessstatus; + try { + oam.getProcessStatus("DMLProc", PrimaryUMModuleName, DMLprocessstatus); + } + catch (exception& ex) + { +// string error = ex.what(); +// log.writeLog(__LINE__, "EXCEPTION ERROR on getProcessStatus: " + error, LOG_TYPE_ERROR); + } + catch(...) + { +// log.writeLog(__LINE__, "EXCEPTION ERROR on getProcessStatus: Caught unknown exception!", LOG_TYPE_ERROR); + } + if (DMLprocessstatus.ProcessOpState == oam::BUSY_INIT) { + if (bfirst) + { + log.writeLog(__LINE__, "Waiting for DMLProc to finish rollback" , LOG_TYPE_INFO); + bfirst = false; + } + } + + if (DMLprocessstatus.ProcessOpState == oam::ACTIVE) { + rtn = oam::ACTIVE; + break; + } + + if (DMLprocessstatus.ProcessOpState == oam::FAILED) { + rtn = oam::FAILED; + break; + } + + // wait some more + sleep(2); + } +*/ return; } diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 9e484c8c5..82e74a1cd 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -4970,17 +4970,6 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master log.writeLog(__LINE__, "runMasterRep function called", LOG_TYPE_DEBUG); - //get mysql user password - string mysqlpw = oam::UnassignedName; - try { - mysqlpw = oam.getMySQLPassword(); - } - catch (...) - {} - - if ( mysqlpw == oam::UnassignedName ) - mysqlpw = ""; - SystemModuleTypeConfig systemModuleTypeConfig; try { oam.getSystemConfig(systemModuleTypeConfig); @@ -5023,8 +5012,7 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master string ipAddr = (*pt1).IPAddr; string logFile = "/tmp/master-rep-columnstore-" + moduleName + ".log"; - string cmd = startup::StartUp::installDir() + "/bin/master-rep-columnstore.sh --password=" + - mysqlpw + " --installdir=" + startup::StartUp::installDir() + " --hostIP=" + ipAddr + " > " + logFile + " 2>&1"; + string cmd = startup::StartUp::installDir() + "/bin/master-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --hostIP=" + ipAddr + " > " + logFile + " 2>&1"; log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); system(cmd.c_str()); @@ -5050,24 +5038,8 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master } } } - - //got check for password and bypass config check - if ( passwordError ) - { - try { - mysqlpw = oam.getMySQLPassword(); - } - catch (...) - {} - if ( mysqlpw == oam::UnassignedName ) - { - log.writeLog(__LINE__, "master-rep-columnstore.sh: MySQL Password Error", LOG_TYPE_ERROR); - return oam::API_FAILURE; - } - } - else - break; + break; } } } @@ -5140,17 +5112,6 @@ int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterL log.writeLog(__LINE__, "runSlaveRep function called", LOG_TYPE_DEBUG); - //get mysql user password - string mysqlpw = oam::UnassignedName; - try { - mysqlpw = oam.getMySQLPassword(); - } - catch (...) - {} - - if ( mysqlpw == oam::UnassignedName ) - mysqlpw = ""; - // get master replicaion module IP Address string PrimaryUMModuleName; oam.getSystemConfig("PrimaryUMModuleName", PrimaryUMModuleName); @@ -5169,8 +5130,7 @@ int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterL bool passwordError = false; while(true) { - string cmd = startup::StartUp::installDir() + "/bin/slave-rep-columnstore.sh --password=" + - mysqlpw + " --installdir=" + startup::StartUp::installDir() + " --masteripaddr=" + masterIPAddress + " --masterlogfile=" + masterLogFile + " --masterlogpos=" + masterLogPos + + " --port=" + port + " > /tmp/slave-rep-columnstore.log 2>&1"; + string cmd = startup::StartUp::installDir() + "/bin/slave-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --masteripaddr=" + masterIPAddress + " --masterlogfile=" + masterLogFile + " --masterlogpos=" + masterLogPos + + " --port=" + port + " > /tmp/slave-rep-columnstore.log 2>&1"; log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); @@ -5200,24 +5160,6 @@ int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterL return oam::API_FAILURE; } } - - //got check for password and bypass config check - if ( passwordError ) - { - try { - mysqlpw = oam.getMySQLPassword(); - } - catch (...) - {} - - if ( mysqlpw == oam::UnassignedName ) - { - log.writeLog(__LINE__, "slave-rep-columnstore.sh: MySQL Password Error", LOG_TYPE_ERROR); - return oam::API_FAILURE; - } - } - else - break; } return oam::API_FAILURE; @@ -5235,19 +5177,7 @@ int ProcessMonitor::runDisableRep() log.writeLog(__LINE__, "runDisableRep function called", LOG_TYPE_DEBUG); - //get mysql user password - string mysqlpw = oam::UnassignedName; - try { - mysqlpw = oam.getMySQLPassword(); - } - catch (...) - {} - - if ( mysqlpw == oam::UnassignedName ) - mysqlpw = ""; - - string cmd = startup::StartUp::installDir() + "/bin/disable-rep-columnstore.sh --password=" + - mysqlpw + " --installdir=" + startup::StartUp::installDir() + " > /tmp/disable-rep-columnstore.log 2>&1"; + string cmd = startup::StartUp::installDir() + "/bin/disable-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " > /tmp/disable-rep-columnstore.log 2>&1"; log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); diff --git a/utils/scenarios/common/sh/execSQLScript_m.sh b/utils/scenarios/common/sh/execSQLScript_m.sh index da731b527..f742c1a66 100755 --- a/utils/scenarios/common/sh/execSQLScript_m.sh +++ b/utils/scenarios/common/sh/execSQLScript_m.sh @@ -22,5 +22,5 @@ # # Execute script on test database # - /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -f -u root $1 <$6 > $logFileName.test.log 2>&1 + /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -f -u root $1 <$6 > $logFileName.test.log 2>&1 diff $logFileName.ref.log $logFileName.test.log > $logFileName.diff.log diff --git a/utils/scenarios/common/sh/testExecEngine.sh b/utils/scenarios/common/sh/testExecEngine.sh index f618b3998..8136ed3e1 100755 --- a/utils/scenarios/common/sh/testExecEngine.sh +++ b/utils/scenarios/common/sh/testExecEngine.sh @@ -186,7 +186,7 @@ function execOneTestRun { fi if [ $dbmsType = "M" ]; then pathSfn=$1\/$sess - /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root $testDB <$sfn 2> $pathSfn\/$sfn.err.log |grep "^Calpont" > $pathSfn\/$sfn.log & + /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root $testDB <$sfn 2> $pathSfn\/$sfn.err.log |grep "^Calpont" > $pathSfn\/$sfn.log & else su - oracle -c "sqlplus /nolog @/home/qa/srv/common/script/callogin.sql $testDB $testDB xe srvqaperf2 <$sfn" |grep "^Calpont" > $1\/$sess\/$sfn.log & fi diff --git a/utils/scenarios/perf/sh/pfExeSQLscript.sh b/utils/scenarios/perf/sh/pfExeSQLscript.sh index 8b80bc1cf..8b8064a51 100755 --- a/utils/scenarios/perf/sh/pfExeSQLscript.sh +++ b/utils/scenarios/perf/sh/pfExeSQLscript.sh @@ -19,5 +19,5 @@ # # Execute script on test database # - /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root $1 <$2 > $logFileName.test.log + /usr/local/mariadb/columnstore/mysql/bin/mysql --defaults-extra-file=/usr/local/mariadb/columnstore/mysql/my.cnf -u root $1 <$2 > $logFileName.test.log exit 0 From d548793c7c089ee12458b6345d4d0f038096b367 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 3 Nov 2017 10:04:26 -0500 Subject: [PATCH 152/185] add sudo to systemctl for amazon non-root --- oam/install_scripts/post-install | 5 +++-- oam/install_scripts/pre-uninstall | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/oam/install_scripts/post-install b/oam/install_scripts/post-install index ea0daba6f..bd3d3fb55 100755 --- a/oam/install_scripts/post-install +++ b/oam/install_scripts/post-install @@ -193,8 +193,8 @@ else fi if [ -n "$systemctl" ]; then - systemctl restart rc-local >/dev/null 2>&1 - systemctl enable rc-local >/dev/null 2>&1 + $SUDO systemctl restart rc-local >/dev/null 2>&1 + $SUDO systemctl enable rc-local >/dev/null 2>&1 fi #setup the columnstore service script @@ -228,6 +228,7 @@ if [ $user = "root" ]; then fi fi fi + #setup MariaDB Columnstore system logging sed -i -e s/groupname/$user/g $installdir/bin/columnstoreSyslog7 sed -i -e s/username/$user/g $installdir/bin/columnstoreSyslog7 diff --git a/oam/install_scripts/pre-uninstall b/oam/install_scripts/pre-uninstall index 73efa387f..2f58b5421 100755 --- a/oam/install_scripts/pre-uninstall +++ b/oam/install_scripts/pre-uninstall @@ -72,7 +72,7 @@ $installdir/bin/clearShm > /dev/null 2>&1 $SUDO rm -f /etc/cron.d/ps > /dev/null 2>&1 $SUDO rm -f /etc/pscollect > /dev/null 2>&1 $SUDO /etc/init.d/crond reload > /dev/null 2>&1 -$SUDO $SUDO systemctl reload crond.service > /dev/null 2>&1 +$SUDO systemctl reload crond.service > /dev/null 2>&1 # delete tmp files rm -f $installdir/local/*.columnstore From 16b4107f65f518787341f5f5e10f26ae0edf2859 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 3 Nov 2017 13:44:15 -0500 Subject: [PATCH 153/185] change release version --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index feb1bb22e..0d999bdf3 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.1.0 Beta -MariaDB ColumnStore 1.1.0 Beta is the development version of MariaDB ColumnStore. -It is built by porting InfiniDB 4.6.7 on MariaDB 10.1.21 and adding entirely +#MariaDB ColumnStore Storage/Execution engine 1.1.1 RC +MariaDB ColumnStore 1.1.1 RC is the development version of MariaDB ColumnStore. +It is built by porting InfiniDB 4.6.7 on MariaDB 10.2.9 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.1.0 is an Beta release. +#MariaDB ColumnStore 1.1.1 is an RC release. - Do not use Beta releases on production systems. From 2cc3fe6cacf73c685a9e795c9df210bde110e46f Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 3 Nov 2017 13:45:01 -0500 Subject: [PATCH 154/185] changed release version --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index d64fa8bca..b8ad2c1f2 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.1.0 Beta -MariaDB ColumnStore 1.1.0Beta is the development version of MariaDB ColumnStore. +This is MariaDB ColumnStore 1.1.1 RC +MariaDB ColumnStore 1.1.1 RC is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.2 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.1.0 is a Beta release. This is the first MariaDB +MariaDB ColumnStore 1.1.1 is a RC release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. From 93f8a59adedfc3231f36624d62e748b6b84d4e55 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 6 Nov 2017 08:35:01 -0600 Subject: [PATCH 155/185] change version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6830abc60..7eb0690ea 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=1 -COLUMNSTORE_VERSION_PATCH=1 +COLUMNSTORE_VERSION_PATCH=2 COLUMNSTORE_VERSION_RELEASE=1 From 43a646581181cac474f2c1df3784016eb1e867c1 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 6 Nov 2017 08:35:54 -0600 Subject: [PATCH 156/185] add a writeconfig after mysqlrep --- oamapps/postConfigure/postConfigure.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 571c7ded6..cc410e86a 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -883,6 +883,11 @@ int main(int argc, char *argv[]) catch(...) {} + if ( !writeConfig(sysConfig) ) { + cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; + exit(1); + } + break; } } @@ -1058,6 +1063,7 @@ int main(int argc, char *argv[]) if ( !rootUser ) { system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); + system("sudo chmod 666 /etc/fstab >/dev/null 2>&1"); } if ( !writeConfig(sysConfig) ) { From 3589563cc381d99f2967146ac92dd274ed54458a Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 6 Nov 2017 08:42:43 -0600 Subject: [PATCH 157/185] Update README.md updated version --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d999bdf3..5ed765d0f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.1.1 RC -MariaDB ColumnStore 1.1.1 RC is the development version of MariaDB ColumnStore. +#MariaDB ColumnStore Storage/Execution engine 1.1.2 GA +MariaDB ColumnStore 1.1.2 GA is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.2.9 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.1.1 is an RC release. +#MariaDB ColumnStore 1.1.2 is an GA release. - Do not use Beta releases on production systems. From 6062ac034f05923aa9664e8b07f203e98c3348b3 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 6 Nov 2017 08:43:16 -0600 Subject: [PATCH 158/185] Update README updated version --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index b8ad2c1f2..8e42cd701 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.1.1 RC -MariaDB ColumnStore 1.1.1 RC is the development version of MariaDB ColumnStore. +This is MariaDB ColumnStore 1.1.2 GA +MariaDB ColumnStore 1.1.2 GA is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.2 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.1.1 is a RC release. This is the first MariaDB +MariaDB ColumnStore 1.1.2 is a GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. From 4f63212145523b24fd79211abbcd6931aec7dc67 Mon Sep 17 00:00:00 2001 From: david hill Date: Mon, 6 Nov 2017 17:46:07 -0600 Subject: [PATCH 159/185] mcol-1009 and mcol-1014 --- dbcon/mysql/my.cnf | 2 +- dbcon/mysql/mysql-Columnstore | 7 +- oam/etc/Columnstore.xml | 2 +- oam/install_scripts/CMakeLists.txt | 1 + oam/install_scripts/mariadb-command-line.sh | 59 +++ oam/install_scripts/master-rep-columnstore.sh | 11 +- oam/install_scripts/slave-rep-columnstore.sh | 11 +- oamapps/postConfigure/helpers.cpp | 5 +- oamapps/postConfigure/helpers.h | 2 +- oamapps/postConfigure/postConfigure.cpp | 2 +- procmgr/processmanager.cpp | 21 +- procmon/processmonitor.cpp | 477 +++++++++--------- procmon/processmonitor.h | 10 +- 13 files changed, 333 insertions(+), 277 deletions(-) create mode 100644 oam/install_scripts/mariadb-command-line.sh diff --git a/dbcon/mysql/my.cnf b/dbcon/mysql/my.cnf index d4f595062..bdbe7ef26 100644 --- a/dbcon/mysql/my.cnf +++ b/dbcon/mysql/my.cnf @@ -53,7 +53,7 @@ infinidb_compression_type=2 infinidb_stringtable_threshold=20 # infinidb local query flag -# infinidb_local_query=1 +infinidb_local_query=0 infinidb_diskjoin_smallsidelimit=0 infinidb_diskjoin_largesidelimit=0 diff --git a/dbcon/mysql/mysql-Columnstore b/dbcon/mysql/mysql-Columnstore index a0c8bca23..b49c646e2 100755 --- a/dbcon/mysql/mysql-Columnstore +++ b/dbcon/mysql/mysql-Columnstore @@ -61,7 +61,7 @@ datadir=$basedir/db # Value here is overriden by value in my.cnf. # 0 means don't wait at all # Negative numbers mean to wait indefinitely -service_startup_timeout=30 +service_startup_timeout=60 # Lock directory for RedHat / SuSE. lockdir='/var/lock/subsys' @@ -262,6 +262,8 @@ wait_for_gone () { done log_failure_msg + kill_by_pid + return 1 } @@ -310,7 +312,7 @@ fi kill_by_pid() { # let's see if we can kill the 2 mysql procs by hand # get the our mysql from ps - eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql//bin/mysqld" | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') + eval $(ps -ef | grep "$COLUMNSTORE_INSTALL_DIR/mysql/bin/mysqld" | grep -v grep | head -1 | awk '{printf "pid=%d\n", $2}') if [ -n "$pid" ]; then ppid=$(ps -o ppid= -p $pid) @@ -369,6 +371,7 @@ case "$mode" in wait_for_gone $mysqld_pid "$mysqld_pid_file_path"; return_value=$? else log_failure_msg "MySQL server process #$mysqld_pid is not running!" + kill_by_pid rm "$mysqld_pid_file_path" fi diff --git a/oam/etc/Columnstore.xml b/oam/etc/Columnstore.xml index 6efa3f8aa..14098fb28 100644 --- a/oam/etc/Columnstore.xml +++ b/oam/etc/Columnstore.xml @@ -226,7 +226,7 @@ C columnstore-1 - unassigned + pm1 unassigned unassigned 1 diff --git a/oam/install_scripts/CMakeLists.txt b/oam/install_scripts/CMakeLists.txt index 6b7296c54..d450d7f27 100644 --- a/oam/install_scripts/CMakeLists.txt +++ b/oam/install_scripts/CMakeLists.txt @@ -33,6 +33,7 @@ install(PROGRAMS post-install myCnf-include-args.text myCnf-exclude-args.text columnstore.service + mariadb-command-line.sh DESTINATION ${ENGINE_BINDIR} COMPONENT platform) install(FILES module DESTINATION ${ENGINE_LOCALDIR} COMPONENT platform) diff --git a/oam/install_scripts/mariadb-command-line.sh b/oam/install_scripts/mariadb-command-line.sh new file mode 100644 index 000000000..bb2750581 --- /dev/null +++ b/oam/install_scripts/mariadb-command-line.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# +# $Id$ +# +# generic MariaDB Columnstore Command Line script. +# +# Notes: This script gets run by ProcMon during installs and upgrades: + +# check log for error +checkForError() { + grep ERROR /tmp/mariadb-command-line.log > /tmp/error.check + if [ `cat /tmp/error.check | wc -c` -ne 0 ]; then + echo "ERROR: check log file: /tmp/mariadb-command-line.log" + rm -f /tmp/error.check + exit 1 + fi + rm -f /tmp/error.check +} + +prefix=/usr/local +installdir=$prefix/mariadb/columnstore +pwprompt= +for arg in "$@"; do + if [ `expr -- "$arg" : '--command='` -eq 10 ]; then + command1="`echo $arg | awk -F= '{print $2}'`" + command2="`echo $arg | awk -F= '{print $3}'`" + command=$command1"="$command2 + elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then + installdir="`echo $arg | awk -F= '{print $2}'`" + prefix=`dirname $installdir` + elif [ `expr -- "$arg" : '--port='` -eq 7 ]; then + port="`echo $arg | awk -F= '{print $2}'`" + fi +done + +test -f $installdir/post/functions && . $installdir/post/functions + + +>/tmp/mariadb-command-line.log + +# +# Run command +# +echo "Run command" >>/tmp/mariadb-command-line.log +cat >/tmp/mariadb-command-line.sql <> /tmp/mariadb-command-line.log +$installdir/mysql/bin/mysql \ + --defaults-extra-file=$installdir/mysql/my.cnf \ + --user=root \ + calpontsys < /tmp/mariadb-command-line.sql >> /tmp/mariadb-command-line.log 2>&1 + +checkForError + +#alls good, 'OK' for success +echo "OK" +exit 0 diff --git a/oam/install_scripts/master-rep-columnstore.sh b/oam/install_scripts/master-rep-columnstore.sh index b811f572a..5d27ee278 100644 --- a/oam/install_scripts/master-rep-columnstore.sh +++ b/oam/install_scripts/master-rep-columnstore.sh @@ -24,9 +24,6 @@ for arg in "$@"; do if [ `expr -- "$arg" : '--prefix='` -eq 9 ]; then prefix="`echo $arg | awk -F= '{print $2}'`" installdir=$prefix/mariadb/columnstore - elif [ `expr -- "$arg" : '--password='` -eq 11 ]; then - password="`echo $arg | awk -F= '{print $2}'`" - pwprompt="--password=$password" elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then installdir="`echo $arg | awk -F= '{print $2}'`" prefix=`dirname $installdir` @@ -54,7 +51,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 checkForError @@ -72,7 +69,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 checkForError @@ -88,7 +85,7 @@ EOD cat /tmp/idb_master-rep.sql >>/tmp/master-rep-status-$hostipaddr.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/master-rep-status-$hostipaddr.log 2>&1 checkForError @@ -101,7 +98,7 @@ EOD cat /tmp/idb_master-rep.sql >/tmp/show-master-status.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/show-master-status.log diff --git a/oam/install_scripts/slave-rep-columnstore.sh b/oam/install_scripts/slave-rep-columnstore.sh index 612427f46..ae8914237 100644 --- a/oam/install_scripts/slave-rep-columnstore.sh +++ b/oam/install_scripts/slave-rep-columnstore.sh @@ -24,9 +24,6 @@ for arg in "$@"; do if [ `expr -- "$arg" : '--prefix='` -eq 9 ]; then prefix="`echo $arg | awk -F= '{print $2}'`" installdir=$prefix/mariadb/columnstore - elif [ `expr -- "$arg" : '--password='` -eq 11 ]; then - password="`echo $arg | awk -F= '{print $2}'`" - pwprompt="--password=$password" elif [ `expr -- "$arg" : '--installdir='` -eq 13 ]; then installdir="`echo $arg | awk -F= '{print $2}'`" prefix=`dirname $installdir` @@ -59,7 +56,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/slave-rep-status.log 2>&1 checkForError @@ -82,7 +79,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/slave-rep-status.log 2>&1 checkForError @@ -98,7 +95,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/slave-rep-status.log 2>&1 checkForError @@ -114,7 +111,7 @@ EOD cat /tmp/idb_slave-rep.sql >>/tmp/slave-rep-status.log $installdir/mysql/bin/mysql \ --defaults-extra-file=$installdir/mysql/my.cnf \ - --user=root $pwprompt \ + --user=root \ calpontsys >/tmp/slave-rep-status.log 2>&1 checkForError diff --git a/oamapps/postConfigure/helpers.cpp b/oamapps/postConfigure/helpers.cpp index 07507acf1..3d84496ed 100644 --- a/oamapps/postConfigure/helpers.cpp +++ b/oamapps/postConfigure/helpers.cpp @@ -368,7 +368,7 @@ int sendUpgradeRequest(int IserverTypeInstall, bool pmwithum) * * ******************************************************************************************/ -int sendReplicationRequest(int IserverTypeInstall, std::string password, std::string port, bool pmwithum) +int sendReplicationRequest(int IserverTypeInstall, std::string password, bool pmwithum) { Oam oam; @@ -459,7 +459,7 @@ int sendReplicationRequest(int IserverTypeInstall, std::string password, std::st { // set for slave repl request // don't do PMs unless PMwithUM flag is set string moduleType = (*pt).DeviceName.substr(0,MAX_MODULE_TYPE_SIZE); - + if ( ( moduleType == "pm" && !pmwithum ) && ( IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM ) ) { pt++; @@ -476,7 +476,6 @@ int sendReplicationRequest(int IserverTypeInstall, std::string password, std::st msg << masterLogFile; msg << masterLogPos; - msg << port; returnStatus = sendMsgProcMon( (*pt).DeviceName, msg, requestID, 30 ); diff --git a/oamapps/postConfigure/helpers.h b/oamapps/postConfigure/helpers.h index 652c86958..64917173b 100644 --- a/oamapps/postConfigure/helpers.h +++ b/oamapps/postConfigure/helpers.h @@ -39,7 +39,7 @@ extern void dbrmDirCheck(); extern void mysqlSetup(); extern int sendMsgProcMon( std::string module, ByteStream msg, int requestID, int timeout ); extern int sendUpgradeRequest(int IserverTypeInstall, bool pmwithum); -extern int sendReplicationRequest(int IserverTypeInstall, std::string password, std::string mysqlPort, bool pmwithum); +extern int sendReplicationRequest(int IserverTypeInstall, std::string password, bool pmwithum); extern void checkFilesPerPartion(int DBRootCount, Config* sysConfig); extern void checkMysqlPort( string& mysqlPort, Config* sysConfig); extern bool writeConfig(Config* sysConfig); diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index cc410e86a..82f92d6da 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -3497,7 +3497,7 @@ int main(int argc, char *argv[]) cout.flush(); //send message to procmon's to run mysql replication script - int status = sendReplicationRequest(IserverTypeInstall, password, mysqlPort, pmwithum); + int status = sendReplicationRequest(IserverTypeInstall, password, pmwithum); if ( status != 0 ) { cout << endl << " MariaDB ColumnStore Install Failed" << endl << endl; diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index c99662d3a..492dc9b05 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -10328,18 +10328,6 @@ int ProcessManager::setMySQLReplication(oam::DeviceNetworkList devicenetworklist */ log.writeLog(__LINE__, "Setup MySQL Replication", LOG_TYPE_DEBUG); - // mysql port number - string MySQLPort; - try { - oam.getSystemConfig("MySQLPort", MySQLPort); - } - catch(...) { - MySQLPort = "3306"; - } - - if ( MySQLPort.empty() ) - MySQLPort = "3306"; - //get master info if ( masterModule == oam::UnassignedName) { @@ -10390,6 +10378,13 @@ int ProcessManager::setMySQLReplication(oam::DeviceNetworkList devicenetworklist if ( remoteModuleName == masterModule ) continue; + // don't do PMs unless PMwithUM flag is set + if ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM ) { + string moduleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + if ( moduleType == "pm" && PMwithUM == "n" ) + continue; + } + ByteStream msg; ByteStream::byte requestID = oam::MASTERDIST; msg << requestID; @@ -10485,7 +10480,6 @@ int ProcessManager::setMySQLReplication(oam::DeviceNetworkList devicenetworklist msg1 << masterLogFile; msg1 << masterLogPos; - msg1 << MySQLPort; } returnStatus = sendMsgProcMon( remoteModuleName, msg1, requestID, 60 ); @@ -10534,7 +10528,6 @@ int ProcessManager::setMySQLReplication(oam::DeviceNetworkList devicenetworklist msg1 << masterLogFile; msg1 << masterLogPos; - msg1 << MySQLPort; } returnStatus = sendMsgProcMon( remoteModuleName, msg1, requestID, 60 ); diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 82e74a1cd..1a1092e61 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -1582,7 +1582,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO } - case RUNUPGRADE: +/* case RUNUPGRADE: { log.writeLog(__LINE__, "MSG RECEIVED: Run upgrade script "); @@ -1601,7 +1601,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO break; } - +*/ case PROCUNMOUNT: { string dbrootID; @@ -1862,8 +1862,6 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO msg >> masterLogFile; string masterLogPos; msg >> masterLogPos; - string port; - msg >> port; if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) @@ -1892,7 +1890,7 @@ void ProcessMonitor::processMessage(messageqcpp::ByteStream msg, messageqcpp::IO } // run Slave Rep script - ret = runSlaveRep(masterLogFile, masterLogPos, port); + ret = runSlaveRep(masterLogFile, masterLogPos); ackMsg << (ByteStream::byte) ACK; ackMsg << (ByteStream::byte) SLAVEREP; @@ -4677,7 +4675,7 @@ void ProcessMonitor::checkProcessFailover( std::string processName) * purpose: run upgrade script * ******************************************************************************************/ -int ProcessMonitor::runUpgrade(std::string mysqlpw) +/*int ProcessMonitor::runUpgrade(std::string mysqlpw) { Oam oam; @@ -4711,7 +4709,7 @@ int ProcessMonitor::runUpgrade(std::string mysqlpw) } return oam::API_FAILURE; } - +*/ /****************************************************************************************** * @brief changeMyCnf @@ -4734,204 +4732,103 @@ int ProcessMonitor::changeMyCnf(std::string type) string dbDir = startup::StartUp::installDir() + "/mysql/db"; -/* if ( type == "master" ) + //get server-id based on ExeMgrx setup + string serverID = "0"; + string localModuleName = config.moduleName(); + for ( int id = 1 ; ; id++ ) { - // set master replication entries - vector lines; - char line[200]; - string buf; - while (file.getline(line, 200)) - { - buf = line; - string::size_type pos = buf.find("server-id =",0); - if ( pos != string::npos ) { - buf = "server-id = 1"; + string Section = "ExeMgr" + oam.itoa(id); + + string moduleName; + + try { + Config* sysConfig = Config::makeConfig(); + moduleName = sysConfig->getConfig(Section, "Module"); + + if ( moduleName == localModuleName ) + { + serverID = oam.itoa(id); + break; } - -// pos = buf.find("# binlog_format=ROW",0); -// if ( pos != string::npos ) { -// buf = "binlog_format=ROW"; -// } - - pos = buf.find("infinidb_local_query=1",0); - if ( pos != string::npos && pos == 0) { - buf = "# infinidb_local_query=1"; - } - - //output to temp file - lines.push_back(buf); } - - file.close(); - unlink (mycnfFile.c_str()); - ofstream newFile (mycnfFile.c_str()); - - //create new file - int fd = open(mycnfFile.c_str(), O_RDWR|O_CREAT, 0664); - - copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); - newFile.close(); - - close(fd); + catch (...) {} } - if ( type == "slave" ) + if ( serverID == "0" ) { -*/ //get slave id based on ExeMgrx setup - string slaveID = "0"; - string localModuleName = config.moduleName(); - for ( int id = 1 ; ; id++ ) + log.writeLog(__LINE__, "changeMyCnf: ExeMgr for local module doesn't exist", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } + + // set server-id and other options in my.cnf + vector lines; + char line[200]; + string buf; + while (file.getline(line, 200)) + { + buf = line; + string::size_type pos = buf.find("server-id",0); + if ( pos != string::npos ) { + buf = "server-id = " + serverID; + + string command = "SET GLOBAL server_id=" + serverID + ";"; + int ret = runMariaDBCommandLine(command); + if (ret != 0) + { + log.writeLog(__LINE__, "changeMyCnf: runMariaDBCommandLine Error", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } + } + + // set local query flag if on pm + if ( (PMwithUM == "y") && config.moduleType() == "pm" ) { - string Section = "ExeMgr" + oam.itoa(id); + pos = buf.find("infinidb_local_query",0); + if ( pos != string::npos ) { + buf = "infinidb_local_query=1"; + + string command = "SET GLOBAL " + buf + ";"; - string moduleName; - - try { - Config* sysConfig = Config::makeConfig(); - moduleName = sysConfig->getConfig(Section, "Module"); - - if ( moduleName == localModuleName ) + int ret = runMariaDBCommandLine(command); + if (ret != 0) { - slaveID = oam.itoa(id); - break; - } + log.writeLog(__LINE__, "changeMyCnf: runMariaDBCommandLine Error", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } } - catch (...) {} } - - if ( slaveID == "0" ) - { - log.writeLog(__LINE__, "changeMyCnf: ExeMgr for local module doesn't exist", LOG_TYPE_ERROR); - return oam::API_FAILURE; - } - - // get local host name -/* string HOSTNAME = "localhost"; - try - { - ModuleConfig moduleconfig; - oam.getSystemConfig(config.moduleName(), moduleconfig); - HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); - HOSTNAME = (*pt1).HostName; - } - catch(...) - {} - - char* p= getenv("HOSTNAME"); - if (p && *p) - HOSTNAME = p; -*/ - // set slave replication entries - vector lines; - char line[200]; - string buf; - while (file.getline(line, 200)) - { - buf = line; - string::size_type pos = buf.find("server-id",0); + else + { // disable, if needed + pos = buf.find("infinidb_local_query",0); if ( pos != string::npos ) { - buf = "server-id = " + slaveID; - } + buf = "infinidb_local_query=0"; - // set local query flag if on pm - if ( (PMwithUM == "y") && config.moduleType() == "pm" ) - { - pos = buf.find("# infinidb_local_query=1",0); - if ( pos != string::npos ) { - buf = "infinidb_local_query=1"; - } + string command = "SET GLOBAL " + buf + ";"; + int ret = runMariaDBCommandLine(command); + if (ret != 0) + { + log.writeLog(__LINE__, "changeMyCnf: runMariaDBCommandLine Error", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } } - else - { // disable, if needed - pos = buf.find("infinidb_local_query=1",0); - if ( pos != string::npos ) { - buf = "# infinidb_local_query=1"; - } - } - -// pos = buf.find("binlog_format=ROW",0); -// if ( pos != string::npos && pos == 0 ) { -// buf = "# binlog_format=ROW"; -// } - - //output to temp file - lines.push_back(buf); } - - file.close(); - unlink (mycnfFile.c_str()); - ofstream newFile (mycnfFile.c_str()); - //create new file - int fd = open(mycnfFile.c_str(), O_RDWR|O_CREAT, 0664); - - copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); - newFile.close(); - - close(fd); -// } - -/* if ( type == "disable" ) - { - // set master replication entries - vector lines; - char line[200]; - string buf; - while (file.getline(line, 200)) - { - buf = line; - string::size_type pos = buf.find("server-id",0); - if ( pos != string::npos ) { - string::size_type pos1 = buf.find("1",pos); - if ( pos1 == string::npos ) { - buf = "# server-id = 1"; - } - } - - pos = buf.find("log-bin=mysql-bin",0); - if ( pos != string::npos ) { - buf = "# log-bin=mysql-bin"; - } - - pos = buf.find("binlog_format=ROW",0); - if ( pos != string::npos && pos == 0 ) { - buf = "# binlog_format=ROW"; - } - - pos = buf.find("infinidb_local_query=1",0); - if ( pos != string::npos && pos == 0) { - buf = "# infinidb_local_query=1"; - } - - pos = buf.find("# relay-log",0); - if ( pos != string::npos ) { - buf = buf; - } - else - { - pos = buf.find("relay-log",0); - if ( pos != string::npos ) { - buf = "# " + buf; - } - } - - //output to temp file - lines.push_back(buf); - } - - file.close(); - unlink (mycnfFile.c_str()); - ofstream newFile (mycnfFile.c_str()); - - //create new file - int fd = open(mycnfFile.c_str(), O_RDWR|O_CREAT, 0664); - - copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); - newFile.close(); - - close(fd); + //output to temp file + lines.push_back(buf); } -*/ + + file.close(); + unlink (mycnfFile.c_str()); + ofstream newFile (mycnfFile.c_str()); + + //create new file + int fd = open(mycnfFile.c_str(), O_RDWR|O_CREAT, 0664); + + copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); + newFile.close(); + + close(fd); + // set owner and permission string cmd = "chmod 664 " + mycnfFile + " >/dev/null 2>&1"; if ( !rootUser) @@ -4946,18 +4843,72 @@ int ProcessMonitor::changeMyCnf(std::string type) system(cmd.c_str()); // restart mysql - try { +/* try { oam.actionMysqlCalpont(MYSQL_RESTART); sleep(5); // give after mysql restart } catch(...) {} - +*/ log.writeLog(__LINE__, "changeMyCnf function successfully completed", LOG_TYPE_DEBUG); return oam::API_SUCCESS; } +/****************************************************************************************** +* @brief runMariaDBCommandLine +* +* purpose: run MariaDB Command Line script +* +******************************************************************************************/ +int ProcessMonitor::runMariaDBCommandLine(std::string command) +{ + Oam oam; + + log.writeLog(__LINE__, "runMariaDBCommandLine function called: cmd = " + command, LOG_TYPE_DEBUG); + + // mysql port number + string MySQLPort; + try { + oam.getSystemConfig("MySQLPort", MySQLPort); + } + catch(...) { + MySQLPort = "3306"; + } + + if ( MySQLPort.empty() ) + MySQLPort = "3306"; + + string cmd = startup::StartUp::installDir() + "/bin/mariadb-command-line.sh --installdir=" + startup::StartUp::installDir() + " --command='" + command + "' --port=" + MySQLPort + " > /tmp/mariadb-command-line.sh.log 2>&1"; + + log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); + + system(cmd.c_str()); + + string logFile = "/tmp/mariadb-command-line.sh.log"; + + if (oam.checkLogStatus(logFile, "ERROR 1045") ) { + log.writeLog(__LINE__, "mariadb-command-line.sh: MySQL Password Error, check .my.cnf", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } + else + { + if (oam.checkLogStatus(logFile, "OK")) + { + log.writeLog(__LINE__, "mariadb-command-line.sh: Successful return", LOG_TYPE_DEBUG); + return oam::API_SUCCESS; + } + else + { + log.writeLog(__LINE__, "mariadb-command-line.sh: Error return, check log /tmp/mariadb-command-line.sh.log", LOG_TYPE_ERROR); + return oam::API_FAILURE; + } + } + + return oam::API_FAILURE; +} + + /****************************************************************************************** * @brief runMasterRep * @@ -4984,6 +4935,18 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master // log.writeLog(__LINE__, "EXCEPTION ERROR on getSystemConfig: Caught unknown exception!", LOG_TYPE_ERROR); } + // mysql port number + string MySQLPort; + try { + oam.getSystemConfig("MySQLPort", MySQLPort); + } + catch(...) { + MySQLPort = "3306"; + } + + if ( MySQLPort.empty() ) + MySQLPort = "3306"; + // create user for each module by ip address for ( unsigned int i = 0 ; i < systemModuleTypeConfig.moduletypeconfig.size(); i++) { @@ -5000,46 +4963,41 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master string moduleType = systemModuleTypeConfig.moduletypeconfig[i].ModuleType; - if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + if ( ( (PMwithUM == "n") && (moduleType == "pm") ) && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) continue; HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); - while(true) // need in case there is a password retry + for ( ; pt1 != (*pt).hostConfigList.end() ; pt1++ ) { - for ( ; pt1 != (*pt).hostConfigList.end() ; pt1++ ) - { - string ipAddr = (*pt1).IPAddr; - - string logFile = "/tmp/master-rep-columnstore-" + moduleName + ".log"; - string cmd = startup::StartUp::installDir() + "/bin/master-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --hostIP=" + ipAddr + " > " + logFile + " 2>&1"; - log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); - - system(cmd.c_str()); - - if (oam.checkLogStatus(logFile, "ERROR 1045") ) { - if ( passwordError ) { - log.writeLog(__LINE__, "master-rep-columnstore.sh: MySQL Password Error", LOG_TYPE_ERROR); - return oam::API_FAILURE; - } - - log.writeLog(__LINE__, "master-rep-columnstore.sh: Missing Password error, go check for a password and retry", LOG_TYPE_DEBUG); - passwordError = true; - break; + string ipAddr = (*pt1).IPAddr; + + string logFile = "/tmp/master-rep-columnstore-" + moduleName + ".log"; + string cmd = startup::StartUp::installDir() + "/bin/master-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --hostIP=" + ipAddr + " --port=" + MySQLPort + " > " + logFile + " 2>&1"; + log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); + + system(cmd.c_str()); + + if (oam.checkLogStatus(logFile, "ERROR 1045") ) { + if ( passwordError ) { + log.writeLog(__LINE__, "master-rep-columnstore.sh: MySQL Password Error", LOG_TYPE_ERROR); + return oam::API_FAILURE; } - else + + log.writeLog(__LINE__, "master-rep-columnstore.sh: Missing Password error, go check for a password and retry", LOG_TYPE_DEBUG); + passwordError = true; + break; + } + else + { + if (oam.checkLogStatus(logFile, "OK")) + log.writeLog(__LINE__, "master-rep-columnstore.sh: Successful return for node " + moduleName, LOG_TYPE_DEBUG); + else { - if (oam.checkLogStatus(logFile, "OK")) - log.writeLog(__LINE__, "master-rep-columnstore.sh: Successful return for node " + moduleName, LOG_TYPE_DEBUG); - else - { - log.writeLog(__LINE__, "master-rep-columnstore.sh: Error return, check log " + logFile, LOG_TYPE_ERROR); - return oam::API_FAILURE; - } + log.writeLog(__LINE__, "master-rep-columnstore.sh: Error return, check log " + logFile, LOG_TYPE_ERROR); + return oam::API_FAILURE; } } - - break; } } } @@ -5106,7 +5064,7 @@ int ProcessMonitor::runMasterRep(std::string& masterLogFile, std::string& master * purpose: run Slave Replication script * ******************************************************************************************/ -int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterLogPos, std::string& port) +int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterLogPos) { Oam oam; @@ -5127,10 +5085,22 @@ int ProcessMonitor::runSlaveRep(std::string& masterLogFile, std::string& masterL catch(...) {} + // mysql port number + string MySQLPort; + try { + oam.getSystemConfig("MySQLPort", MySQLPort); + } + catch(...) { + MySQLPort = "3306"; + } + + if ( MySQLPort.empty() ) + MySQLPort = "3306"; + bool passwordError = false; while(true) { - string cmd = startup::StartUp::installDir() + "/bin/slave-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --masteripaddr=" + masterIPAddress + " --masterlogfile=" + masterLogFile + " --masterlogpos=" + masterLogPos + + " --port=" + port + " > /tmp/slave-rep-columnstore.log 2>&1"; + string cmd = startup::StartUp::installDir() + "/bin/slave-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " --masteripaddr=" + masterIPAddress + " --masterlogfile=" + masterLogFile + " --masterlogpos=" + masterLogPos + " --port=" + MySQLPort + " > /tmp/slave-rep-columnstore.log 2>&1"; log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); @@ -5177,6 +5147,18 @@ int ProcessMonitor::runDisableRep() log.writeLog(__LINE__, "runDisableRep function called", LOG_TYPE_DEBUG); + // mysql port number + string MySQLPort; + try { + oam.getSystemConfig("MySQLPort", MySQLPort); + } + catch(...) { + MySQLPort = "3306"; + } + + if ( MySQLPort.empty() ) + MySQLPort = "3306"; + string cmd = startup::StartUp::installDir() + "/bin/disable-rep-columnstore.sh --installdir=" + startup::StartUp::installDir() + " > /tmp/disable-rep-columnstore.log 2>&1"; log.writeLog(__LINE__, "cmd = " + cmd, LOG_TYPE_DEBUG); @@ -5227,6 +5209,7 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul // log.writeLog(__LINE__, "EXCEPTION ERROR on getSystemConfig: Caught unknown exception!", LOG_TYPE_ERROR); } + int slave = 0; if ( slaveModule == "all" ) { // Distrubuted MySQL Front-end DB to Slave Modules @@ -5238,7 +5221,7 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul string moduleType = systemModuleTypeConfig.moduletypeconfig[i].ModuleType; - if ( ( (PMwithUM == "n") && (config.moduleType() == "pm") ) && + if ( ( (PMwithUM == "n") && (moduleType == "pm") ) && ( config.ServerInstallType() != oam::INSTALL_COMBINE_DM_UM_PM) ) continue; @@ -5251,6 +5234,8 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul if ( moduleName == config.moduleName() ) continue; + slave++; + HostConfigList::iterator pt1 = (*pt).hostConfigList.begin(); for ( ; pt1 != (*pt).hostConfigList.end() ; pt1++ ) { @@ -5263,7 +5248,10 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul string logFile = "/tmp/master-dist_" + moduleName + ".log"; if (!oam.checkLogStatus(logFile, "FAILED")) + { log.writeLog(__LINE__, "runMasterDist: Success rsync to module: " + moduleName, LOG_TYPE_DEBUG); + break; + } else { log.writeLog(__LINE__, "runMasterDist: Failure rsync to module: " + moduleName, LOG_TYPE_ERROR); @@ -5275,24 +5263,37 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul } else { - // get slave IP address - ModuleConfig moduleconfig; - oam.getSystemConfig(slaveModule, moduleconfig); - HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); - string ipAddr = (*pt1).IPAddr; + // don't do PMs unless PMwithUM flag is set + + string moduleType = slaveModule.substr(0,MAX_MODULE_TYPE_SIZE); - string cmd = startup::StartUp::installDir() + "/bin/rsync.sh " + ipAddr + " " + password + " " + startup::StartUp::installDir() + " 1 > /tmp/master-dist_" + slaveModule + ".log"; - system(cmd.c_str()); - - string logFile = "/tmp/master-dist_" + slaveModule + ".log"; - if (!oam.checkLogStatus(logFile, "FAILED")) - log.writeLog(__LINE__, "runMasterDist: Success rsync to module: " + slaveModule, LOG_TYPE_DEBUG); - else + if ( ( (PMwithUM == "y") && (moduleType == "pm") ) && + ( config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM) ) { - log.writeLog(__LINE__, "runMasterDist: Failure rsync to module: " + slaveModule, LOG_TYPE_ERROR); - return oam::API_FAILURE; + slave++; + + // get slave IP address + ModuleConfig moduleconfig; + oam.getSystemConfig(slaveModule, moduleconfig); + HostConfigList::iterator pt1 = moduleconfig.hostConfigList.begin(); + string ipAddr = (*pt1).IPAddr; + + string cmd = startup::StartUp::installDir() + "/bin/rsync.sh " + ipAddr + " " + password + " " + startup::StartUp::installDir() + " 1 > /tmp/master-dist_" + slaveModule + ".log"; + system(cmd.c_str()); + + string logFile = "/tmp/master-dist_" + slaveModule + ".log"; + if (!oam.checkLogStatus(logFile, "FAILED")) + log.writeLog(__LINE__, "runMasterDist: Success rsync to module: " + slaveModule, LOG_TYPE_DEBUG); + else + { + log.writeLog(__LINE__, "runMasterDist: Failure rsync to module: " + slaveModule, LOG_TYPE_ERROR); + return oam::API_FAILURE; + } } } + + if (slave == 0 ) + log.writeLog(__LINE__, "runMasterDist: No configured slave nodes", LOG_TYPE_DEBUG); return oam::API_SUCCESS; } diff --git a/procmon/processmonitor.h b/procmon/processmonitor.h index a82e80bc0..5a3145963 100644 --- a/procmon/processmonitor.h +++ b/procmon/processmonitor.h @@ -492,13 +492,19 @@ public: /** *@brief run upgrade script */ - int runUpgrade(std::string mysqlpw); +// int runUpgrade(std::string mysqlpw); /** *@brief change my.cnf */ int changeMyCnf(std::string type); + + /** + *@brief run MariaDB Command Line script + */ + int runMariaDBCommandLine(std::string command); + /** *@brief run Master Replication script */ @@ -512,7 +518,7 @@ public: /** *@brief run Slave Replication script */ - int runSlaveRep(std::string& masterLogFile, std::string& masterLogPos, std::string& port); + int runSlaveRep(std::string& masterLogFile, std::string& masterLogPos); /** *@brief run Disable Replication script From 468b2d473b46bcb9c8757782bdc80ff6935abb94 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 7 Nov 2017 08:28:29 +0000 Subject: [PATCH 160/185] MCOL-1016 Fix I_S calculations * COLUMNSTORE_EXTENTS data_size now shows the total size on the highest segment of an extent file. It also shows 0 bytes if HWM is zero so that if there is more than one segment it doesn't show 8192 bytes for the lower segments. * COMPRESSION_RATIO was missing some data and using compressed data size instead of file size (which is probably more realistic). --- dbcon/mysql/columnstore_info.sql | 4 +--- dbcon/mysql/is_columnstore_extents.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dbcon/mysql/columnstore_info.sql b/dbcon/mysql/columnstore_info.sql index 60dab7eac..23a6a0ed6 100644 --- a/dbcon/mysql/columnstore_info.sql +++ b/dbcon/mysql/columnstore_info.sql @@ -82,9 +82,7 @@ DROP PROCEDURE IF EXISTS `compression_ratio` // CREATE PROCEDURE compression_ratio() BEGIN -SELECT CONCAT(((sum(compressed_data_size) / sum(data_size)) * 100), '%') COMPRESSION_RATIO FROM INFORMATION_SCHEMA.COLUMNSTORE_EXTENTS ce -JOIN INFORMATION_SCHEMA.COLUMNSTORE_FILES cf ON ce.object_id = cf.object_id -WHERE compressed_data_size IS NOT NULL; +SELECT CONCAT((SELECT SUM(file_size) FROM information_schema.columnstore_files WHERE compressed_data_size IS NOT NULL) / (SELECT SUM(data_size) FROM information_schema.columnstore_extents) * 100, '%') COMPRESSION_RATIO; END // DELIMITER ; diff --git a/dbcon/mysql/is_columnstore_extents.cpp b/dbcon/mysql/is_columnstore_extents.cpp index 9f7e11710..4ee4cbce6 100644 --- a/dbcon/mysql/is_columnstore_extents.cpp +++ b/dbcon/mysql/is_columnstore_extents.cpp @@ -152,14 +152,18 @@ static int is_columnstore_extents_fill(THD *thd, TABLE_LIST *tables, COND *cond) default: table->field[14]->store("Unknown", strlen("Unknown"), cs); } - // MCOL-454: special case, sometimes blockOffset can be > 0 and HWM can be 0 + // MCOL-1016: on multiple segments HWM is set to 0 on the lower + // segments, we don't want these to show as 8KB. The down side is + // if the column has less than 1 block it will show as 0 bytes. + // We have no lookahead without it getting messy so this is the + // best compromise. if (iter->HWM == 0) { - table->field[15]->store(8192); + table->field[15]->store(0); } else { - table->field[15]->store((iter->HWM - iter->blockOffset + 1) * 8192); + table->field[15]->store((iter->HWM + 1) * 8192); } if (schema_table_store_record(thd, table)) From 1c59a8875c524d8f4d2b4ae2a9d434f900b606d2 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 7 Nov 2017 12:52:32 -0600 Subject: [PATCH 161/185] added retry on remote install timeout errors --- oam/install_scripts/binary_installer.sh | 16 +++++------ oam/install_scripts/package_installer.sh | 14 +++++----- oamapps/postConfigure/postConfigure.cpp | 34 +++++++++++++++++------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/oam/install_scripts/binary_installer.sh b/oam/install_scripts/binary_installer.sh index 2437af2b8..9baa26e4a 100644 --- a/oam/install_scripts/binary_installer.sh +++ b/oam/install_scripts/binary_installer.sh @@ -54,14 +54,14 @@ expect { exp_continue } "Exit status 0" { send_user "DONE"} - "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } + "Exit status 1" { send_user "FAILED: Login Failure\n" ; exit 1 } "Host key verification failed" { send_user "FAILED: Host key verification failed\n" ; exit 1 } "service not known" { send_user "FAILED: Invalid Host\n" ; exit 1 } "Permission denied, please try again" { send_user "ERROR: Invalid password\n" ; exit 1 } "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -125,7 +125,7 @@ expect { send_user "\n*** Installation ERROR\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - timeout { send_user "ERROR: Timeout\n" ; exit 1 } + timeout { send_user "ERROR: Timeout\n" ; exit 2 } } send_user "\n" # @@ -144,7 +144,7 @@ expect { } "Exit status 0" { send_user "DONE" } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - timeout { send_user "ERROR: Timeout\n" ; exit 1 } + timeout { send_user "ERROR: Timeout\n" ; exit 2 } } send_user "\n" @@ -167,7 +167,7 @@ expect { send_user "\n*** Installation ERROR\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - timeout { send_user "ERROR: Timeout\n" ; exit 1 } + timeout { send_user "ERROR: Timeout\n" ; exit 2 } } send_user "\n" @@ -189,7 +189,7 @@ expect { send_user "\n*** Installation ERROR\n" ; exit 1 } "Exit status 0" { send_user "DONE" } "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -208,7 +208,7 @@ expect { "Exit status 127" { send_user "ERROR: $INSTALLDIR/bin/post-install Not Found\n" ; exit 1 } "MariaDB Columnstore syslog logging not working" { send_user "WARNING: MariaDB Columnstore System logging not setup\n"; exp_continue } "Exit status 0" { send_user "DONE" } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -226,7 +226,7 @@ expect { } "Exit status 127" { send_user "ERROR: $INSTALLDIR/bin/post-install Not Found\n" ; exit 1 } "Exit status 0" { send_user "DONE" } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" diff --git a/oam/install_scripts/package_installer.sh b/oam/install_scripts/package_installer.sh index 32b05e0a4..02486cb96 100644 --- a/oam/install_scripts/package_installer.sh +++ b/oam/install_scripts/package_installer.sh @@ -79,7 +79,7 @@ expect { "Connection refused" { send_user "ERROR: Connection refused\n" ; exit 1 } "Connection closed" { send_user "ERROR: Connection closed\n" ; exit 1 } "No route to host" { send_user "ERROR: No route to host\n" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -138,7 +138,7 @@ expect { exp_continue } "Exit status 0" { send_user "DONE" } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } set timeout 180 send "scp -v $HOME/mariadb-columnstore*$VERSION*$PKGTYPE $USERNAME@$SERVER:.\n" @@ -154,7 +154,7 @@ expect { exit 1 } "Exit status 0" { send_user "DONE" } "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -179,7 +179,7 @@ expect { "conflicts" { send_user "ERROR: File Conflict issue\n" ; exit 1 } "MariaDB Columnstore syslog logging not working" { send_user "WARNING: MariaDB Columnstore System logging not setup\n"; exp_continue } "Exit status 0" { send_user "DONE" } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -202,7 +202,7 @@ expect { send_user "\n*** Installation ERROR\n" ; exit 1 } "Read-only file system" { send_user "ERROR: local disk - Read-only file system\n" ; exit 1} - timeout { send_user "ERROR: Timeout\n" ; exit 1 } + timeout { send_user "ERROR: Timeout\n" ; exit 2 } } send_user "\n" @@ -224,7 +224,7 @@ expect { exit 1 } "Exit status 0" { send_user "DONE" } "Exit status 1" { send_user "ERROR: scp failed" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" @@ -242,7 +242,7 @@ expect { } "Exit status 0" { send_user "DONE" } "Exit status 127" { send_user "ERROR: $INSTALLDIR/bin/columnstore Not Found\n" ; exit 1 } - timeout { send_user "ERROR: Timeout to host\n" ; exit 1 } + timeout { send_user "ERROR: Timeout to host\n" ; exit 2 } } send_user "\n" diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 82f92d6da..fb02d27d9 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2943,7 +2943,7 @@ int main(int argc, char *argv[]) if ( pwprompt == " " ) temppwprompt = "none"; - //run remote installer script + //run remote installer script cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; if ( thread_remote_installer ) { @@ -5345,15 +5345,31 @@ void remoteInstallThread(void *arg) { thread_data_t *data = (thread_data_t *)arg; - int rtnCode = system((data->command).c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - pthread_mutex_lock(&THREAD_LOCK); - cout << endl << "Failure with a remote module install, check install log files in /tmp" << endl; - exit(1); + for ( int retry = 0 ; retry < 5 ; retry++ ) + { + int rtnCode = system((data->command).c_str()); + if (WEXITSTATUS(rtnCode) == 0) { + //success + pthread_exit(0); + } + else + { + if (WEXITSTATUS(rtnCode) == 2) { + //timeout retry + continue; + } + else + { //failure + pthread_mutex_lock(&THREAD_LOCK); + cout << endl << "Failure with a remote module install, check install log files in /tmp" << endl; + exit(1); + } + } } - - // exit thread - pthread_exit(0); + + pthread_mutex_lock(&THREAD_LOCK); + cout << endl << "Failure with a remote module install, check install log files in /tmp" << endl; + exit(1); } std::string launchInstance(ModuleIP moduleip) From 0db37ad7df6567e05971a1222c9ef7423742869f Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 7 Nov 2017 18:19:36 -0600 Subject: [PATCH 162/185] added new script to cmake --- cpackEngineRPM.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cpackEngineRPM.cmake b/cpackEngineRPM.cmake index 260a2a2a1..a6013b280 100644 --- a/cpackEngineRPM.cmake +++ b/cpackEngineRPM.cmake @@ -217,6 +217,7 @@ SET(CPACK_RPM_platform_USER_FILELIST "/usr/local/mariadb/columnstore/post/test-004.sh" "/usr/local/mariadb/columnstore/bin/os_detect.sh" "/usr/local/mariadb/columnstore/bin/columnstoreClusterTester.sh" +"/usr/local/mariadb/columnstore/bin/mariadb-command-line.sh" ${ignored}) SET(CPACK_RPM_libs_USER_FILELIST From c84ea561e1b6006b526b370bc5f8ed5c4b2285fb Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 8 Nov 2017 12:10:01 -0600 Subject: [PATCH 163/185] MCOL-998 - added in binlog_format --- dbcon/execplan/calpontsystemcatalog.cpp | 34 +++++-------------------- dbcon/execplan/calpontsystemcatalog.h | 5 +--- dbcon/mysql/my.cnf | 2 +- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/dbcon/execplan/calpontsystemcatalog.cpp b/dbcon/execplan/calpontsystemcatalog.cpp index a5a35bd66..33fe2a7a3 100755 --- a/dbcon/execplan/calpontsystemcatalog.cpp +++ b/dbcon/execplan/calpontsystemcatalog.cpp @@ -1190,7 +1190,7 @@ const CalpontSystemCatalog::ColType CalpontSystemCatalog::colTypeDct(const OID& } // check map first cached column type - boost::recursive_mutex::scoped_lock lk3(fDctTokenMapLock); + boost::mutex::scoped_lock lk3(fDctTokenMapLock); DctTokenMap::const_iterator iter = fDctTokenMap.find(dictOid); if (iter != fDctTokenMap.end()) return colType(iter->second); @@ -3093,35 +3093,18 @@ const CalpontSystemCatalog::RIDList CalpontSystemCatalog::columnRIDs(const Table ctList[i].nextvalue = ((*it)->GetData(i)); } } - // MCOL-895 sort ctList, we can't specify an ORDER BY to do this yet - std::sort(ctList, ctList + ti.numOfCols, ctListSort); - + // populate colinfo cache lk3.lock(); for (int i = 0; i < ti.numOfCols; i++) fColinfomap[ctList[i].columnOID] = ctList[i]; lk3.unlock(); - - // Re-sort the output based on the sorted ctList - // Don't need to do this for the cached list as this will be already sorted - RIDList rlOut; - for (int i = 0; i < ti.numOfCols; i++) - { - OID objid = ctList[i].columnOID; - for (size_t j = 0; j < rl.size(); j++) - { - if (rl[j].objnum == objid) - { - rlOut.push_back(rl[j]); - } - } - } - + delete [] ctList; // delete col[9]; - if (rlOut.size() != 0) + if (rl.size() != 0) { - return rlOut; + return rl; } Message::Args args; @@ -5337,7 +5320,7 @@ void CalpontSystemCatalog::flushCache() buildSysTablemap(); lk3.unlock(); - boost::recursive_mutex::scoped_lock lk4(fDctTokenMapLock); + boost::mutex::scoped_lock lk4(fDctTokenMapLock); fDctTokenMap.clear(); buildSysDctmap(); lk4.unlock(); @@ -5805,10 +5788,5 @@ vector getAllSysCatOIDs() return ret; } -bool ctListSort(const CalpontSystemCatalog::ColType& a, const CalpontSystemCatalog::ColType& b) -{ - return a.colPosition < b.colPosition; -} - } // namespace execplan // vim:sw=4 ts=4: diff --git a/dbcon/execplan/calpontsystemcatalog.h b/dbcon/execplan/calpontsystemcatalog.h index 19e293070..c58e531bc 100755 --- a/dbcon/execplan/calpontsystemcatalog.h +++ b/dbcon/execplan/calpontsystemcatalog.h @@ -871,8 +871,7 @@ private: typedef std::map DctTokenMap; DctTokenMap fDctTokenMap; - // MCOL-859: this can lock when already locked in the same thread - boost::recursive_mutex fDctTokenMapLock; + boost::mutex fDctTokenMapLock; typedef std::map TableNameMap; TableNameMap fTableNameMap; @@ -1247,8 +1246,6 @@ std::ostream& operator<<(std::ostream& os, const CalpontSystemCatalog::ColType& const std::string colDataTypeToString(CalpontSystemCatalog::ColDataType cdt); -bool ctListSort(const CalpontSystemCatalog::ColType& a, const CalpontSystemCatalog::ColType& b); - } //namespace execplan #endif //EXECPLAN_CALPONTSYSTEMCATALOG_H diff --git a/dbcon/mysql/my.cnf b/dbcon/mysql/my.cnf index bdbe7ef26..fb20fd8c9 100644 --- a/dbcon/mysql/my.cnf +++ b/dbcon/mysql/my.cnf @@ -79,7 +79,7 @@ plugin_dir = /usr/local/mariadb/columnstore/mysql/lib/plugi # Replication Master Server (default) # binary logging is required for replication # log-bin=mysql-bin -# binlog_format=ROW +binlog_format=ROW # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host From 1603ce925f4cbffef8754663ae0a3058bafc4c65 Mon Sep 17 00:00:00 2001 From: david hill Date: Wed, 8 Nov 2017 13:06:45 -0600 Subject: [PATCH 164/185] rechecking back in version of calpontsystemcatalog, accidental commit old versions --- dbcon/execplan/calpontsystemcatalog.cpp | 34 ++++++++++++++++++++----- dbcon/execplan/calpontsystemcatalog.h | 5 +++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/dbcon/execplan/calpontsystemcatalog.cpp b/dbcon/execplan/calpontsystemcatalog.cpp index 33fe2a7a3..a5a35bd66 100755 --- a/dbcon/execplan/calpontsystemcatalog.cpp +++ b/dbcon/execplan/calpontsystemcatalog.cpp @@ -1190,7 +1190,7 @@ const CalpontSystemCatalog::ColType CalpontSystemCatalog::colTypeDct(const OID& } // check map first cached column type - boost::mutex::scoped_lock lk3(fDctTokenMapLock); + boost::recursive_mutex::scoped_lock lk3(fDctTokenMapLock); DctTokenMap::const_iterator iter = fDctTokenMap.find(dictOid); if (iter != fDctTokenMap.end()) return colType(iter->second); @@ -3093,18 +3093,35 @@ const CalpontSystemCatalog::RIDList CalpontSystemCatalog::columnRIDs(const Table ctList[i].nextvalue = ((*it)->GetData(i)); } } - + // MCOL-895 sort ctList, we can't specify an ORDER BY to do this yet + std::sort(ctList, ctList + ti.numOfCols, ctListSort); + // populate colinfo cache lk3.lock(); for (int i = 0; i < ti.numOfCols; i++) fColinfomap[ctList[i].columnOID] = ctList[i]; lk3.unlock(); - + + // Re-sort the output based on the sorted ctList + // Don't need to do this for the cached list as this will be already sorted + RIDList rlOut; + for (int i = 0; i < ti.numOfCols; i++) + { + OID objid = ctList[i].columnOID; + for (size_t j = 0; j < rl.size(); j++) + { + if (rl[j].objnum == objid) + { + rlOut.push_back(rl[j]); + } + } + } + delete [] ctList; // delete col[9]; - if (rl.size() != 0) + if (rlOut.size() != 0) { - return rl; + return rlOut; } Message::Args args; @@ -5320,7 +5337,7 @@ void CalpontSystemCatalog::flushCache() buildSysTablemap(); lk3.unlock(); - boost::mutex::scoped_lock lk4(fDctTokenMapLock); + boost::recursive_mutex::scoped_lock lk4(fDctTokenMapLock); fDctTokenMap.clear(); buildSysDctmap(); lk4.unlock(); @@ -5788,5 +5805,10 @@ vector getAllSysCatOIDs() return ret; } +bool ctListSort(const CalpontSystemCatalog::ColType& a, const CalpontSystemCatalog::ColType& b) +{ + return a.colPosition < b.colPosition; +} + } // namespace execplan // vim:sw=4 ts=4: diff --git a/dbcon/execplan/calpontsystemcatalog.h b/dbcon/execplan/calpontsystemcatalog.h index c58e531bc..19e293070 100755 --- a/dbcon/execplan/calpontsystemcatalog.h +++ b/dbcon/execplan/calpontsystemcatalog.h @@ -871,7 +871,8 @@ private: typedef std::map DctTokenMap; DctTokenMap fDctTokenMap; - boost::mutex fDctTokenMapLock; + // MCOL-859: this can lock when already locked in the same thread + boost::recursive_mutex fDctTokenMapLock; typedef std::map TableNameMap; TableNameMap fTableNameMap; @@ -1246,6 +1247,8 @@ std::ostream& operator<<(std::ostream& os, const CalpontSystemCatalog::ColType& const std::string colDataTypeToString(CalpontSystemCatalog::ColDataType cdt); +bool ctListSort(const CalpontSystemCatalog::ColType& a, const CalpontSystemCatalog::ColType& b); + } //namespace execplan #endif //EXECPLAN_CALPONTSYSTEMCATALOG_H From 22dced568cd7be7c640a23602d401eb95425fe04 Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Wed, 8 Nov 2017 15:12:10 -0600 Subject: [PATCH 165/185] MCOL-976: Change how processes are restarted after losing or regaining contact with a down module. --- procmgr/main.cpp | 89 ++++++++++++++++++++++++++++++++++++-- procmgr/processmanager.cpp | 57 +++++------------------- 2 files changed, 95 insertions(+), 51 deletions(-) diff --git a/procmgr/main.cpp b/procmgr/main.cpp index f54ff09be..4b3fa1376 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -1635,9 +1635,16 @@ void pingDeviceThread() processManager.distributeConfigFile("system"); sleep(1); - // if a PM module was started successfully, restart ACTIVE ExeMgr(s) / mysqld + // if a PM module was started successfully, restart ACTIVE DBRM(s), ExeMgr(s) / mysqld if( moduleName.find("pm") == 0 ) { - processManager.restartProcessType("ExeMgr", moduleName); + processManager.restartProcessType("DBRMControllerNode", moduleName); + processManager.restartProcessType("DBRMWorkerNode"); + processManager.stopProcessType("DDLProc"); + processManager.stopProcessType("DMLProc"); + processManager.stopProcessType("ExeMgr"); + processManager.restartProcessType("PrimProc"); + sleep(1); + processManager.restartProcessType("ExeMgr"); } string moduleType = moduleName.substr(0,MAX_MODULE_TYPE_SIZE); @@ -1667,9 +1674,11 @@ void pingDeviceThread() // if a PM module was started successfully, DMLProc/DDLProc if( moduleName.find("pm") == 0 ) { - processManager.restartProcessType("DDLProc", moduleName); + processManager.restartProcessType("WriteEngineServer"); sleep(1); - processManager.restartProcessType("DMLProc", moduleName); + processManager.restartProcessType("DDLProc"); + sleep(1); + processManager.restartProcessType("DMLProc"); } //enable query stats @@ -1680,6 +1689,78 @@ void pingDeviceThread() processManager.setSystemState(oam::ACTIVE); + //reset standby module + string newStandbyModule = processManager.getStandbyModule(); + + //send message to start new Standby Process-Manager, if needed + if ( !newStandbyModule.empty() && newStandbyModule != "NONE") { + processManager.setStandbyModule(newStandbyModule); + } + else + { + Config* sysConfig = Config::makeConfig(); + + // clear Standby OAM Module + sysConfig->setConfig("SystemConfig", "StandbyOAMModuleName", oam::UnassignedName); + sysConfig->setConfig("ProcStatusControlStandby", "IPAddr", oam::UnassignedIpAddr); + + //update Calpont Config table + try { + sysConfig->write(); + } + catch(...) + { + log.writeLog(__LINE__, "ERROR: sysConfig->write", LOG_TYPE_ERROR); + } + } + + if ( moduletypeconfig.RunType == SIMPLEX ) { + //start SIMPLEX runtype processes on a SIMPLEX runtype module + string moduletype = moduleName.substr(0,MAX_MODULE_TYPE_SIZE); + DeviceNetworkList::iterator pt = moduletypeconfig.ModuleNetworkList.begin(); + for( ; pt != moduletypeconfig.ModuleNetworkList.end() ; pt++) + { + string launchModuleName = (*pt).DeviceName; + string launchModuletype = launchModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + if ( moduletype != launchModuletype ) + continue; + + //skip if active pm module (local module) + if ( launchModuleName == config.moduleName() ) + continue; + + //check if module is active before starting any SIMPLEX STANDBY apps + try{ + int launchopState = oam::ACTIVE; + bool degraded; + oam.getModuleStatus(launchModuleName, launchopState, degraded); + + if (launchopState != oam::ACTIVE && launchopState != oam::STANDBY ) { + continue; + } + } + catch (exception& ex) + { +// string error = ex.what(); +// log.writeLog(__LINE__, "EXCEPTION ERROR on : " + error, LOG_TYPE_ERROR); + } + catch(...) + { +// log.writeLog(__LINE__, "EXCEPTION ERROR on getModuleStatus on module " + moduleName + ": Caught unknown exception!", LOG_TYPE_ERROR); + } + + int status; + log.writeLog(__LINE__, "Starting up STANDBY process on module " + launchModuleName, LOG_TYPE_DEBUG); + for ( int j = 0 ; j < 20 ; j ++ ) + { + status = processManager.startModule(launchModuleName, oam::FORCEFUL, oam::AUTO_OFFLINE); + if ( status == API_SUCCESS) + break; + } + log.writeLog(__LINE__, "pingDeviceThread: ACK received from '" + launchModuleName + "' Process-Monitor, return status = " + oam.itoa(status), LOG_TYPE_DEBUG); + } + } + //clear count moduleInfoList[moduleName] = 0; } diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 492dc9b05..c3cd330a9 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -3439,9 +3439,13 @@ void ProcessManager::recycleProcess(string module) //restart ExeMgrs/mysql if module is a pm if ( moduleType == "pm" ) { -// restartProcessType("DBRMWorkerNode"); -// restartProcessType("PrimProc"); -// restartProcessType("WriteEngineServer"); + restartProcessType("DBRMControllerNode", module); + restartProcessType("DBRMWorkerNode"); + stopProcessType("DDLProc"); + stopProcessType("DMLProc"); + stopProcessType("ExeMgr"); + restartProcessType("PrimProc"); + sleep(1); restartProcessType("ExeMgr"); restartProcessType("mysql"); } @@ -3457,54 +3461,13 @@ void ProcessManager::recycleProcess(string module) if( moduleType == "pm" && PrimaryUMModuleName != module) { -// restartProcessType("DBRMControllerNode", module); -// sleep(1); - reinitProcessType("DDLProc"); + restartProcessType("WriteEngineServer"); + sleep(1); + restartProcessType("DDLProc"); sleep(1); restartProcessType("DMLProc", module); } - //wait for DMLProc to go ACTIVE -/* uint16_t rtn = 0; - bool bfirst = true; - while (rtn == 0) - { - ProcessStatus DMLprocessstatus; - try { - oam.getProcessStatus("DMLProc", PrimaryUMModuleName, DMLprocessstatus); - } - catch (exception& ex) - { -// string error = ex.what(); -// log.writeLog(__LINE__, "EXCEPTION ERROR on getProcessStatus: " + error, LOG_TYPE_ERROR); - } - catch(...) - { -// log.writeLog(__LINE__, "EXCEPTION ERROR on getProcessStatus: Caught unknown exception!", LOG_TYPE_ERROR); - } - - if (DMLprocessstatus.ProcessOpState == oam::BUSY_INIT) { - if (bfirst) - { - log.writeLog(__LINE__, "Waiting for DMLProc to finish rollback" , LOG_TYPE_INFO); - bfirst = false; - } - } - - if (DMLprocessstatus.ProcessOpState == oam::ACTIVE) { - rtn = oam::ACTIVE; - break; - } - - if (DMLprocessstatus.ProcessOpState == oam::FAILED) { - rtn = oam::FAILED; - break; - } - - // wait some more - sleep(2); - } -*/ return; } From f1dd92a13d63e495e0bc2c1de9402473b5578fad Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Wed, 8 Nov 2017 15:27:54 -0600 Subject: [PATCH 166/185] MCOL-989: Fix command string missing space and error messages to not reference postConfigure since this can happen under addmodule mcsadmin command. --- oam/oamcpp/liboamcpp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/oam/oamcpp/liboamcpp.cpp b/oam/oamcpp/liboamcpp.cpp index d0c3764eb..e28e21aa6 100644 --- a/oam/oamcpp/liboamcpp.cpp +++ b/oam/oamcpp/liboamcpp.cpp @@ -8421,12 +8421,12 @@ namespace oam if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: peer probe command failed." << endl; - command = InstallDir + "/bin/remote_command.sh " + DataRedundancyConfigs[pm].pmIpAddr + " " + password + "'stat /var/run/glusterd.pid > /dev/null 2>&1'"; + command = InstallDir + "/bin/remote_command.sh " + DataRedundancyConfigs[pm].pmIpAddr + " " + password + " 'stat /var/run/glusterd.pid > /dev/null 2>&1'"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: No glusterd process detected at " << DataRedundancyConfigs[pm].pmIpAddr << "." << endl; - cout << " Start and enable glusterd and run postConfigure again." << endl; + cout << " Start and enable glusterd at " << DataRedundancyConfigs[pm].pmIpAddr << "." << endl; } exceptionControl("GLUSTER_ADD", API_FAILURE); } @@ -8565,12 +8565,12 @@ namespace oam if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: peer probe command failed." << endl; - command = InstallDir + "/bin/remote_command.sh " + ipAddress + " " + password + "'stat /var/run/glusterd.pid > /dev/null 2>&1'"; + command = InstallDir + "/bin/remote_command.sh " + ipAddress + " " + password + " 'stat /var/run/glusterd.pid > /dev/null 2>&1'"; status = system(command.c_str()); if (WEXITSTATUS(status) != 0 ) { cout << "ERROR: No glusterd process detected at " << ipAddress << "." << endl; - cout << " Start and enable glusterd and run postConfigure again." << endl; + cout << " Start and enable glusterd at " << ipAddress << "." << endl; } return 1; } From 5de2ccde622ab851132a78ab3d53546d2acadd72 Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Wed, 8 Nov 2017 16:28:07 -0600 Subject: [PATCH 167/185] MCOL-997: remove prompt for system installation step. --- oamapps/postConfigure/postConfigure.cpp | 31 ++----------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index fb02d27d9..0b6579463 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2778,27 +2778,9 @@ int main(int argc, char *argv[]) // cout << endl << "===== System Installation =====" << endl << endl; - cout << "System Configuration is complete, System Installation is the next step." << endl; + cout << "System Configuration is complete." << endl; + cout << "Performing System Installation." << endl; - while(true) - { - pcommand = callReadline("Would you like to continue with the System Installation? [y,n] (y) > "); - if (pcommand) - { - if (strlen(pcommand) > 0) install = pcommand; - callFree(pcommand); - } - if ( install == "y" || install == "n" ) - break; - else - cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; - install = "y"; - if ( noPrompting ) - exit(1); - } - - if ( install == "y" ) - { SystemSoftware systemsoftware; try @@ -3169,15 +3151,6 @@ int main(int argc, char *argv[]) cout << " DONE" << endl; } } - else - { - if (DataRedundancy && install != "y") - { - cout << endl << "Must choose to install with DataRedundancy configured." << endl; - exit(1); - } - } - } else { if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || From f52d07eabb8c09212e7ba55a65421d5109cbf913 Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Wed, 8 Nov 2017 16:33:24 -0600 Subject: [PATCH 168/185] MCOL-997: whitespace. --- oamapps/postConfigure/postConfigure.cpp | 646 ++++++++++++------------ 1 file changed, 323 insertions(+), 323 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 0b6579463..8c50308cc 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2781,139 +2781,294 @@ int main(int argc, char *argv[]) cout << "System Configuration is complete." << endl; cout << "Performing System Installation." << endl; - SystemSoftware systemsoftware; + SystemSoftware systemsoftware; - try + try + { + oam.getSystemSoftware(systemsoftware); + } + catch (exception& e) + { + cout << " ERROR: reading getSystemSoftware API" << endl; + exit (1); + } + + cout << endl; + + string version = systemsoftware.Version + "-" + systemsoftware.Release; + + string installType = "initial"; + + if ( EEPackageType == "rpm" ) + { + cout << "Performing a MariaDB ColumnStore System install using RPM packages" << endl; + cout << "located in the " + HOME + " directory." << endl << endl; + } + else + { + if ( EEPackageType == "binary" ) { - oam.getSystemSoftware(systemsoftware); - } - catch (exception& e) - { - cout << " ERROR: reading getSystemSoftware API" << endl; - exit (1); - } - - cout << endl; - - string version = systemsoftware.Version + "-" + systemsoftware.Release; - - string installType = "initial"; - - if ( EEPackageType == "rpm" ) - { - cout << "Performing a MariaDB ColumnStore System install using RPM packages" << endl; + cout << "Performing a MariaDB ColumnStore System install using a Binary package" << endl; cout << "located in the " + HOME + " directory." << endl << endl; } else { - if ( EEPackageType == "binary" ) - { - cout << "Performing a MariaDB ColumnStore System install using a Binary package" << endl; - cout << "located in the " + HOME + " directory." << endl << endl; - } - else - { - cout << "Performing a MariaDB ColumnStore System install using using DEB packages" << endl; - cout << "located in the " + HOME + " directory." << endl; - } + cout << "Performing a MariaDB ColumnStore System install using using DEB packages" << endl; + cout << "located in the " + HOME + " directory." << endl; } + } - //check if pkgs are located in $HOME directory - if ( EEPackageType == "rpm") - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm"; + //check if pkgs are located in $HOME directory + if ( EEPackageType == "rpm") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm"; + else + if ( EEPackageType == "deb") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb"; else - if ( EEPackageType == "deb") - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb"; - else - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.bin.tar.gz"; + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.bin.tar.gz"; - if( !pkgCheck(columnstorePackage) ) - exit(1); + if( !pkgCheck(columnstorePackage) ) + exit(1); - if ( password.empty() ) - { - cout << endl; - cout << "Next step is to enter the password to access the other Servers." << endl; - cout << "This is either your password or you can default to using a ssh key" << endl; - cout << "If using a password, the password needs to be the same on all Servers." << endl << endl; - } + if ( password.empty() ) + { + cout << endl; + cout << "Next step is to enter the password to access the other Servers." << endl; + cout << "This is either your password or you can default to using a ssh key" << endl; + cout << "If using a password, the password needs to be the same on all Servers." << endl << endl; + } - while(true) - { - char *pass1, *pass2; + while(true) + { + char *pass1, *pass2; - if ( noPrompting ) { - cout << "Enter password, hit 'enter' to default to using a ssh key, or 'exit' > " << endl; - if ( password.empty() ) - password = "ssh"; - break; - } - - //check for command line option password - if ( !password.empty() ) - break; - - pass1=getpass("Enter password, hit 'enter' to default to using a ssh key, or 'exit' > "); - if ( strcmp(pass1, "") == 0 ) { + if ( noPrompting ) { + cout << "Enter password, hit 'enter' to default to using a ssh key, or 'exit' > " << endl; + if ( password.empty() ) password = "ssh"; - break; - } + break; + } - if ( pass1 == "exit") - exit(0); + //check for command line option password + if ( !password.empty() ) + break; - string p1 = pass1; - pass2=getpass("Confirm password > "); - string p2 = pass2; - if ( p1 == p2 ) { - password = p2; - break; + pass1=getpass("Enter password, hit 'enter' to default to using a ssh key, or 'exit' > "); + if ( strcmp(pass1, "") == 0 ) { + password = "ssh"; + break; + } + + if ( pass1 == "exit") + exit(0); + + string p1 = pass1; + pass2=getpass("Confirm password > "); + string p2 = pass2; + if ( p1 == p2 ) { + password = p2; + break; + } + else + cout << "Password mismatch, please re-enter" << endl; + } + + //add single quote for special characters + if ( password != "ssh" ) + { + password = "'" + password + "'"; + } + + checkSystemMySQLPort(mysqlPort, sysConfig, USER, password, childmodulelist, IserverTypeInstall, pmwithum); + + if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || + ( (IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) && pmwithum ) ) + { + cout << endl << "===== Running the MariaDB ColumnStore MariaDB ColumnStore setup scripts =====" << endl << endl; + + // call the mysql setup scripts + mysqlSetup(); + sleep(5); + } + + string AmazonInstall = "0"; + if ( amazonInstall ) + AmazonInstall = "1"; + + ChildModuleList::iterator list1 = childmodulelist.begin(); + for (; list1 != childmodulelist.end() ; list1++) + { + string remoteModuleName = (*list1).moduleName; + string remoteModuleIP = (*list1).moduleIP; + string remoteHostName = (*list1).hostName; + string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + + string debug_logfile; + string logfile; + if ( remote_installer_debug == "1" ) { + logfile = "/tmp/"; + logfile += remoteModuleName + "_" + EEPackageType + "_install.log"; + debug_logfile = " > " + logfile; + } + + if ( remoteModuleType == "um" || + (remoteModuleType == "pm" && IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM) || + (remoteModuleType == "pm" && pmwithum) ) + { + cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; + + if ( remote_installer_debug == "1" ) + cout << "Install log file is located here: " + logfile << endl << endl; + + if ( EEPackageType != "binary" ) { + string temppwprompt = pwprompt; + if ( pwprompt == " " ) + temppwprompt = "none"; + + //run remote installer script + cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; + + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; + + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); + + if ( status != 0 ) + { + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } + thread_id++; } else - cout << "Password mismatch, please re-enter" << endl; + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); + } + + //check for mysql password on remote UM +/* if ( pwprompt == " " ) { + //start mysqld + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore start'"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from mysql-Columnstore start" << endl; + exit(1); + } + + //try to login + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from remote_command.sh" << endl; + exit(1); + } + + if (oam.checkLogStatus("/tmp/idbmysql.log", "ERROR .my.cnf") ) { + // password needed check and get password from remote UM + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "bin/getMySQLpw > /tmp/mysqlpw.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "MariaDB ColumnStore login failure, MySQL Root password is set." << endl; + cout << "Need MariaDB ColumnStore password configuration file " + HOME + "/.my.cnf on " << remoteModuleName << endl; + exit(1); + } + + //get password from local tmp file + try { + mysqlpw = oam.getMySQLPassword(); + } + catch(...) + { + mysqlpw = oam::UnassignedName; + } + + if ( mysqlpw != oam::UnassignedName ) + { + mysqlpw = "'" + mysqlpw + "'"; + pwprompt = "--password=" + mysqlpw; + } + + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; + exit(1); + } + } + else + { + if (!oam.checkLogStatus("/tmp/idbmysql.log", "Columnstore") ) { + cout << endl << "ERROR: MariaDB ColumnStore runtime error, exit..." << endl << endl; + system("cat /tmp/idbmysql.log"); + exit (1); + } + else + { + cout << endl << "Additional MariaDB ColumnStore Installation steps Successfully Completed on '" + remoteModuleName + "'" << endl << endl; + + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore stop'"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from mysql-Columnstore stop" << endl; + exit(1); + } + unlink("/tmp/idbmysql.log"); + break; + } + } + + //re-run post-mysql-install with password + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/post-mysql-install " + pwprompt + "' < /tmp/post-mysql-install.log"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from post-mysql-install, check /tmp/post-mysql-install.log" << endl; + exit(1); + } + else + cout << endl << "post-mysql-install Successfully Completed" << endl; + } +*/ } } + else + { // do a binary package install + string binservertype = serverTypeInstall; + if ( pmwithum ) + binservertype = "pmwithum"; - //add single quote for special characters - if ( password != "ssh" ) - { - password = "'" + password + "'"; - } - - checkSystemMySQLPort(mysqlPort, sysConfig, USER, password, childmodulelist, IserverTypeInstall, pmwithum); + cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + + remoteModuleIP + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + remote_installer_debug + + " " + installDir + " " + debug_logfile; - if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || - ( (IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) && pmwithum ) ) - { - cout << endl << "===== Running the MariaDB ColumnStore MariaDB ColumnStore setup scripts =====" << endl << endl; + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; - // call the mysql setup scripts - mysqlSetup(); - sleep(5); - } + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - string AmazonInstall = "0"; - if ( amazonInstall ) - AmazonInstall = "1"; + if ( status != 0 ) + { + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } - ChildModuleList::iterator list1 = childmodulelist.begin(); - for (; list1 != childmodulelist.end() ; list1++) - { - string remoteModuleName = (*list1).moduleName; - string remoteModuleIP = (*list1).moduleIP; - string remoteHostName = (*list1).hostName; - string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); - - string debug_logfile; - string logfile; - if ( remote_installer_debug == "1" ) { - logfile = "/tmp/"; - logfile += remoteModuleName + "_" + EEPackageType + "_install.log"; - debug_logfile = " > " + logfile; + thread_id++; } - - if ( remoteModuleType == "um" || - (remoteModuleType == "pm" && IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM) || - (remoteModuleType == "pm" && pmwithum) ) + else + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); + } + } + } + } + else + { + if ( (remoteModuleType == "pm" && IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) || + (remoteModuleType == "pm" && !pmwithum ) ) { cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; @@ -2921,236 +3076,81 @@ int main(int argc, char *argv[]) cout << "Install log file is located here: " + logfile << endl << endl; if ( EEPackageType != "binary" ) { - string temppwprompt = pwprompt; - if ( pwprompt == " " ) - temppwprompt = "none"; - - //run remote installer script - cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; + //run remote installer script + cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - thread_id++; - } - else - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - //check for mysql password on remote UM -/* if ( pwprompt == " " ) { - //start mysqld - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore start'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore start" << endl; - exit(1); - } - - //try to login - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from remote_command.sh" << endl; - exit(1); - } - - if (oam.checkLogStatus("/tmp/idbmysql.log", "ERROR .my.cnf") ) { - // password needed check and get password from remote UM - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "bin/getMySQLpw > /tmp/mysqlpw.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, MySQL Root password is set." << endl; - cout << "Need MariaDB ColumnStore password configuration file " + HOME + "/.my.cnf on " << remoteModuleName << endl; - exit(1); - } - - //get password from local tmp file - try { - mysqlpw = oam.getMySQLPassword(); - } - catch(...) - { - mysqlpw = oam::UnassignedName; - } - - if ( mysqlpw != oam::UnassignedName ) - { - mysqlpw = "'" + mysqlpw + "'"; - pwprompt = "--password=" + mysqlpw; - } - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; - exit(1); - } - } - else - { - if (!oam.checkLogStatus("/tmp/idbmysql.log", "Columnstore") ) { - cout << endl << "ERROR: MariaDB ColumnStore runtime error, exit..." << endl << endl; - system("cat /tmp/idbmysql.log"); - exit (1); - } - else - { - cout << endl << "Additional MariaDB ColumnStore Installation steps Successfully Completed on '" + remoteModuleName + "'" << endl << endl; - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore stop'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore stop" << endl; - exit(1); - } - unlink("/tmp/idbmysql.log"); - break; - } - } - - //re-run post-mysql-install with password - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/post-mysql-install " + pwprompt + "' < /tmp/post-mysql-install.log"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from post-mysql-install, check /tmp/post-mysql-install.log" << endl; - exit(1); - } - else - cout << endl << "post-mysql-install Successfully Completed" << endl; - } -*/ } - } - else - { // do a binary package install - string binservertype = serverTypeInstall; - if ( pmwithum ) - binservertype = "pmwithum"; - - cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + - remoteModuleIP + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + remote_installer_debug + - " " + installDir + " " + debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; - } - else - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } - } - } - } - else - { - if ( (remoteModuleType == "pm" && IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) || - (remoteModuleType == "pm" && !pmwithum ) ) - { - cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; - - if ( remote_installer_debug == "1" ) - cout << "Install log file is located here: " + logfile << endl << endl; - - if ( EEPackageType != "binary" ) { - //run remote installer script - cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; - } - else + if ( status != 0 ) { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); } + + thread_id++; } else - { // do a binary package install - string binservertype = serverTypeInstall; - if ( pmwithum ) - binservertype = "pmwithum"; - cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + - " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + - remote_installer_debug + " " + installDir + " " + - debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); } - else + } + } + else + { // do a binary package install + string binservertype = serverTypeInstall; + if ( pmwithum ) + binservertype = "pmwithum"; + cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + + remote_installer_debug + " " + installDir + " " + + debug_logfile; + + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; + + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); + + if ( status != 0 ) { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } + + thread_id++; + } + else + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); } } } } } - - if ( thread_remote_installer ) { - - //wait until remove install Thread Count is at zero or hit timeout - cout << endl << "MariaDB ColumnStore Package being installed, please wait ..."; - cout.flush(); - - /* block until all threads complete */ - for (thread_id = 0; thread_id < (int) childmodulelist.size(); ++thread_id) { - pthread_join(thr[thread_id], NULL); - } - - cout << " DONE" << endl; - } } + + if ( thread_remote_installer ) { + + //wait until remove install Thread Count is at zero or hit timeout + cout << endl << "MariaDB ColumnStore Package being installed, please wait ..."; + cout.flush(); + + /* block until all threads complete */ + for (thread_id = 0; thread_id < (int) childmodulelist.size(); ++thread_id) { + pthread_join(thr[thread_id], NULL); + } + + cout << " DONE" << endl; + } + } else { if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || From 2ff827f3f4431cca187ee88f68bfae07c79d47f0 Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 9 Nov 2017 10:29:12 -0600 Subject: [PATCH 169/185] increase procmgr wait for procmon start timeout value. 60 to 120. needed for amazon --- procmgr/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/procmgr/main.cpp b/procmgr/main.cpp index f54ff09be..14839a0f7 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -502,7 +502,7 @@ static void startMgrProcessThread() ModuleTypeConfig PMSmoduletypeconfig; ALARMManager aManager; - int waitTime = 60; + int waitTime = 120; log.writeLog(__LINE__, "startMgrProcessThread launched", LOG_TYPE_DEBUG); From 21ca6ca42fc3d0f34b22976b9939b8f01ace4af4 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 9 Nov 2017 17:28:21 +0000 Subject: [PATCH 170/185] MCOL-1021 Fix dictionary de-duplication cache The signatures were getting destroyed whilst processing before being used in the dictionary de-duplication cache making the cache full of empty strings. This fix resets the signature after insertion for the cache. This fix also lets the signature cache be read when there is 1000 entries in it. --- writeengine/dictionary/we_dctnry.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/writeengine/dictionary/we_dctnry.cpp b/writeengine/dictionary/we_dctnry.cpp index 8a4b9d2af..59411b951 100644 --- a/writeengine/dictionary/we_dctnry.cpp +++ b/writeengine/dictionary/we_dctnry.cpp @@ -628,6 +628,8 @@ int Dctnry::insertDctnry2(Signature& sig) int rc = 0; int write_size; bool lbid_in_token = false; + size_t origSigSize = sig.size; + unsigned char* origSig = sig.signature; sig.token.bc = 0; @@ -718,6 +720,8 @@ int Dctnry::insertDctnry2(Signature& sig) } } + sig.size = origSigSize; + sig.signature = origSig; return NO_ERROR; } @@ -825,8 +829,7 @@ int Dctnry::insertDctnry(const char* buf, //...Search for the string in our string cache //if it fits into one block (< 8KB) - if ((m_arraySize < MAX_STRING_CACHE_SIZE) && - (curSig.size <= MAX_SIGNATURE_SIZE)) + if (curSig.size <= MAX_SIGNATURE_SIZE) { //Stats::startParseEvent("getTokenFromArray"); found = getTokenFromArray(curSig); @@ -1375,8 +1378,7 @@ int Dctnry::updateDctnry(unsigned char* sigValue, int& sigSize, // Look for string in cache // As long as the string <= 8000 bytes - if ((m_arraySize < MAX_STRING_CACHE_SIZE) && - (sigSize <= MAX_SIGNATURE_SIZE)) + if (sigSize <= MAX_SIGNATURE_SIZE) { bool found = false; found = getTokenFromArray(sig); From cecc9edf7b034be7bffab6adead4fc6d13d43fa5 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Nov 2017 08:22:29 -0600 Subject: [PATCH 171/185] remove password passing in post-mysql-install --- oamapps/postConfigure/helpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oamapps/postConfigure/helpers.cpp b/oamapps/postConfigure/helpers.cpp index 3d84496ed..b53a17302 100644 --- a/oamapps/postConfigure/helpers.cpp +++ b/oamapps/postConfigure/helpers.cpp @@ -259,7 +259,7 @@ void mysqlSetup() HOME = p; } - cmd = installDir + "/bin/post-mysql-install " + pwprompt + " --installdir=" + installDir + " > /tmp/post-mysql-install.log";; + cmd = installDir + "/bin/post-mysql-install --installdir=" + installDir + " > /tmp/post-mysql-install.log";; rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 2) { cout << "Error running post-mysql-install, password is needed. check " + HOME + "/.my.cnf " << endl; From 22d3016e524cc3c3a0d9ff646e54b4e666d81abf Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Nov 2017 10:44:43 -0600 Subject: [PATCH 172/185] fix issue with amazon install problems, rc.local not setup and addmodule failing due to login issues --- oam/install_scripts/module_installer.sh | 8 +- oamapps/postConfigure/helpers.cpp | 2 +- oamapps/postConfigure/installer.cpp | 29 +++---- oamapps/postConfigure/postConfigure.cpp | 110 +++--------------------- procmgr/processmanager.cpp | 3 + 5 files changed, 36 insertions(+), 116 deletions(-) diff --git a/oam/install_scripts/module_installer.sh b/oam/install_scripts/module_installer.sh index 343d022c0..10cefaf5f 100755 --- a/oam/install_scripts/module_installer.sh +++ b/oam/install_scripts/module_installer.sh @@ -86,8 +86,6 @@ mid=`module_id` #if um, cloud, separate system type, external um storage, then setup mount if [ $module = "um" ]; then if [ $cloud = "amazon-ec2" ] || [ $cloud = "amazon-vpc" ]; then - $SUDO sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1 - systemtype=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation ServerTypeInstall` if [ $systemtype = "1" ]; then umstoragetype=`$COLUMNSTORE_INSTALL_DIR/bin/getConfig Installation UMStorageType` @@ -181,6 +179,7 @@ else fi touch $RCFILE +echo "add deadline to rc.local" if [ $module = "um" ]; then if [ $user = "root" ]; then echo "for scsi_dev in \`mount | awk '/mnt\\/tmp/ {print $1}' | awk -F/ '{print $3}' | sed 's/[0-9]*$//'\`; do" >> $RCFILE @@ -213,6 +212,11 @@ else fi fi +if [ $user != "root" ]; then + echo "uncomment runuser in rc.local" + sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1 +fi + echo "!!!Module Installation Successfully Completed!!!" exit 0 diff --git a/oamapps/postConfigure/helpers.cpp b/oamapps/postConfigure/helpers.cpp index 3d84496ed..b53a17302 100644 --- a/oamapps/postConfigure/helpers.cpp +++ b/oamapps/postConfigure/helpers.cpp @@ -259,7 +259,7 @@ void mysqlSetup() HOME = p; } - cmd = installDir + "/bin/post-mysql-install " + pwprompt + " --installdir=" + installDir + " > /tmp/post-mysql-install.log";; + cmd = installDir + "/bin/post-mysql-install --installdir=" + installDir + " > /tmp/post-mysql-install.log";; rtnCode = system(cmd.c_str()); if (WEXITSTATUS(rtnCode) == 2) { cout << "Error running post-mysql-install, password is needed. check " + HOME + "/.my.cnf " << endl; diff --git a/oamapps/postConfigure/installer.cpp b/oamapps/postConfigure/installer.cpp index d165e7756..548636980 100644 --- a/oamapps/postConfigure/installer.cpp +++ b/oamapps/postConfigure/installer.cpp @@ -1018,8 +1018,6 @@ bool updateProcessConfig(int serverTypeInstall) */ bool makeRClocal(string moduleName, int IserverTypeInstall) { - string cmd; - string moduleType = moduleName.substr(0,MAX_MODULE_TYPE_SIZE); vector lines; @@ -1096,27 +1094,26 @@ bool makeRClocal(string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - - string fileName = "/etc/rc.d/rc.local"; - - ofstream newFile (fileName.c_str()); - if (!newFile) + + string RCfileName = "/etc/rc.d/rc.local"; + std::ofstream file; + + file.open(RCfileName.c_str(), std::ios::out | std::ios::app); + if (file.fail()) { - fileName = "/etc/rc.local"; + RCfileName = "/etc/rc.local"; - ofstream newFile (fileName.c_str()); - if (!newFile) + file.open(RCfileName.c_str(), std::ios::out | std::ios::app); + if (file.fail()) return true; } - //create new file - int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0666); + file.exceptions(file.exceptions() | std::ios::failbit | std::ifstream::badbit); - copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); - newFile.close(); + copy(lines.begin(), lines.end(), ostream_iterator(file, "\n")); + + file.close(); - close(fd); - return true; } diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index fb02d27d9..ae9569260 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2965,90 +2965,7 @@ int main(int argc, char *argv[]) cout << endl << "Error returned from package_installer.sh" << endl; exit(1); } - - //check for mysql password on remote UM -/* if ( pwprompt == " " ) { - //start mysqld - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore start'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore start" << endl; - exit(1); - } - - //try to login - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from remote_command.sh" << endl; - exit(1); - } - - if (oam.checkLogStatus("/tmp/idbmysql.log", "ERROR .my.cnf") ) { - // password needed check and get password from remote UM - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "bin/getMySQLpw > /tmp/mysqlpw.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, MySQL Root password is set." << endl; - cout << "Need MariaDB ColumnStore password configuration file " + HOME + "/.my.cnf on " << remoteModuleName << endl; - exit(1); - } - - //get password from local tmp file - try { - mysqlpw = oam.getMySQLPassword(); - } - catch(...) - { - mysqlpw = oam::UnassignedName; - } - - if ( mysqlpw != oam::UnassignedName ) - { - mysqlpw = "'" + mysqlpw + "'"; - pwprompt = "--password=" + mysqlpw; - } - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; - exit(1); - } - } - else - { - if (!oam.checkLogStatus("/tmp/idbmysql.log", "Columnstore") ) { - cout << endl << "ERROR: MariaDB ColumnStore runtime error, exit..." << endl << endl; - system("cat /tmp/idbmysql.log"); - exit (1); - } - else - { - cout << endl << "Additional MariaDB ColumnStore Installation steps Successfully Completed on '" + remoteModuleName + "'" << endl << endl; - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore stop'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore stop" << endl; - exit(1); - } - unlink("/tmp/idbmysql.log"); - break; - } - } - - //re-run post-mysql-install with password - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/post-mysql-install " + pwprompt + "' < /tmp/post-mysql-install.log"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from post-mysql-install, check /tmp/post-mysql-install.log" << endl; - exit(1); - } - else - cout << endl << "post-mysql-install Successfully Completed" << endl; - } -*/ } + } } else { // do a binary package install @@ -4006,26 +3923,25 @@ bool makeRClocal(string moduleType, string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - string fileName = "/etc/rc.d/rc.local"; - - ofstream newFile (fileName.c_str()); - if (!newFile) + string RCfileName = "/etc/rc.d/rc.local"; + std::ofstream file; + + file.open(RCfileName.c_str(), std::ios::out | std::ios::app); + if (file.fail()) { - fileName = "/etc/rc.local"; + RCfileName = "/etc/rc.local"; - ofstream newFile (fileName.c_str()); - if (!newFile) + file.open(RCfileName.c_str(), std::ios::out | std::ios::app); + if (file.fail()) return true; } - //create new file - int fd = open(fileName.c_str(), O_RDWR|O_CREAT, 0666); + file.exceptions(file.exceptions() | std::ios::failbit | std::ifstream::badbit); - copy(lines.begin(), lines.end(), ostream_iterator(newFile, "\n")); - newFile.close(); + copy(lines.begin(), lines.end(), ostream_iterator(file, "\n")); + + file.close(); - close(fd); - return true; } diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 492dc9b05..5fee029e1 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -5050,6 +5050,9 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str //distribute config file distributeConfigFile("system"); + + string cmd = "rm -f " + homedir + "/.ssh/known_hosts > /dev/null 2>&1"; + system(cmd.c_str()); if ( DistributedInstall == "y" ) { From b43afdb8e9da96244ecf2d0426d4474190d98353 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Nov 2017 11:12:52 -0600 Subject: [PATCH 173/185] add back in remove prompt changes --- oamapps/postConfigure/postConfigure.cpp | 586 +++++++++++++----------- 1 file changed, 321 insertions(+), 265 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index ae9569260..4a371f357 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -2778,160 +2778,297 @@ int main(int argc, char *argv[]) // cout << endl << "===== System Installation =====" << endl << endl; - cout << "System Configuration is complete, System Installation is the next step." << endl; + cout << "System Configuration is complete." << endl; + cout << "Performing System Installation." << endl; - while(true) + SystemSoftware systemsoftware; + + try { - pcommand = callReadline("Would you like to continue with the System Installation? [y,n] (y) > "); - if (pcommand) - { - if (strlen(pcommand) > 0) install = pcommand; - callFree(pcommand); - } - if ( install == "y" || install == "n" ) - break; - else - cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; - install = "y"; - if ( noPrompting ) - exit(1); + oam.getSystemSoftware(systemsoftware); + } + catch (exception& e) + { + cout << " ERROR: reading getSystemSoftware API" << endl; + exit (1); } - if ( install == "y" ) + cout << endl; + + string version = systemsoftware.Version + "-" + systemsoftware.Release; + + string installType = "initial"; + + if ( EEPackageType == "rpm" ) { - SystemSoftware systemsoftware; - - try + cout << "Performing a MariaDB ColumnStore System install using RPM packages" << endl; + cout << "located in the " + HOME + " directory." << endl << endl; + } + else + { + if ( EEPackageType == "binary" ) { - oam.getSystemSoftware(systemsoftware); - } - catch (exception& e) - { - cout << " ERROR: reading getSystemSoftware API" << endl; - exit (1); - } - - cout << endl; - - string version = systemsoftware.Version + "-" + systemsoftware.Release; - - string installType = "initial"; - - if ( EEPackageType == "rpm" ) - { - cout << "Performing a MariaDB ColumnStore System install using RPM packages" << endl; + cout << "Performing a MariaDB ColumnStore System install using a Binary package" << endl; cout << "located in the " + HOME + " directory." << endl << endl; } else { - if ( EEPackageType == "binary" ) - { - cout << "Performing a MariaDB ColumnStore System install using a Binary package" << endl; - cout << "located in the " + HOME + " directory." << endl << endl; - } - else - { - cout << "Performing a MariaDB ColumnStore System install using using DEB packages" << endl; - cout << "located in the " + HOME + " directory." << endl; - } + cout << "Performing a MariaDB ColumnStore System install using using DEB packages" << endl; + cout << "located in the " + HOME + " directory." << endl; } + } - //check if pkgs are located in $HOME directory - if ( EEPackageType == "rpm") - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm"; + //check if pkgs are located in $HOME directory + if ( EEPackageType == "rpm") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.rpm"; + else + if ( EEPackageType == "deb") + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb"; else - if ( EEPackageType == "deb") - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.deb"; - else - columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.bin.tar.gz"; + columnstorePackage = HOME + "/" + "mariadb-columnstore-" + version + "*.bin.tar.gz"; - if( !pkgCheck(columnstorePackage) ) - exit(1); + if( !pkgCheck(columnstorePackage) ) + exit(1); - if ( password.empty() ) - { - cout << endl; - cout << "Next step is to enter the password to access the other Servers." << endl; - cout << "This is either your password or you can default to using a ssh key" << endl; - cout << "If using a password, the password needs to be the same on all Servers." << endl << endl; - } + if ( password.empty() ) + { + cout << endl; + cout << "Next step is to enter the password to access the other Servers." << endl; + cout << "This is either your password or you can default to using a ssh key" << endl; + cout << "If using a password, the password needs to be the same on all Servers." << endl << endl; + } - while(true) - { - char *pass1, *pass2; + while(true) + { + char *pass1, *pass2; - if ( noPrompting ) { - cout << "Enter password, hit 'enter' to default to using a ssh key, or 'exit' > " << endl; - if ( password.empty() ) - password = "ssh"; - break; - } - - //check for command line option password - if ( !password.empty() ) - break; - - pass1=getpass("Enter password, hit 'enter' to default to using a ssh key, or 'exit' > "); - if ( strcmp(pass1, "") == 0 ) { + if ( noPrompting ) { + cout << "Enter password, hit 'enter' to default to using a ssh key, or 'exit' > " << endl; + if ( password.empty() ) password = "ssh"; - break; - } + break; + } - if ( pass1 == "exit") - exit(0); + //check for command line option password + if ( !password.empty() ) + break; - string p1 = pass1; - pass2=getpass("Confirm password > "); - string p2 = pass2; - if ( p1 == p2 ) { - password = p2; - break; + pass1=getpass("Enter password, hit 'enter' to default to using a ssh key, or 'exit' > "); + if ( strcmp(pass1, "") == 0 ) { + password = "ssh"; + break; + } + + if ( pass1 == "exit") + exit(0); + + string p1 = pass1; + pass2=getpass("Confirm password > "); + string p2 = pass2; + if ( p1 == p2 ) { + password = p2; + break; + } + else + cout << "Password mismatch, please re-enter" << endl; + } + + //add single quote for special characters + if ( password != "ssh" ) + { + password = "'" + password + "'"; + } + + checkSystemMySQLPort(mysqlPort, sysConfig, USER, password, childmodulelist, IserverTypeInstall, pmwithum); + + if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || + ( (IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) && pmwithum ) ) + { + cout << endl << "===== Running the MariaDB ColumnStore MariaDB ColumnStore setup scripts =====" << endl << endl; + + // call the mysql setup scripts + mysqlSetup(); + sleep(5); + } + + string AmazonInstall = "0"; + if ( amazonInstall ) + AmazonInstall = "1"; + + ChildModuleList::iterator list1 = childmodulelist.begin(); + for (; list1 != childmodulelist.end() ; list1++) + { + string remoteModuleName = (*list1).moduleName; + string remoteModuleIP = (*list1).moduleIP; + string remoteHostName = (*list1).hostName; + string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); + + string debug_logfile; + string logfile; + if ( remote_installer_debug == "1" ) { + logfile = "/tmp/"; + logfile += remoteModuleName + "_" + EEPackageType + "_install.log"; + debug_logfile = " > " + logfile; + } + + if ( remoteModuleType == "um" || + (remoteModuleType == "pm" && IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM) || + (remoteModuleType == "pm" && pmwithum) ) + { + cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; + + if ( remote_installer_debug == "1" ) + cout << "Install log file is located here: " + logfile << endl << endl; + + if ( EEPackageType != "binary" ) { + string temppwprompt = pwprompt; + if ( pwprompt == " " ) + temppwprompt = "none"; + + //run remote installer script + cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; + + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; + + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); + + if ( status != 0 ) + { + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } + thread_id++; } else - cout << "Password mismatch, please re-enter" << endl; + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); + } + + //check for mysql password on remote UM +/* if ( pwprompt == " " ) { + //start mysqld + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore start'"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from mysql-Columnstore start" << endl; + exit(1); + } + + //try to login + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from remote_command.sh" << endl; + exit(1); + } + + if (oam.checkLogStatus("/tmp/idbmysql.log", "ERROR .my.cnf") ) { + // password needed check and get password from remote UM + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "bin/getMySQLpw > /tmp/mysqlpw.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "MariaDB ColumnStore login failure, MySQL Root password is set." << endl; + cout << "Need MariaDB ColumnStore password configuration file " + HOME + "/.my.cnf on " << remoteModuleName << endl; + exit(1); + } + + //get password from local tmp file + try { + mysqlpw = oam.getMySQLPassword(); + } + catch(...) + { + mysqlpw = oam::UnassignedName; + } + + if ( mysqlpw != oam::UnassignedName ) + { + mysqlpw = "'" + mysqlpw + "'"; + pwprompt = "--password=" + mysqlpw; + } + + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; + exit(1); + } + } + else + { + if (!oam.checkLogStatus("/tmp/idbmysql.log", "Columnstore") ) { + cout << endl << "ERROR: MariaDB ColumnStore runtime error, exit..." << endl << endl; + system("cat /tmp/idbmysql.log"); + exit (1); + } + else + { + cout << endl << "Additional MariaDB ColumnStore Installation steps Successfully Completed on '" + remoteModuleName + "'" << endl << endl; + + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore stop'"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from mysql-Columnstore stop" << endl; + exit(1); + } + unlink("/tmp/idbmysql.log"); + break; + } + } + + //re-run post-mysql-install with password + cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/post-mysql-install " + pwprompt + "' < /tmp/post-mysql-install.log"; + rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from post-mysql-install, check /tmp/post-mysql-install.log" << endl; + exit(1); + } + else + cout << endl << "post-mysql-install Successfully Completed" << endl; + } +*/ } } + else + { // do a binary package install + string binservertype = serverTypeInstall; + if ( pmwithum ) + binservertype = "pmwithum"; - //add single quote for special characters - if ( password != "ssh" ) - { - password = "'" + password + "'"; - } - - checkSystemMySQLPort(mysqlPort, sysConfig, USER, password, childmodulelist, IserverTypeInstall, pmwithum); + cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + + remoteModuleIP + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + remote_installer_debug + + " " + installDir + " " + debug_logfile; - if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || - ( (IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) && pmwithum ) ) - { - cout << endl << "===== Running the MariaDB ColumnStore MariaDB ColumnStore setup scripts =====" << endl << endl; + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; - // call the mysql setup scripts - mysqlSetup(); - sleep(5); - } + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - string AmazonInstall = "0"; - if ( amazonInstall ) - AmazonInstall = "1"; + if ( status != 0 ) + { + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } - ChildModuleList::iterator list1 = childmodulelist.begin(); - for (; list1 != childmodulelist.end() ; list1++) - { - string remoteModuleName = (*list1).moduleName; - string remoteModuleIP = (*list1).moduleIP; - string remoteHostName = (*list1).hostName; - string remoteModuleType = remoteModuleName.substr(0,MAX_MODULE_TYPE_SIZE); - - string debug_logfile; - string logfile; - if ( remote_installer_debug == "1" ) { - logfile = "/tmp/"; - logfile += remoteModuleName + "_" + EEPackageType + "_install.log"; - debug_logfile = " > " + logfile; + thread_id++; } - - if ( remoteModuleType == "um" || - (remoteModuleType == "pm" && IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM) || - (remoteModuleType == "pm" && pmwithum) ) + else + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); + } + } + } + } + else + { + if ( (remoteModuleType == "pm" && IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) || + (remoteModuleType == "pm" && !pmwithum ) ) { cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; @@ -2939,162 +3076,81 @@ int main(int argc, char *argv[]) cout << "Install log file is located here: " + logfile << endl << endl; if ( EEPackageType != "binary" ) { - string temppwprompt = pwprompt; - if ( pwprompt == " " ) - temppwprompt = "none"; - - //run remote installer script - cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; + //run remote installer script + cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - thread_id++; - } - else - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } - } - } - else - { // do a binary package install - string binservertype = serverTypeInstall; - if ( pmwithum ) - binservertype = "pmwithum"; + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + - remoteModuleIP + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + remote_installer_debug + - " " + installDir + " " + debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; - } - else - { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } - } - } - } - else - { - if ( (remoteModuleType == "pm" && IserverTypeInstall != oam::INSTALL_COMBINE_DM_UM_PM) || - (remoteModuleType == "pm" && !pmwithum ) ) - { - cout << endl << "----- Performing Install on '" + remoteModuleName + " / " + remoteHostName + "' -----" << endl << endl; - - if ( remote_installer_debug == "1" ) - cout << "Install log file is located here: " + logfile << endl << endl; - - if ( EEPackageType != "binary" ) { - //run remote installer script - cmd = installDir + "/bin/package_installer.sh " + remoteModuleName + " " + remoteModuleIP + " " + password + " " + version + " initial " + AmazonInstall + " " + EEPackageType + " " + nodeps + " " + remote_installer_debug + " " + debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; - } - else + if ( status != 0 ) { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); } + + thread_id++; } else - { // do a binary package install - string binservertype = serverTypeInstall; - if ( pmwithum ) - binservertype = "pmwithum"; - cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + - " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + - remote_installer_debug + " " + installDir + " " + - debug_logfile; - - if ( thread_remote_installer ) { - thr_data[thread_id].command = cmd; - - int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); - - if ( status != 0 ) - { - cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; - exit (1); - } - - thread_id++; + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); } - else + } + } + else + { // do a binary package install + string binservertype = serverTypeInstall; + if ( pmwithum ) + binservertype = "pmwithum"; + cmd = installDir + "/bin/binary_installer.sh " + remoteModuleName + " " + remoteModuleIP + + " " + password + " " + columnstorePackage + " " + installType + " " + AmazonInstall + " " + + remote_installer_debug + " " + installDir + " " + + debug_logfile; + + if ( thread_remote_installer ) { + thr_data[thread_id].command = cmd; + + int status = pthread_create (&thr[thread_id], NULL, (void*(*)(void*)) &remoteInstallThread, &thr_data[thread_id]); + + if ( status != 0 ) { - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from package_installer.sh" << endl; - exit(1); - } + cout << "remoteInstallThread failed for " << remoteModuleName << ", exiting" << endl; + exit (1); + } + + thread_id++; + } + else + { + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << endl << "Error returned from package_installer.sh" << endl; + exit(1); } } } } } - - if ( thread_remote_installer ) { - - //wait until remove install Thread Count is at zero or hit timeout - cout << endl << "MariaDB ColumnStore Package being installed, please wait ..."; - cout.flush(); - - /* block until all threads complete */ - for (thread_id = 0; thread_id < (int) childmodulelist.size(); ++thread_id) { - pthread_join(thr[thread_id], NULL); - } - - cout << " DONE" << endl; - } } - else - { - if (DataRedundancy && install != "y") - { - cout << endl << "Must choose to install with DataRedundancy configured." << endl; - exit(1); + + if ( thread_remote_installer ) { + + //wait until remove install Thread Count is at zero or hit timeout + cout << endl << "MariaDB ColumnStore Package being installed, please wait ..."; + cout.flush(); + + /* block until all threads complete */ + for (thread_id = 0; thread_id < (int) childmodulelist.size(); ++thread_id) { + pthread_join(thr[thread_id], NULL); } + + cout << " DONE" << endl; } - } + } else { if ( ( IserverTypeInstall == oam::INSTALL_COMBINE_DM_UM_PM ) || @@ -3922,7 +3978,7 @@ bool makeRClocal(string moduleType, string moduleName, int IserverTypeInstall) if ( lines.begin() == lines.end()) return true; - + string RCfileName = "/etc/rc.d/rc.local"; std::ofstream file; From b63d9fcce1815e178701599b12df3f9810f6acac Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Nov 2017 13:41:50 -0600 Subject: [PATCH 174/185] MCOL-1024 --- oamapps/postConfigure/installer.cpp | 5 + oamapps/postConfigure/postConfigure.cpp | 299 ++++-------------------- procmgr/processmanager.cpp | 8 - 3 files changed, 48 insertions(+), 264 deletions(-) diff --git a/oamapps/postConfigure/installer.cpp b/oamapps/postConfigure/installer.cpp index 548636980..bc91217f0 100644 --- a/oamapps/postConfigure/installer.cpp +++ b/oamapps/postConfigure/installer.cpp @@ -616,6 +616,7 @@ int main(int argc, char *argv[]) //setup local OS Files if( !setOSFiles(parentOAMModuleName, IserverTypeInstall) ) { cout << "ERROR: setOSFiles error" << endl; + cout << " IMPORTANT: Once issue has been resolved, rerun postConfigure" << endl << endl; exit(1); } @@ -797,6 +798,7 @@ int main(int argc, char *argv[]) if ( !oam.checkLogStatus("/tmp/dbbuilder.log", "System catalog appears to exist") ) { cout << endl << "System Catalog Create Failure" << endl; cout << "Check latest log file in /tmp/dbbuilder.log.*" << endl; + cout << " IMPORTANT: Once issue has been resolved, rerun postConfigure" << endl << endl; exit (1); } } @@ -815,6 +817,9 @@ int main(int argc, char *argv[]) else { cout << " FAILED" << endl; + + cout << " IMPORTANT: There was a system startup failed, once issue has been resolved, rerun postConfigure" << endl << endl; + cout << endl << "ERROR: MariaDB ColumnStore Process failed to start, check log files in /var/log/mariadb/columnstore" << endl; cout << "Enter the following command to define MariaDB ColumnStore Alias Commands" << endl << endl; diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 4a371f357..bbf6cc32e 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -1003,7 +1003,8 @@ int main(int argc, char *argv[]) { if ( cloud == oam::UnassignedName ) { - cout << "NOTE: Amazon AWS CLI Tools are installed and allow MariaDB ColumnStore to create Instances and ABS Volumes" << endl << endl; + cout << "NOTE: Amazon AWS CLI Tools are installed and allow MariaDB ColumnStore" << endl; + cout << " to create Instances and EBS Volumes" << endl << endl; while(true) { string enable = "y"; @@ -2947,90 +2948,7 @@ int main(int argc, char *argv[]) cout << endl << "Error returned from package_installer.sh" << endl; exit(1); } - - //check for mysql password on remote UM -/* if ( pwprompt == " " ) { - //start mysqld - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore start'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore start" << endl; - exit(1); - } - - //try to login - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from remote_command.sh" << endl; - exit(1); - } - - if (oam.checkLogStatus("/tmp/idbmysql.log", "ERROR .my.cnf") ) { - // password needed check and get password from remote UM - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "bin/getMySQLpw > /tmp/mysqlpw.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, MySQL Root password is set." << endl; - cout << "Need MariaDB ColumnStore password configuration file " + HOME + "/.my.cnf on " << remoteModuleName << endl; - exit(1); - } - - //get password from local tmp file - try { - mysqlpw = oam.getMySQLPassword(); - } - catch(...) - { - mysqlpw = oam::UnassignedName; - } - - if ( mysqlpw != oam::UnassignedName ) - { - mysqlpw = "'" + mysqlpw + "'"; - pwprompt = "--password=" + mysqlpw; - } - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/bin/mysql --defaults-extra-file=" + installDir + "/mysql/my.cnf -u root " + pwprompt + " -e status' 1 > /tmp/idbmysql.log 2>&1"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "MariaDB ColumnStore login failure, password mismatch in " + HOME + ".my.cnf on " << remoteModuleName << endl; - exit(1); - } - } - else - { - if (!oam.checkLogStatus("/tmp/idbmysql.log", "Columnstore") ) { - cout << endl << "ERROR: MariaDB ColumnStore runtime error, exit..." << endl << endl; - system("cat /tmp/idbmysql.log"); - exit (1); - } - else - { - cout << endl << "Additional MariaDB ColumnStore Installation steps Successfully Completed on '" + remoteModuleName + "'" << endl << endl; - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/mysql/mysql-Columnstore stop'"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from mysql-Columnstore stop" << endl; - exit(1); - } - unlink("/tmp/idbmysql.log"); - break; - } - } - - //re-run post-mysql-install with password - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/post-mysql-install " + pwprompt + "' < /tmp/post-mysql-install.log"; - rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << endl << "Error returned from post-mysql-install, check /tmp/post-mysql-install.log" << endl; - exit(1); - } - else - cout << endl << "post-mysql-install Successfully Completed" << endl; - } -*/ } + } } else { // do a binary package install @@ -3221,178 +3139,52 @@ int main(int argc, char *argv[]) // cout << endl << "===== MariaDB ColumnStore System Startup =====" << endl << endl; - string start = "y"; - cout << "System Installation is complete. If any part of the install failed," << endl; - cout << "the problem should be investigated and resolved before continuing." << endl << endl; + cout << "System Configuration is complete." << endl; + cout << "Performing System Installation." << endl; - if ( nonDistribute ) - cout << "Non-Distrubuted Install: make sure all other modules have MariaDB ColumnStore" << endl; - cout << "package installed and the associated service started."<< endl << endl; - - while(true) + if (hdfs && !nonDistribute ) { - pcommand = callReadline("Would you like to startup the MariaDB ColumnStore System? [y,n] (y) > "); - if (pcommand) - { - if (strlen(pcommand) > 0) start = pcommand; - callFree(pcommand); + cout << endl << "----- Starting MariaDB ColumnStore Service on all Modules -----" << endl << endl; + string cmd = "pdsh -a '" + installDir + "/bin/columnstore restart' > /tmp/postConfigure.pdsh 2>&1"; + system(cmd.c_str()); + if (oam.checkLogStatus("/tmp/postConfigure.pdsh", "exit") ) { + cout << endl << "ERROR: Starting MariaDB ColumnStore Service failue, check /tmp/postConfigure.pdsh. exit..." << endl; + exit (1); } - if ( start == "y" || start == "n" ) - break; - else - cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; - start = "y"; - if ( noPrompting ) - exit(1); - } - - if ( start == "y" ) { - - if (hdfs && !nonDistribute ) - { - cout << endl << "----- Starting MariaDB ColumnStore Service on all Modules -----" << endl << endl; - string cmd = "pdsh -a '" + installDir + "/bin/columnstore restart' > /tmp/postConfigure.pdsh 2>&1"; - system(cmd.c_str()); - if (oam.checkLogStatus("/tmp/postConfigure.pdsh", "exit") ) { - cout << endl << "ERROR: Starting MariaDB ColumnStore Service failue, check /tmp/postConfigure.pdsh. exit..." << endl; - exit (1); - } - } - else - { -/* if ( !nonDistribute ) - { - if ( password.empty() ) { - while(true) - { - char *pass1, *pass2; - - if ( noPrompting ) { - cout << "Enter your password, hit 'enter' to default to using a ssh key, or 'exit' > " << endl; - if ( password.empty() ) - password = "ssh"; - break; - } - - //check for command line option password - if ( !password.empty() ) - break; - - pass1=getpass("Enter your password, hit 'enter' to default to using a ssh key, or 'exit' > "); - if ( strcmp(pass1, "") == 0 ) { - password = "ssh"; - break; - } - - if ( strcmp(pass1, "exit") == 0 ) - exit(0); - string p1 = pass1; - pass2=getpass("Confirm password > "); - string p2 = pass2; - if ( p1 == p2 ) { - password = p2; - break; - } - else - cout << "Password mismatch, please re-enter" << endl; - } - - //add single quote for special characters - if ( password != "ssh" ) - { - password = "'" + password + "'"; - } - } - - ChildModuleList::iterator list1 = childmodulelist.begin(); - - for (; list1 != childmodulelist.end() ; list1++) - { - string remoteModuleName = (*list1).moduleName; - string remoteModuleIP = (*list1).moduleIP; - string remoteHostName = (*list1).hostName; - - //run remote command script - cout << endl << "----- Starting MariaDB ColumnStore on '" + remoteModuleName + "' -----" << endl << endl; - - if ( install == "n" ) - { // didnt do a full install, push the config file - cmd = installDir + "/bin/remote_scp_put.sh " + remoteModuleIP + " " + installDir + "/etc/Columnstore.xml > /dev/null 2>&1"; - system(cmd.c_str()); - } - - cmd = installDir + "/bin/remote_command.sh " + remoteModuleIP + " " + password + " '" + installDir + "/bin/columnstore restart' 0"; - int rtnCode = system(cmd.c_str()); - - if (WEXITSTATUS(rtnCode) != 0) - cout << "Error with running remote_command.sh" << endl; - else - cout << "MariaDB ColumnStore successfully started" << endl; - } - } -*/ - //start MariaDB ColumnStore on local server - cout << endl << "----- Starting MariaDB ColumnStore on local server -----" << endl << endl; - cmd = installDir + "/bin/columnstore restart > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "Error Starting MariaDB ColumnStore local module" << endl; - cout << "Installation Failed, exiting" << endl; - exit (1); - } - else - cout << "MariaDB ColumnStore successfully started" << endl; - } } else { - cout << endl << "You choose not to Start the MariaDB ColumnStore Software at this time." << endl; - exit (1); + //start MariaDB ColumnStore on local server + cout << endl << "----- Starting MariaDB ColumnStore on local server -----" << endl << endl; + cmd = installDir + "/bin/columnstore restart > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "Error Starting MariaDB ColumnStore local module" << endl; + cout << "Installation Failed, exiting" << endl; + exit (1); + } + else + cout << "MariaDB ColumnStore successfully started" << endl; } } else // Single Server start { cout << endl << "===== MariaDB ColumnStore System Startup =====" << endl << endl; - string start = "y"; - cout << "System Installation is complete." << endl; - cout << "If an error occurred while running the MariaDB ColumnStore setup scripts," << endl; - cout << "this will need to be corrected and postConfigure will need to be re-run." << endl << endl; - while(true) - { - pcommand = callReadline("Would you like to startup the MariaDB ColumnStore System? [y,n] (y) > "); - if (pcommand) - { - if (strlen(pcommand) > 0) start = pcommand; - callFree(pcommand); - } - if ( start == "y" || start == "n" ) - break; - else - cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; - start = "y"; - if ( noPrompting ) - exit(1); - } - - if ( start == "y" ) { - //start MariaDB ColumnStore on local server - cout << endl << "----- Starting MariaDB ColumnStore on local Server '" + parentOAMModuleName + "' -----" << endl << endl; - string cmd = installDir + "/bin/columnstore restart > /dev/null 2>&1"; - int rtnCode = system(cmd.c_str()); - if (WEXITSTATUS(rtnCode) != 0) { - cout << "Error Starting MariaDB ColumnStore local module" << endl; - cout << "Installation Failed, exiting" << endl; - exit (1); - } - else - cout << endl << "MariaDB ColumnStore successfully started" << endl; - } - else - { - cout << endl << "You choose not to Start the MariaDB ColumnStore Software at this time." << endl; + cout << "System Configuration is complete." << endl; + cout << "Performing System Installation." << endl; + + //start MariaDB ColumnStore on local server + cout << endl << "----- Starting MariaDB ColumnStore on local Server '" + parentOAMModuleName + "' -----" << endl << endl; + string cmd = installDir + "/bin/columnstore restart > /dev/null 2>&1"; + int rtnCode = system(cmd.c_str()); + if (WEXITSTATUS(rtnCode) != 0) { + cout << "Error Starting MariaDB ColumnStore local module" << endl; + cout << "Installation Failed, exiting" << endl; exit (1); } + else + cout << endl << "MariaDB ColumnStore successfully started" << endl; } cout << endl << "MariaDB ColumnStore Database Platform Starting, please wait ."; @@ -3439,23 +3231,14 @@ int main(int argc, char *argv[]) { if ( oam.checkLogStatus("/tmp/dbbuilder.log", "System catalog appears to exist") ) { -// cout << endl << "Run MySQL Upgrade.. "; cout.flush(); - - //send message to procmon's to run upgrade script -// int status = sendUpgradeRequest(IserverTypeInstall, pmwithum); - -// if ( status != 0 ) { -// cout << endl << "MariaDB ColumnStore Install Failed" << endl << endl; -// exit(1); -// } -// else -// cout << " DONE" << endl; } else { cout << endl << "System Catalog Create Failure" << endl; cout << "Check latest log file in /tmp/dbbuilder.log.*" << endl; + cout << " IMPORTANT: Once issue has been resolved, rerun postConfigure" << endl << endl; + exit (1); } } @@ -3473,7 +3256,8 @@ int main(int argc, char *argv[]) int status = sendReplicationRequest(IserverTypeInstall, password, pmwithum); if ( status != 0 ) { - cout << endl << " MariaDB ColumnStore Install Failed" << endl << endl; + cout << endl << " MariaDB ColumnStore Replication Setup Failed, check logs" << endl << endl; + cout << " IMPORTANT: Once issue has been resolved, rerun postConfigure" << endl << endl; exit(1); } else @@ -3493,7 +3277,10 @@ int main(int argc, char *argv[]) } else { - cout << " FAILED" << endl; + cout << " FAILED" << endl << endl; + + cout << " IMPORTANT: There was a system startup failed, once issue has been resolved, rerun postConfigure" << endl << endl; + cout << endl << "MariaDB ColumnStore System failed to start, check log files in /var/log/mariadb/columnstore" << endl; cout << "Enter the following command to define MariaDB ColumnStore Alias Commands" << endl << endl; diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 5fee029e1..5624f3971 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -7081,14 +7081,6 @@ void startSystemThread(oam::DeviceNetworkList Devicenetworklist) } processManager.setSystemState(rtn); } - - //run command to build system table if they don't already exist - sleep(5); - int ret = processManager.buildSystemTables("pm1"); - if (ret == oam::API_SUCCESS ) - log.writeLog(__LINE__, "System Catalog Successfully Built", LOG_TYPE_DEBUG); - else - log.writeLog(__LINE__, "System Catalog not built, already existed", LOG_TYPE_DEBUG); // exit thread log.writeLog(__LINE__, "startSystemThread Exit", LOG_TYPE_DEBUG); From fda44955ea05e33f8bb6666df25b02926a17d6f8 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 10 Nov 2017 14:13:27 -0600 Subject: [PATCH 175/185] MCOL-1020 - added checks to prevent crash --- oamapps/postConfigure/postConfigure.cpp | 103 +++++++++++++----------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index bbf6cc32e..70937a8f6 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -479,61 +479,68 @@ int main(int argc, char *argv[]) char *addr; bool found = false; - getifaddrs (&ifap); - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family==AF_INET) { - sa = (struct sockaddr_in *) ifa->ifa_addr; - addr = inet_ntoa(sa->sin_addr); - //printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); - - if ( PM1ipAdd == addr ) - { - //match - found = true; - } - } - - if (found) - break; - } - - freeifaddrs(ifap); - - if (!found) + if (getifaddrs (&ifap) == 0 ) { - - string answer = "y"; + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL ) { + found = true; + break; + } + + if (ifa->ifa_addr->sa_family==AF_INET) { + sa = (struct sockaddr_in *) ifa->ifa_addr; + addr = inet_ntoa(sa->sin_addr); + //printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); + + if ( PM1ipAdd == addr ) + { + //match + found = true; + } + } + + if (found) + break; + } + + freeifaddrs(ifap); - while(true) { - cout << endl << "The Configured PM1 IP Address of " << PM1ipAdd << " does not match any of the" << endl; - cout << "Server Ethernet IP addresses there were detected, do you want to continue?" << endl; - cout << "This is to make sure that you arent running postConfigure from a non-PM1 node." << endl; - prompt = "Enter 'y' to continue using Configured IP address [y,n] (y) > "; + if (!found) + { + + string answer = "y"; - pcommand = callReadline(prompt.c_str()); - if (pcommand) { - if (strlen(pcommand) > 0) answer = pcommand; - callFree(pcommand); + while(true) { + cout << endl << "The Configured PM1 IP Address of " << PM1ipAdd << " does not match any of the" << endl; + cout << "Server Ethernet IP addresses there were detected, do you want to continue?" << endl; + cout << "This is to make sure that you arent running postConfigure from a non-PM1 node." << endl; + prompt = "Enter 'y' to continue using Configured IP address [y,n] (y) > "; + + pcommand = callReadline(prompt.c_str()); + if (pcommand) { + if (strlen(pcommand) > 0) answer = pcommand; + callFree(pcommand); + } + + if ( answer == "y" || answer == "n" ) { + cout << endl; + break; + } + else + cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; + + if ( noPrompting ) + exit(1); } - if ( answer == "y" || answer == "n" ) { + if ( answer == "n" ) { cout << endl; - break; + cout << "ERROR: postConfigure install can only be done on the PM1" << endl; + cout << "designated node. The configured PM1 IP address doesn't match the local" << endl; + cout << "IP Address. exiting..." << endl; + exit(1); } - else - cout << "Invalid Entry, please enter 'y' for yes or 'n' for no" << endl; - - if ( noPrompting ) - exit(1); - } - - if ( answer == "n" ) { - cout << endl; - cout << "ERROR: postConfigure install can only be done on the PM1" << endl; - cout << "designated node. The configured PM1 IP address doesn't match the local" << endl; - cout << "IP Address. exiting..." << endl; - exit(1); - } + } } } } From 854d32560ad8a7809f2b73e9fa7c971781881347 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sat, 11 Nov 2017 09:31:09 +0000 Subject: [PATCH 176/185] MCOL-1008 Fix bad length on bulk DML insert If a VARCHAR was defined as less than 255 characters and a data via LDI or INSERT...SELECT was > 127 characters the length field would contain a negative number. In 1.0.11 and 1.1.0 this was not a problem because we cast the negative back again. With MCOL-877 we stoped doing the double-cast. This patch casts properly the first time. --- dbcon/mysql/ha_calpont_dml.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 30eba5833..9583d9f9e 100755 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -893,12 +893,12 @@ int ha_calpont_impl_write_batch_row_(uchar *buf, TABLE* table, cal_impl_if::cal_ { if (ci.columnTypes[colpos].colWidth < 256) { - dataLength = *(int8_t*) buf; + dataLength = *(uint8_t*) buf; buf++; } else { - dataLength = *(int16_t*) buf; + dataLength = *(uint16_t*) buf; buf = buf + 2 ; } escape.assign((char*)buf, dataLength); @@ -909,7 +909,7 @@ int ha_calpont_impl_write_batch_row_(uchar *buf, TABLE* table, cal_impl_if::cal_ { if (ci.columnTypes[colpos].colWidth < 86) { - dataLength = *(int8_t*) buf; + dataLength = *(uint8_t*) buf; buf++; } else From e345d20f97314fa70e97c6708349bef3d2eae654 Mon Sep 17 00:00:00 2001 From: Ben Thompson Date: Mon, 13 Nov 2017 16:25:11 -0600 Subject: [PATCH 177/185] MCOL-976: Change to how restartProcessType restarts DDLProc and DMLProc. --- procmgr/processmanager.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index c3cd330a9..7c147f9e4 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -3447,11 +3447,15 @@ void ProcessManager::recycleProcess(string module) restartProcessType("PrimProc"); sleep(1); restartProcessType("ExeMgr"); + sleep(1); restartProcessType("mysql"); } else + { + restartProcessType("DBRMControllerNode", module); + restartProcessType("DBRMWorkerNode"); restartProcessType("ExeMgr"); - + } if ( PrimaryUMModuleName == module ) { restartProcessType("DDLProc", module); @@ -4254,6 +4258,7 @@ int ProcessManager::restartProcessType( std::string processName, std::string ski SystemProcessStatus systemprocessstatus; ProcessStatus processstatus; int retStatus = API_SUCCESS; + bool setPMProcIPs = true; log.writeLog(__LINE__, "restartProcessType: Restart all " + processName, LOG_TYPE_DEBUG); @@ -4301,8 +4306,8 @@ int ProcessManager::restartProcessType( std::string processName, std::string ski ( systemprocessstatus.processstatus[i].ProcessOpState == oam::COLD_STANDBY && !manualFlag ) ) continue; - if( processName.find("DDLProc") == 0 || - processName.find("DMLProc") == 0 ) { + if ( (processName.find("DDLProc") == 0 || processName.find("DMLProc") == 0) && setPMProcIPs ) + { string procModuleType = systemprocessstatus.processstatus[i].Module.substr(0,MAX_MODULE_TYPE_SIZE); if ( procModuleType == "pm" && PMwithUM == "y" ) continue; @@ -4329,11 +4334,11 @@ int ProcessManager::restartProcessType( std::string processName, std::string ski // if DDL or DMLProc, change IP Address if ( retStatus == oam::API_SUCCESS ) { - if( processName.find("DDLProc") == 0 || - processName.find("DMLProc") == 0 ) { - + if ( (processName.find("DDLProc") == 0 || processName.find("DMLProc") == 0) && setPMProcIPs ) + { processManager.setPMProcIPs(systemprocessstatus.processstatus[i].Module, processName); - return retStatus; + setPMProcIPs = false; + continue; } } } @@ -8188,7 +8193,7 @@ int ProcessManager::setPMProcIPs( std::string moduleName, std::string processNam pthread_mutex_unlock(&THREAD_LOCK); - log.writeLog(__LINE__, "setPMProcIPs failed", LOG_TYPE_DEBUG); + //log.writeLog(__LINE__, "setPMProcIPs failed", LOG_TYPE_DEBUG); return API_SUCCESS; From f5a2306bb297358c2a68e6257acb7f8e6ce54db3 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 14 Nov 2017 11:21:50 -0600 Subject: [PATCH 178/185] increase procup timeout from 6 to 12, neede for amazon --- oam/etc/Columnstore.xml | 2 +- procmgr/main.cpp | 4 ++-- procmgr/processmanager.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/oam/etc/Columnstore.xml b/oam/etc/Columnstore.xml index 14098fb28..c3aa79c42 100644 --- a/oam/etc/Columnstore.xml +++ b/oam/etc/Columnstore.xml @@ -231,7 +231,7 @@ unassigned 1 3 - 6 // 2.5 minutes + 12 // 2.5 minutes diff --git a/procmgr/main.cpp b/procmgr/main.cpp index caecbf777..b054d3e40 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -1504,12 +1504,12 @@ void pingDeviceThread() //restart module processes int retry = 0; - int ModuleProcMonWaitCount = 6; + int ModuleProcMonWaitCount = 12; try{ oam.getSystemConfig("ModuleProcMonWaitCount", ModuleProcMonWaitCount); } catch(...) { - ModuleProcMonWaitCount = 6; + ModuleProcMonWaitCount = 12; } for ( ; retry < ModuleProcMonWaitCount ; retry ++ ) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index cb39092d9..10b68ea06 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -9180,7 +9180,7 @@ int ProcessManager::OAMParentModuleChange() if (amazon && AmazonPMFailover == "n") { log.writeLog(__LINE__, " ", LOG_TYPE_DEBUG); - log.writeLog(__LINE__, "*** OAMParentModule outage, AmazonPMFailover not set, wating for instance to restart ***", LOG_TYPE_DEBUG); + log.writeLog(__LINE__, "*** OAMParentModule outage, AmazonPMFailover not set, waiting for instance to restart ***", LOG_TYPE_DEBUG); string currentIPAddr = oam.getEC2InstanceIpAddress(downOAMParentHostname); if (currentIPAddr == "stopped") From 9a012444ec46cdbebc35b92b01dc27f0c15030b0 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 14 Nov 2017 15:25:38 -0600 Subject: [PATCH 179/185] MCOL-963 fix for regressions introduced --- dbcon/mysql/ha_calpont_execplan.cpp | 1 - dbcon/mysql/ha_calpont_impl.cpp | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index a0d8ed8b1..4eaa8aab5 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -6488,7 +6488,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i // re-construct the select query and redo phase 1 if (redo) { - ++gwi.thd->infinidb_vtable.redo_count; // select now() from region case. returnedCols should have minSc. if (sel_cols_in_create.length() == 0) { diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 5ff9002ad..781047106 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -2838,10 +2838,7 @@ int ha_calpont_impl_rnd_init(TABLE* table) // set query state to be in_process. Sometimes mysql calls rnd_init multiple // times, this makes sure plan only being generated and sent once. It will be // reset when query finishes in sm::end_query - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE) - { - thd->infinidb_vtable.isNewQuery = false; - } + thd->infinidb_vtable.isNewQuery = false; // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; @@ -3077,8 +3074,8 @@ int ha_calpont_impl_rnd_end(TABLE* table) thd->infinidb_vtable.vtable_state = THD::INFINIDB_SELECT_VTABLE; // flip back to normal state return rc; } - if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) - return rc; +// if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) +// return rc; if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) return rc; @@ -3095,7 +3092,7 @@ int ha_calpont_impl_rnd_end(TABLE* table) // @bug 4022. error handling for select part of dml if (ci->cal_conn_hndl && ci->rc) { - // send ExeMgr a signal before cloing the connection + // send ExeMgr a signal before closing the connection ByteStream msg; ByteStream::quadbyte qb = 0; msg << qb; From a5038cd79ba6b99ddd10f6bf392c65e330f0db8c Mon Sep 17 00:00:00 2001 From: david hill Date: Thu, 16 Nov 2017 08:48:01 -0600 Subject: [PATCH 180/185] fix added in um module for mysqlrep --- procmon/processmonitor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/procmon/processmonitor.cpp b/procmon/processmonitor.cpp index 1a1092e61..90679ee28 100644 --- a/procmon/processmonitor.cpp +++ b/procmon/processmonitor.cpp @@ -5267,8 +5267,9 @@ int ProcessMonitor::runMasterDist(std::string& password, std::string& slaveModul string moduleType = slaveModule.substr(0,MAX_MODULE_TYPE_SIZE); - if ( ( (PMwithUM == "y") && (moduleType == "pm") ) && - ( config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM) ) + if ( (moduleType == "um") || + ( (PMwithUM == "y") && (moduleType == "pm") ) || + ( config.ServerInstallType() == oam::INSTALL_COMBINE_DM_UM_PM) ) { slave++; From d5119173e7be2847de86573bfff26fc47a2c9e56 Mon Sep 17 00:00:00 2001 From: david hill Date: Fri, 17 Nov 2017 14:32:58 -0600 Subject: [PATCH 181/185] increase the addmodule timeout to 60secs, needed for amazon --- procmgr/processmanager.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/procmgr/processmanager.cpp b/procmgr/processmanager.cpp index 10b68ea06..403bbbdda 100755 --- a/procmgr/processmanager.cpp +++ b/procmgr/processmanager.cpp @@ -4172,7 +4172,11 @@ int ProcessManager::stopProcessType( std::string processName, bool manualFlag ) for( unsigned int i = 0 ; i < systemprocessstatus.processstatus.size(); i++) { if ( systemprocessstatus.processstatus[i].ProcessName == processName) { - // found one, request restart of it + //skip if in a COLD_STANDBY state + if ( systemprocessstatus.processstatus[i].ProcessOpState == oam::COLD_STANDBY ) + continue; + + // found one, request restart of it processManager.stopProcess(systemprocessstatus.processstatus[i].Module, processName, GRACEFUL, @@ -5454,8 +5458,8 @@ int ProcessManager::addModule(oam::DeviceNetworkList devicenetworklist, std::str } //delay to give time for ProcMon to start after the config is sent and procmon restarts - log.writeLog(__LINE__, "addModule - sleep 30 - give ProcMon time to CONFIGURE and restart", LOG_TYPE_DEBUG); - sleep(30); + log.writeLog(__LINE__, "addModule - sleep 60 - give ProcMon time to CONFIGURE and restart", LOG_TYPE_DEBUG); + sleep(60); log.writeLog(__LINE__, "Setup MySQL Replication for new Modules being Added", LOG_TYPE_DEBUG); processManager.setMySQLReplication(devicenetworklist, oam::UnassignedName, false, true, password ); From 98138fe493756ee406a37d24ed8a1d84fd6b06e1 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Mon, 20 Nov 2017 16:04:20 +0000 Subject: [PATCH 182/185] MCOL-1029 Skip cached conditions Cached conditions are things like (TRUE OR FALSE). They don't actually add any value to the query and were breaking our working stack trying to process them. --- dbcon/mysql/ha_calpont_execplan.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 4eaa8aab5..0fb1a1326 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -4317,6 +4317,14 @@ void gp_walk(const Item *item, void *arg) bool isOr = (ftype == Item_func::COND_OR_FUNC); bool isXor = (ftype == Item_func::XOR_FUNC); + // MCOL-1029 A cached COND_ITEM is something like: + // AND (TRUE OR FALSE) + // We can skip it + if (isCached) + { + break; + } + List *argumentList; List xorArgumentList; if (isXor) @@ -4369,7 +4377,7 @@ void gp_walk(const Item *item, void *arg) } } } - + // @bug1603. MySQL's filter tree is a multi-tree grouped by operator. So more than // two filters saved on the stack so far might belong to this operator. uint32_t leftInStack = gwip->ptWorkStack.size() - argumentList->elements + 1; From 2a3bd029d0a0c285cc47f074857b28224b5905ac Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 21 Nov 2017 15:17:40 -0600 Subject: [PATCH 183/185] fix a system complete/install comment --- oamapps/postConfigure/postConfigure.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/oamapps/postConfigure/postConfigure.cpp b/oamapps/postConfigure/postConfigure.cpp index 70937a8f6..de321eff8 100644 --- a/oamapps/postConfigure/postConfigure.cpp +++ b/oamapps/postConfigure/postConfigure.cpp @@ -612,6 +612,13 @@ int main(int argc, char *argv[]) nonDistribute = true; } + // setup to start on reboot, for non-root amazon installs + if ( !rootUser ) + { + system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); + system("sudo chmod 666 /etc/fstab >/dev/null 2>&1"); + } + cout << endl; cout << "===== Setup System Server Type Configuration =====" << endl << endl; @@ -1067,13 +1074,6 @@ int main(int argc, char *argv[]) } } - // setup to start on reboot, for non-root amazon installs - if ( !rootUser ) - { - system("sudo sed -i -e 's/#sudo runuser/sudo runuser/g' /etc/rc.d/rc.local >/dev/null 2>&1"); - system("sudo chmod 666 /etc/fstab >/dev/null 2>&1"); - } - if ( !writeConfig(sysConfig) ) { cout << "ERROR: Failed trying to update MariaDB ColumnStore System Configuration file" << endl; exit(1); @@ -3146,8 +3146,8 @@ int main(int argc, char *argv[]) // cout << endl << "===== MariaDB ColumnStore System Startup =====" << endl << endl; - cout << "System Configuration is complete." << endl; - cout << "Performing System Installation." << endl; + cout << "System Installation is complete." << endl; + cout << "Performing System Start-up." << endl; if (hdfs && !nonDistribute ) { @@ -3178,8 +3178,8 @@ int main(int argc, char *argv[]) { cout << endl << "===== MariaDB ColumnStore System Startup =====" << endl << endl; - cout << "System Configuration is complete." << endl; - cout << "Performing System Installation." << endl; + cout << "System Installation is complete." << endl; + cout << "Performing System Start-up." << endl; //start MariaDB ColumnStore on local server cout << endl << "----- Starting MariaDB ColumnStore on local Server '" + parentOAMModuleName + "' -----" << endl << endl; From 8f018f81d72b047529d61e042c777e50304db2d4 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 21 Nov 2017 15:18:23 -0600 Subject: [PATCH 184/185] increased wait for procmon to go active to 3 minutes, neede for amazon --- procmgr/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/procmgr/main.cpp b/procmgr/main.cpp index b054d3e40..b6f51a609 100644 --- a/procmgr/main.cpp +++ b/procmgr/main.cpp @@ -502,7 +502,7 @@ static void startMgrProcessThread() ModuleTypeConfig PMSmoduletypeconfig; ALARMManager aManager; - int waitTime = 120; + int waitTime = 180; log.writeLog(__LINE__, "startMgrProcessThread launched", LOG_TYPE_DEBUG); From 573d465a75014b23ac19ff5e4234776971850b69 Mon Sep 17 00:00:00 2001 From: david hill Date: Tue, 21 Nov 2017 15:23:55 -0600 Subject: [PATCH 185/185] bump version number --- README | 6 +++--- README.md | 8 +++----- VERSION | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README b/README index 8e42cd701..3517d0580 100644 --- a/README +++ b/README @@ -1,9 +1,9 @@ -This is MariaDB ColumnStore 1.1.2 GA -MariaDB ColumnStore 1.1.2 GA is the development version of MariaDB ColumnStore. +This is MariaDB ColumnStore 1.1.3 GA +MariaDB ColumnStore 1.1.3 GA is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.2 and adding entirely new features not found anywhere else. -MariaDB ColumnStore 1.1.2 is a GA release. This is the first MariaDB +MariaDB ColumnStore 1.1.3 is a GA release. This is the first MariaDB ColumnStore release, not all features planned for the MariaDB ColumnStore 1.0 series are included in this release. diff --git a/README.md b/README.md index 5ed765d0f..cf83245c7 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -#MariaDB ColumnStore Storage/Execution engine 1.1.2 GA -MariaDB ColumnStore 1.1.2 GA is the development version of MariaDB ColumnStore. +#MariaDB ColumnStore Storage/Execution engine 1.1.3 GA +MariaDB ColumnStore 1.1.3 GA is the development version of MariaDB ColumnStore. It is built by porting InfiniDB 4.6.7 on MariaDB 10.2.9 and adding entirely new features not found anywhere else. -#MariaDB ColumnStore 1.1.2 is an GA release. - -- Do not use Beta releases on production systems. +#MariaDB ColumnStore 1.1.3 is an GA release. #Building This repository is not meant to be built independently outside of the server. This repository is integrated into http://mariadb-corporation/mariadb-columnstore-server (ie, the *server*) as a git submodule. As such, you can find complete build instructions on *the server* page. diff --git a/VERSION b/VERSION index 7eb0690ea..f370899f3 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ COLUMNSTORE_VERSION_MAJOR=1 COLUMNSTORE_VERSION_MINOR=1 -COLUMNSTORE_VERSION_PATCH=2 +COLUMNSTORE_VERSION_PATCH=3 COLUMNSTORE_VERSION_RELEASE=1