summaryrefslogtreecommitdiff
path: root/server-tools
diff options
context:
space:
mode:
Diffstat (limited to 'server-tools')
-rw-r--r--server-tools/CMakeLists.txt33
-rw-r--r--server-tools/Makefile.am20
-rwxr-xr-xserver-tools/instance-manager/CMakeLists.txt38
-rw-r--r--server-tools/instance-manager/IMService.cpp124
-rw-r--r--server-tools/instance-manager/IMService.h32
-rw-r--r--server-tools/instance-manager/Makefile.am103
-rw-r--r--server-tools/instance-manager/README11
-rw-r--r--server-tools/instance-manager/WindowsService.cpp231
-rw-r--r--server-tools/instance-manager/WindowsService.h56
-rw-r--r--server-tools/instance-manager/angel.cc407
-rw-r--r--server-tools/instance-manager/angel.h34
-rw-r--r--server-tools/instance-manager/buffer.cc110
-rw-r--r--server-tools/instance-manager/buffer.h65
-rw-r--r--server-tools/instance-manager/command.cc30
-rw-r--r--server-tools/instance-manager/command.h60
-rw-r--r--server-tools/instance-manager/commands.cc1752
-rw-r--r--server-tools/instance-manager/commands.h393
-rw-r--r--server-tools/instance-manager/exit_codes.h40
-rw-r--r--server-tools/instance-manager/guardian.cc496
-rw-r--r--server-tools/instance-manager/guardian.h110
-rw-r--r--server-tools/instance-manager/instance.cc944
-rw-r--r--server-tools/instance-manager/instance.h273
-rw-r--r--server-tools/instance-manager/instance_map.cc649
-rw-r--r--server-tools/instance-manager/instance_map.h102
-rw-r--r--server-tools/instance-manager/instance_options.cc753
-rw-r--r--server-tools/instance-manager/instance_options.h126
-rw-r--r--server-tools/instance-manager/listener.cc337
-rw-r--r--server-tools/instance-manager/listener.h61
-rw-r--r--server-tools/instance-manager/log.cc196
-rw-r--r--server-tools/instance-manager/log.h59
-rw-r--r--server-tools/instance-manager/manager.cc526
-rw-r--r--server-tools/instance-manager/manager.h71
-rw-r--r--server-tools/instance-manager/messages.cc104
-rw-r--r--server-tools/instance-manager/messages.h23
-rw-r--r--server-tools/instance-manager/mysql_connection.cc376
-rw-r--r--server-tools/instance-manager/mysql_connection.h74
-rw-r--r--server-tools/instance-manager/mysql_manager_error.h40
-rw-r--r--server-tools/instance-manager/mysqlmanager.cc232
-rw-r--r--server-tools/instance-manager/options.cc558
-rw-r--r--server-tools/instance-manager/options.h108
-rw-r--r--server-tools/instance-manager/parse.cc509
-rw-r--r--server-tools/instance-manager/parse.h212
-rw-r--r--server-tools/instance-manager/parse_output.cc407
-rw-r--r--server-tools/instance-manager/parse_output.h33
-rw-r--r--server-tools/instance-manager/portability.h65
-rw-r--r--server-tools/instance-manager/priv.cc76
-rw-r--r--server-tools/instance-manager/priv.h99
-rw-r--r--server-tools/instance-manager/protocol.cc217
-rw-r--r--server-tools/instance-manager/protocol.h47
-rw-r--r--server-tools/instance-manager/thread_registry.cc419
-rw-r--r--server-tools/instance-manager/thread_registry.h176
-rw-r--r--server-tools/instance-manager/user_management_commands.cc421
-rw-r--r--server-tools/instance-manager/user_management_commands.h167
-rw-r--r--server-tools/instance-manager/user_map.cc395
-rw-r--r--server-tools/instance-manager/user_map.h103
55 files changed, 0 insertions, 13103 deletions
diff --git a/server-tools/CMakeLists.txt b/server-tools/CMakeLists.txt
deleted file mode 100644
index 3f02ba88f1d..00000000000
--- a/server-tools/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2006 MySQL AB
-#
-# 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 St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
-INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
- ${PROJECT_SOURCE_DIR}/extra/yassl/include)
-
-ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
- instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
- mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
- thread_registry.cc user_map.cc imservice.cpp windowsservice.cpp
- user_management_commands.cc
- ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
- ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
-
-ADD_DEPENDENCIES(mysqlmanager GenError)
-TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
diff --git a/server-tools/Makefile.am b/server-tools/Makefile.am
deleted file mode 100644
index 96e9d5a946e..00000000000
--- a/server-tools/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003, 2006 MySQL AB
-#
-# 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 St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = . instance-manager
-DIST_SUBDIRS = . instance-manager
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt
deleted file mode 100755
index 2b9bce56ff7..00000000000
--- a/server-tools/instance-manager/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2006 MySQL AB
-#
-# 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 St, Fifth Floor, Boston, MA 02110-1301 USA
-INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
-
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
-INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
- ${PROJECT_SOURCE_DIR}/extra/yassl/include)
-
-ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
- instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
- mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
- thread_registry.cc user_map.cc IMService.cpp WindowsService.cpp
- user_management_commands.cc
- ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
- ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
- ../../libmysql/errmsg.c)
-
-ADD_DEPENDENCIES(mysqlmanager GenError)
-TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32)
-
-IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker")
-ENDIF(EMBED_MANIFESTS)
diff --git a/server-tools/instance-manager/IMService.cpp b/server-tools/instance-manager/IMService.cpp
deleted file mode 100644
index feccaadbecc..00000000000
--- a/server-tools/instance-manager/IMService.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Copyright (C) 2005 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <winsock2.h>
-#include <signal.h>
-
-#include "IMService.h"
-
-#include "log.h"
-#include "manager.h"
-#include "options.h"
-
-static const char * const IM_SVC_USERNAME= NULL;
-static const char * const IM_SVC_PASSWORD= NULL;
-
-IMService::IMService(void)
- :WindowsService("MySqlManager", "MySQL Manager")
-{
-}
-
-IMService::~IMService(void)
-{
-}
-
-void IMService::Stop()
-{
- ReportStatus(SERVICE_STOP_PENDING);
-
- /* stop the IM work */
- raise(SIGTERM);
-}
-
-void IMService::Run(DWORD argc, LPTSTR *argv)
-{
- /* report to the SCM that we're about to start */
- ReportStatus((DWORD)SERVICE_START_PENDING);
-
- Options::load(argc, argv);
-
- /* init goes here */
- ReportStatus((DWORD)SERVICE_RUNNING);
-
- /* wait for main loop to terminate */
- (void) Manager::main();
- Options::cleanup();
-}
-
-void IMService::Log(const char *msg)
-{
- log_info(msg);
-}
-
-int IMService::main()
-{
- IMService winService;
-
- if (Options::Service::install_as_service)
- {
- if (winService.IsInstalled())
- {
- log_info("Service is already installed.");
- return 1;
- }
-
- if (winService.Install(IM_SVC_USERNAME, IM_SVC_PASSWORD))
- {
- log_info("Service installed successfully.");
- return 0;
- }
- else
- {
- log_error("Service failed to install.");
- return 1;
- }
- }
-
- if (Options::Service::remove_service)
- {
- if (!winService.IsInstalled())
- {
- log_info("Service is not installed.");
- return 1;
- }
-
- if (winService.Remove())
- {
- log_info("Service removed successfully.");
- return 0;
- }
- else
- {
- log_error("Service failed to remove.");
- return 1;
- }
- }
-
- log_info("Initializing Instance Manager service...");
-
- if (!winService.Init())
- {
- log_error("Service failed to initialize.");
-
- fprintf(stderr,
- "The service should be started by Windows Service Manager.\n"
- "The MySQL Manager should be started with '--standalone'\n"
- "to run from command line.");
-
- return 1;
- }
-
- return 0;
-}
diff --git a/server-tools/instance-manager/IMService.h b/server-tools/instance-manager/IMService.h
deleted file mode 100644
index aceafb2fca6..00000000000
--- a/server-tools/instance-manager/IMService.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (C) 2005 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#pragma once
-#include "WindowsService.h"
-
-class IMService: public WindowsService
-{
-public:
- static int main();
-
-private:
- IMService(void);
- ~IMService(void);
-
-protected:
- void Log(const char *msg);
- void Stop();
- void Run(DWORD argc, LPTSTR *argv);
-};
diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am
deleted file mode 100644
index 19c4ac8de19..00000000000
--- a/server-tools/instance-manager/Makefile.am
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-#
-# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-INCLUDES= @ZLIB_INCLUDES@ -I$(top_srcdir)/include \
- @openssl_includes@ -I$(top_builddir)/include
-
-DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER
-
-# As all autoconf variables depend from ${prefix} and being resolved only when
-# make is run, we can not put these defines to a header file (e.g. to
-# default_options.h, generated from default_options.h.in)
-# See automake/autoconf docs for details
-
-noinst_LTLIBRARIES= liboptions.la
-noinst_LIBRARIES= libnet.a
-
-liboptions_la_CXXFLAGS= $(CXXFLAGS) \
- -DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
- -DDEFAULT_LOG_FILE_NAME="$(localstatedir)/mysqlmanager.log" \
- -DDEFAULT_SOCKET_FILE_NAME="/tmp/mysqlmanager.sock" \
- -DDEFAULT_PASSWORD_FILE_NAME="/etc/mysqlmanager.passwd" \
- -DDEFAULT_MYSQLD_PATH="$(libexecdir)/mysqld$(EXEEXT)" \
- -DDEFAULT_CONFIG_FILE="my.cnf" \
- -DPROTOCOL_VERSION=@PROTOCOL_VERSION@
-
-liboptions_la_SOURCES= options.h options.cc priv.h priv.cc
-liboptions_la_LIBADD= $(top_builddir)/libmysql/get_password.lo
-
-# MySQL sometimes uses symlinks to reuse code
-# All symlinked files are grouped in libnet.a
-
-nodist_libnet_a_SOURCES= net_serv.cc client_settings.h
-libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \
- $(top_builddir)/sql/pack.$(OBJEXT) \
- $(top_builddir)/sql/sql_state.$(OBJEXT) \
- $(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
- $(top_builddir)/sql/client.$(OBJEXT)
-
-CLEANFILES= net_serv.cc client_settings.h
-
-net_serv.cc:
- rm -f net_serv.cc
- @LN_CP_F@ $(top_srcdir)/sql/net_serv.cc net_serv.cc
-
-client_settings.h:
- rm -f client_settings.h
- @LN_CP_F@ $(top_srcdir)/sql/client_settings.h client_settings.h
-
-libexec_PROGRAMS= mysqlmanager
-
-mysqlmanager_CXXFLAGS=
-
-mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
- manager.h manager.cc log.h log.cc \
- thread_registry.h thread_registry.cc \
- listener.h listener.cc protocol.h protocol.cc \
- mysql_connection.h mysql_connection.cc \
- user_map.h user_map.cc \
- messages.h messages.cc \
- commands.h commands.cc \
- instance.h instance.cc \
- instance_map.h instance_map.cc\
- instance_options.h instance_options.cc \
- buffer.h buffer.cc parse.cc parse.h \
- guardian.cc guardian.h \
- parse_output.cc parse_output.h \
- mysql_manager_error.h \
- portability.h \
- exit_codes.h \
- user_management_commands.h \
- user_management_commands.cc \
- angel.h \
- angel.cc
-
-mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \
- liboptions.la \
- libnet.a \
- $(top_builddir)/vio/libvio.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a \
- $(top_builddir)/dbug/libdbug.a \
- @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
-
-EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
- IMService.h CMakeLists.txt
-
-tags:
- ctags -R *.h *.cc
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/server-tools/instance-manager/README b/server-tools/instance-manager/README
deleted file mode 100644
index ac799775003..00000000000
--- a/server-tools/instance-manager/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Instance Manager - manage MySQL instances locally and remotely.
-
-File description:
- mysqlmanager.cc - entry point to the manager, main,
- options.{h,cc} - handle startup options
- manager.{h,cc} - manager process
- mysql_connection.{h,cc} - handle one connection with mysql client.
-
-See also instance manager architecture description in mysqlmanager.cc.
-
-
diff --git a/server-tools/instance-manager/WindowsService.cpp b/server-tools/instance-manager/WindowsService.cpp
deleted file mode 100644
index 14795e2225a..00000000000
--- a/server-tools/instance-manager/WindowsService.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Copyright (C) 2005 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "my_global.h"
-#include <windows.h>
-#include "WindowsService.h"
-
-static WindowsService *gService;
-
-WindowsService::WindowsService(const char *p_serviceName,
- const char *p_displayName) :
- statusCheckpoint(0),
- serviceName(p_serviceName),
- displayName(p_displayName),
- inited(FALSE),
- dwAcceptedControls(SERVICE_ACCEPT_STOP),
- debugging(FALSE)
-{
- DBUG_ASSERT(serviceName != NULL);
-
- /* TODO: shouldn't we check displayName too (can it really be NULL)? */
-
- /* WindowsService is assumed to be singleton. Let's assure this. */
- DBUG_ASSERT(gService == NULL);
-
- gService= this;
-
- status.dwServiceType= SERVICE_WIN32_OWN_PROCESS;
- status.dwServiceSpecificExitCode= 0;
-}
-
-WindowsService::~WindowsService(void)
-{
-}
-
-BOOL WindowsService::Install(const char *username, const char *password)
-{
- bool ret_val= FALSE;
- SC_HANDLE newService;
- SC_HANDLE scm;
-
- if (IsInstalled())
- return TRUE;
-
- // determine the name of the currently executing file
- char szFilePath[_MAX_PATH];
- GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
-
- // open a connection to the SCM
- if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
- return FALSE;
-
- newService= CreateService(scm, serviceName, displayName,
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
- szFilePath, NULL, NULL, NULL, username,
- password);
-
- if (newService)
- {
- CloseServiceHandle(newService);
- ret_val= TRUE;
- }
-
- CloseServiceHandle(scm);
- return ret_val;
-}
-
-BOOL WindowsService::Init()
-{
- DBUG_ASSERT(serviceName != NULL);
-
- if (inited)
- return TRUE;
-
- SERVICE_TABLE_ENTRY stb[] =
- {
- { (LPSTR)serviceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
- { NULL, NULL }
- };
- inited= TRUE;
- return StartServiceCtrlDispatcher(stb); //register with the Service Manager
-}
-
-BOOL WindowsService::Remove()
-{
- bool ret_val= FALSE;
-
- if (!IsInstalled())
- return TRUE;
-
- // open a connection to the SCM
- SC_HANDLE scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
- if (!scm)
- return FALSE;
-
- SC_HANDLE service= OpenService(scm, serviceName, DELETE);
- if (service)
- {
- if (DeleteService(service))
- ret_val= TRUE;
- DWORD dw= ::GetLastError();
- CloseServiceHandle(service);
- }
-
- CloseServiceHandle(scm);
- return ret_val;
-}
-
-BOOL WindowsService::IsInstalled()
-{
- BOOL ret_val= FALSE;
-
- SC_HANDLE scm= ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- SC_HANDLE serv_handle= ::OpenService(scm, serviceName, SERVICE_QUERY_STATUS);
-
- ret_val= serv_handle != NULL;
-
- ::CloseServiceHandle(serv_handle);
- ::CloseServiceHandle(scm);
-
- return ret_val;
-}
-
-void WindowsService::SetAcceptedControls(DWORD acceptedControls)
-{
- dwAcceptedControls= acceptedControls;
-}
-
-
-BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
- DWORD dwError)
-{
- if (debugging)
- return TRUE;
-
- if(currentState == SERVICE_START_PENDING)
- status.dwControlsAccepted= 0;
- else
- status.dwControlsAccepted= dwAcceptedControls;
-
- status.dwCurrentState= currentState;
- status.dwWin32ExitCode= dwError != 0 ?
- ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
- status.dwWaitHint= waitHint;
- status.dwServiceSpecificExitCode= dwError;
-
- if(currentState == SERVICE_RUNNING || currentState == SERVICE_STOPPED)
- {
- status.dwCheckPoint= 0;
- statusCheckpoint= 0;
- }
- else
- status.dwCheckPoint= ++statusCheckpoint;
-
- // Report the status of the service to the service control manager.
- BOOL result= SetServiceStatus(statusHandle, &status);
- if (!result)
- Log("ReportStatus failed");
-
- return result;
-}
-
-void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv)
-{
- statusHandle= ::RegisterServiceCtrlHandler(serviceName, ControlHandler);
- if (statusHandle && ReportStatus(SERVICE_START_PENDING))
- Run(argc, argv);
- ReportStatus(SERVICE_STOPPED);
-}
-
-void WindowsService::HandleControlCode(DWORD opcode)
-{
- // Handle the requested control code.
- switch(opcode) {
- case SERVICE_CONTROL_STOP:
- // Stop the service.
- status.dwCurrentState= SERVICE_STOP_PENDING;
- Stop();
- break;
-
- case SERVICE_CONTROL_PAUSE:
- status.dwCurrentState= SERVICE_PAUSE_PENDING;
- Pause();
- break;
-
- case SERVICE_CONTROL_CONTINUE:
- status.dwCurrentState= SERVICE_CONTINUE_PENDING;
- Continue();
- break;
-
- case SERVICE_CONTROL_SHUTDOWN:
- Shutdown();
- break;
-
- case SERVICE_CONTROL_INTERROGATE:
- ReportStatus(status.dwCurrentState);
- break;
-
- default:
- // invalid control code
- break;
- }
-}
-
-void WINAPI WindowsService::ServiceMain(DWORD argc, LPTSTR *argv)
-{
- DBUG_ASSERT(gService != NULL);
-
- // register our service control handler:
- gService->RegisterAndRun(argc, argv);
-}
-
-void WINAPI WindowsService::ControlHandler(DWORD opcode)
-{
- DBUG_ASSERT(gService != NULL);
-
- return gService->HandleControlCode(opcode);
-}
diff --git a/server-tools/instance-manager/WindowsService.h b/server-tools/instance-manager/WindowsService.h
deleted file mode 100644
index 02a499e5f0c..00000000000
--- a/server-tools/instance-manager/WindowsService.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (C) 2005 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#pragma once
-
-class WindowsService
-{
-protected:
- bool inited;
- const char *serviceName;
- const char *displayName;
- SERVICE_STATUS_HANDLE statusHandle;
- DWORD statusCheckpoint;
- SERVICE_STATUS status;
- DWORD dwAcceptedControls;
- bool debugging;
-
-public:
- WindowsService(const char *p_serviceName, const char *p_displayName);
- ~WindowsService(void);
-
- BOOL Install(const char *username, const char *password);
- BOOL Remove();
- BOOL Init();
- BOOL IsInstalled();
- void SetAcceptedControls(DWORD acceptedControls);
- void Debug(bool debugFlag) { debugging= debugFlag; }
-
-public:
- static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
- static void WINAPI ControlHandler(DWORD CtrlType);
-
-protected:
- virtual void Run(DWORD argc, LPTSTR *argv)= 0;
- virtual void Stop() {}
- virtual void Shutdown() {}
- virtual void Pause() {}
- virtual void Continue() {}
- virtual void Log(const char *msg) {}
-
- BOOL ReportStatus(DWORD currentStatus, DWORD waitHint= 3000, DWORD dwError=0);
- void HandleControlCode(DWORD opcode);
- void RegisterAndRun(DWORD argc, LPTSTR *argv);
-};
diff --git a/server-tools/instance-manager/angel.cc b/server-tools/instance-manager/angel.cc
deleted file mode 100644
index 64515c8498c..00000000000
--- a/server-tools/instance-manager/angel.cc
+++ /dev/null
@@ -1,407 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef __WIN__
-
-#include "angel.h"
-
-#include <sys/wait.h>
-/*
- sys/wait.h is needed for waitpid(). Unfortunately, there is no MySQL
- include file, that can serve for this. Include it before MySQL system
- headers so that we can change system defines if needed.
-*/
-
-#include "my_global.h"
-#include "my_alarm.h"
-#include "my_dir.h"
-#include "my_sys.h"
-
-/* Include other IM files. */
-
-#include "log.h"
-#include "manager.h"
-#include "options.h"
-#include "priv.h"
-
-/************************************************************************/
-
-enum { CHILD_OK= 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL };
-
-static int log_fd;
-
-static volatile sig_atomic_t child_status= CHILD_OK;
-static volatile sig_atomic_t child_exit_code= 0;
-static volatile sig_atomic_t shutdown_request_signo= 0;
-
-
-/************************************************************************/
-/**
- Open log file.
-
- @return
- TRUE on error;
- FALSE on success.
-*************************************************************************/
-
-static bool open_log_file()
-{
- log_info("Angel: opening log file '%s'...",
- (const char *) Options::Daemon::log_file_name);
-
- log_fd= open(Options::Daemon::log_file_name,
- O_WRONLY | O_CREAT | O_APPEND | O_NOCTTY,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-
- if (log_fd < 0)
- {
- log_error("Can not open log file '%s': %s.",
- (const char *) Options::Daemon::log_file_name,
- (const char *) strerror(errno));
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/************************************************************************/
-/**
- Detach the process from controlling tty.
-
- @return
- TRUE on error;
- FALSE on success.
-*************************************************************************/
-
-static bool detach_process()
-{
- /*
- Become a session leader (the goal is not to have a controlling tty).
-
- setsid() must succeed because child is guaranteed not to be a process
- group leader (it belongs to the process group of the parent).
-
- NOTE: if we now don't have a controlling tty we will not receive
- tty-related signals - no need to ignore them.
- */
-
- if (setsid() < 0)
- {
- log_error("setsid() failed: %s.", (const char *) strerror(errno));
- return -1;
- }
-
- /* Close STDIN. */
-
- log_info("Angel: preparing standard streams.");
-
- if (close(STDIN_FILENO) < 0)
- {
- log_error("Warning: can not close stdin (%s)."
- "Trying to continue...",
- (const char *) strerror(errno));
- }
-
- /* Dup STDOUT and STDERR to the log file. */
-
- if (dup2(log_fd, STDOUT_FILENO) < 0 ||
- dup2(log_fd, STDERR_FILENO) < 0)
- {
- log_error("Can not redirect stdout and stderr to the log file: %s.",
- (const char *) strerror(errno));
-
- return TRUE;
- }
-
- if (log_fd != STDOUT_FILENO && log_fd != STDERR_FILENO)
- {
- if (close(log_fd) < 0)
- {
- log_error("Can not close original log file handler (%d): %s. "
- "Trying to continue...",
- (int) log_fd,
- (const char *) strerror(errno));
- }
- }
-
- return FALSE;
-}
-
-
-/************************************************************************/
-/**
- Create PID file.
-
- @return
- TRUE on error;
- FALSE on success.
-*************************************************************************/
-
-static bool create_pid_file()
-{
- if (create_pid_file(Options::Daemon::angel_pid_file_name, getpid()))
- {
- log_error("Angel: can not create pid file (%s).",
- (const char *) Options::Daemon::angel_pid_file_name);
-
- return TRUE;
- }
-
- log_info("Angel: pid file (%s) created.",
- (const char *) Options::Daemon::angel_pid_file_name);
-
- return FALSE;
-}
-
-
-/************************************************************************/
-/**
- SIGCHLD handler.
-
- Reap child, analyze child exit code, and set child_status
- appropriately.
-*************************************************************************/
-
-extern "C" void reap_child(int);
-
-void reap_child(int __attribute__((unused)) signo)
-{
- /* NOTE: As we have only one child, no need to cycle waitpid(). */
-
- int exit_code;
-
- if (waitpid(0, &exit_code, WNOHANG) > 0)
- {
- child_exit_code= exit_code;
- child_status= exit_code ? CHILD_NEED_RESPAWN : CHILD_EXIT_ANGEL;
- }
-}
-
-
-/************************************************************************/
-/**
- SIGTERM, SIGHUP, SIGINT handler.
-
- Set termination status and return.
-*************************************************************************/
-
-extern "C" void terminate(int signo);
-void terminate(int signo)
-{
- shutdown_request_signo= signo;
-}
-
-
-/************************************************************************/
-/**
- Angel main loop.
-
- @return
- The function returns exit status for global main():
- 0 -- program completed successfully;
- !0 -- error occurred.
-*************************************************************************/
-
-static int angel_main_loop()
-{
- /*
- Install signal handlers.
-
- NOTE: Although signal handlers are needed only for parent process
- (IM-angel), we should install them before fork() in order to avoid race
- condition (i.e. to be sure, that IM-angel will receive SIGCHLD in any
- case).
- */
-
- sigset_t wait_for_signals_mask;
-
- struct sigaction sa_chld;
- struct sigaction sa_term;
- struct sigaction sa_chld_orig;
- struct sigaction sa_term_orig;
- struct sigaction sa_int_orig;
- struct sigaction sa_hup_orig;
-
- log_info("Angel: setting necessary signal actions...");
-
- sigemptyset(&wait_for_signals_mask);
-
- sigemptyset(&sa_chld.sa_mask);
- sa_chld.sa_handler= reap_child;
- sa_chld.sa_flags= SA_NOCLDSTOP;
-
- sigemptyset(&sa_term.sa_mask);
- sa_term.sa_handler= terminate;
- sa_term.sa_flags= 0;
-
- /* NOTE: sigaction() fails only if arguments are wrong. */
-
- sigaction(SIGCHLD, &sa_chld, &sa_chld_orig);
- sigaction(SIGTERM, &sa_term, &sa_term_orig);
- sigaction(SIGINT, &sa_term, &sa_int_orig);
- sigaction(SIGHUP, &sa_term, &sa_hup_orig);
-
- /* The main Angel loop. */
-
- while (true)
- {
- /* Spawn a new Manager. */
-
- log_info("Angel: forking Manager process...");
-
- switch (fork()) {
- case -1:
- log_error("Angel: can not fork IM-main: %s.",
- (const char *) strerror(errno));
-
- return -1;
-
- case 0:
- /*
- We are in child process, which will be IM-main:
- - Restore default signal actions to let the IM-main work with
- signals as he wishes;
- - Call Manager::main();
- */
-
- log_info("Angel: Manager process created successfully.");
-
- /* NOTE: sigaction() fails only if arguments are wrong. */
-
- sigaction(SIGCHLD, &sa_chld_orig, NULL);
- sigaction(SIGTERM, &sa_term_orig, NULL);
- sigaction(SIGINT, &sa_int_orig, NULL);
- sigaction(SIGHUP, &sa_hup_orig, NULL);
-
- log_info("Angel: executing Manager...");
-
- return Manager::main();
- }
-
- /* Wait for signals. */
-
- log_info("Angel: waiting for signals...");
-
- while (child_status == CHILD_OK && shutdown_request_signo == 0)
- sigsuspend(&wait_for_signals_mask);
-
- /* Exit if one of shutdown signals has been caught. */
-
- if (shutdown_request_signo)
- {
- log_info("Angel: received shutdown signal (%d). Exiting...",
- (int) shutdown_request_signo);
-
- return 0;
- }
-
- /* Manager process died. Respawn it if it was a failure. */
-
- if (child_status == CHILD_NEED_RESPAWN)
- {
- child_status= CHILD_OK;
-
- log_error("Angel: Manager exited abnormally (exit code: %d).",
- (int) child_exit_code);
-
- log_info("Angel: sleeping 1 second...");
-
- sleep(1); /* don't respawn too fast */
-
- log_info("Angel: respawning Manager...");
-
- continue;
- }
-
- /* Delete IM-angel PID file. */
-
- my_delete(Options::Daemon::angel_pid_file_name, MYF(0));
-
- /* IM-angel finished. */
-
- log_info("Angel: Manager exited normally. Exiting...");
-
- return 0;
- }
-}
-
-
-/************************************************************************/
-/**
- Angel main function.
-
- @return
- The function returns exit status for global main():
- 0 -- program completed successfully;
- !0 -- error occurred.
-*************************************************************************/
-
-int Angel::main()
-{
- log_info("Angel: started.");
-
- /* Open log file. */
-
- if (open_log_file())
- return -1;
-
- /* Fork a new process. */
-
- log_info("Angel: daemonizing...");
-
- switch (fork()) {
- case -1:
- /*
- This is the main Instance Manager process, fork() failed.
- Log an error and bail out with error code.
- */
-
- log_error("fork() failed: %s.", (const char *) strerror(errno));
- return -1;
-
- case 0:
- /* We are in child process. Continue Angel::main() execution. */
-
- break;
-
- default:
- /*
- We are in the parent process. Return 0 so that parent exits
- successfully.
- */
-
- log_info("Angel: exiting from the original process...");
-
- return 0;
- }
-
- /* Detach child from controlling tty. */
-
- if (detach_process())
- return -1;
-
- /* Create PID file. */
-
- if (create_pid_file())
- return -1;
-
- /* Start Angel main loop. */
-
- return angel_main_loop();
-}
-
-#endif // __WIN__
diff --git a/server-tools/instance-manager/angel.h b/server-tools/instance-manager/angel.h
deleted file mode 100644
index db21c250972..00000000000
--- a/server-tools/instance-manager/angel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_ANGEL_H
-#define INCLUDES_MYSQL_ANGEL_H
-
-#ifndef __WIN__
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-#include <my_global.h>
-
-class Angel
-{
-public:
- static int main();
-};
-
-#endif // INCLUDES_MYSQL_ANGEL_H
-#endif // __WIN__
diff --git a/server-tools/instance-manager/buffer.cc b/server-tools/instance-manager/buffer.cc
deleted file mode 100644
index f197f42d009..00000000000
--- a/server-tools/instance-manager/buffer.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "buffer.h"
-#include <m_string.h>
-
-const uint Buffer::BUFFER_INITIAL_SIZE= 4096;
-const uint Buffer::MAX_BUFFER_SIZE= 16777216;
-
-/*
- Puts the given string to the buffer.
-
- SYNOPSIS
- append()
- position start position in the buffer
- string string to be put in the buffer
- len_arg the length of the string. This way we can avoid some
- strlens.
-
- DESCRIPTION
-
- The method puts a string into the buffer, starting from position .
- In the case when the buffer is too small it reallocs the buffer. The
- total size of the buffer is restricted with 16.
-
- RETURN
- 0 - ok
- 1 - got an error in reserve()
-*/
-
-int Buffer::append(size_t position, const char *string, size_t len_arg)
-{
- if (reserve(position, len_arg))
- return 1;
-
- strnmov((char*) buffer + position, string, len_arg);
- return 0;
-}
-
-
-/*
- Checks whether the current buffer size is ok to put a string of the length
- "len_arg" starting from "position" and reallocs it if no.
-
- SYNOPSIS
- reserve()
- position the number starting byte on the buffer to store a buffer
- len_arg the length of the string.
-
- DESCRIPTION
-
- The method checks whether it is possible to put a string of the "len_arg"
- length into the buffer, starting from "position" byte. In the case when the
- buffer is too small it reallocs the buffer. The total size of the buffer is
- restricted with 16 Mb.
-
- RETURN
- 0 - ok
- 1 - realloc error or we have come to the 16Mb barrier
-*/
-
-int Buffer::reserve(size_t position, size_t len_arg)
-{
- if (position + len_arg >= MAX_BUFFER_SIZE)
- goto err;
-
- if (position + len_arg >= buffer_size)
- {
- buffer= (uchar*) my_realloc(buffer,
- min(MAX_BUFFER_SIZE,
- max((uint) (buffer_size*1.5),
- position + len_arg)), MYF(0));
- if (!(buffer))
- goto err;
- buffer_size= (size_t) (buffer_size*1.5);
- }
- return 0;
-
-err:
- error= 1;
- return 1;
-}
-
-
-int Buffer::get_size()
-{
- return (uint) buffer_size;
-}
-
-
-int Buffer::is_error()
-{
- return error;
-}
diff --git a/server-tools/instance-manager/buffer.h b/server-tools/instance-manager/buffer.h
deleted file mode 100644
index 3bd7a714437..00000000000
--- a/server-tools/instance-manager/buffer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_sys.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-/*
- This class is a simple implementation of the buffer of varying size.
- It is used to store MySQL client-server protocol packets. This is why
- the maximum buffer size if 16Mb. (See internals manual section
- 7. MySQL Client/Server Protocol)
-*/
-
-class Buffer
-{
-private:
- static const uint BUFFER_INITIAL_SIZE;
- /* maximum buffer size is 16Mb */
- static const uint MAX_BUFFER_SIZE;
- size_t buffer_size;
- /* Error flag. Triggered if we get an error of some kind */
- int error;
-public:
- Buffer(size_t buffer_size_arg= BUFFER_INITIAL_SIZE)
- :buffer_size(buffer_size_arg), error(0)
- {
- /*
- As append() will invokes realloc() anyway, it's ok if malloc returns 0
- */
- if (!(buffer= (uchar*) my_malloc(buffer_size, MYF(0))))
- buffer_size= 0;
- }
-
- ~Buffer()
- {
- my_free(buffer, MYF(0));
- }
-
-public:
- uchar *buffer;
- int get_size();
- int is_error();
- int append(size_t position, const char *string, size_t len_arg);
- int reserve(size_t position, size_t len_arg);
-};
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H */
diff --git a/server-tools/instance-manager/command.cc b/server-tools/instance-manager/command.cc
deleted file mode 100644
index ba84285ead2..00000000000
--- a/server-tools/instance-manager/command.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "manager.h"
-#include "command.h"
-
-Command::Command()
- :guardian(Manager::get_guardian()),
- instance_map(Manager::get_instance_map())
-{}
-
-Command::~Command()
-{}
-
diff --git a/server-tools/instance-manager/command.h b/server-tools/instance-manager/command.h
deleted file mode 100644
index 25d8c9849e8..00000000000
--- a/server-tools/instance-manager/command.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-/* Class responsible for allocation of IM commands. */
-
-class Guardian;
-class Instance_map;
-
-struct st_net;
-
-/*
- Command - entry point for any command.
- GangOf4: 'Command' design pattern
-*/
-
-class Command
-{
-public:
- Command();
- virtual ~Command();
-
- /*
- This operation incapsulates behaviour of the command.
-
- SYNOPSIS
- net The network connection to the client.
- connection_id Client connection ID
-
- RETURN
- 0 On success
- non 0 On error. Client error code is returned.
- */
- virtual int execute(st_net *net, ulong connection_id) = 0;
-
-protected:
- Guardian *guardian;
- Instance_map *instance_map;
-};
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H */
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
deleted file mode 100644
index 56bd720b3e9..00000000000
--- a/server-tools/instance-manager/commands.cc
+++ /dev/null
@@ -1,1752 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "commands.h"
-
-#include <my_global.h>
-#include <m_ctype.h>
-#include <mysql.h>
-#include <my_dir.h>
-
-#include "buffer.h"
-#include "guardian.h"
-#include "instance_map.h"
-#include "log.h"
-#include "manager.h"
-#include "messages.h"
-#include "mysqld_error.h"
-#include "mysql_manager_error.h"
-#include "options.h"
-#include "priv.h"
-#include "protocol.h"
-
-/**************************************************************************
- {{{ Static functions.
-**************************************************************************/
-
-/**
- modify_defaults_to_im_error -- a map of error codes of
- mysys::modify_defaults_file() into Instance Manager error codes.
-*/
-
-static const int modify_defaults_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
- ER_ACCESS_OPTION_FILE };
-
-
-/**
- Parse version number from the version string.
-
- SYNOPSIS
- parse_version_number()
- version_str
- version
- version_size
-
- DESCRIPTION
- TODO
-
- TODO: Move this function to Instance_options and parse version number
- only once.
-
- NOTE: This function is used only in SHOW INSTANCE STATUS statement at the
- moment.
-*/
-
-static int parse_version_number(const char *version_str, char *version,
- uint version_size)
-{
- const char *start= version_str;
- const char *end;
-
- // skip garbage
- while (!my_isdigit(default_charset_info, *start))
- start++;
-
- end= start;
- // skip digits and dots
- while (my_isdigit(default_charset_info, *end) || *end == '.')
- end++;
-
- if ((uint)(end - start) >= version_size)
- return -1;
-
- strncpy(version, start, end-start);
- version[end-start]= '\0';
-
- return 0;
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
-
-/**************************************************************************
- Implementation of Instance_name.
-**************************************************************************/
-
-Instance_name::Instance_name(const LEX_STRING *name)
-{
- str.str= str_buffer;
- str.length= name->length;
-
- if (str.length > MAX_INSTANCE_NAME_SIZE - 1)
- str.length= MAX_INSTANCE_NAME_SIZE - 1;
-
- strmake(str.str, name->str, str.length);
-}
-
-/**************************************************************************
- Implementation of Show_instances.
-**************************************************************************/
-
-/**
- Implementation of SHOW INSTANCES statement.
-
- Possible error codes:
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Show_instances::execute(st_net *net, ulong /* connection_id */)
-{
- int err_code;
-
- if ((err_code= write_header(net)) ||
- (err_code= write_data(net)))
- return err_code;
-
- if (send_eof(net) || net_flush(net))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-int Show_instances::write_header(st_net *net)
-{
- LIST name, state;
- LEX_STRING name_field, state_field;
- LIST *field_list;
-
- name_field.str= (char *) "instance_name";
- name_field.length= DEFAULT_FIELD_LENGTH;
- name.data= &name_field;
-
- state_field.str= (char *) "state";
- state_field.length= DEFAULT_FIELD_LENGTH;
- state.data= &state_field;
-
- field_list= list_add(NULL, &state);
- field_list= list_add(field_list, &name);
-
- return send_fields(net, field_list) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-int Show_instances::write_data(st_net *net)
-{
- my_bool err_status= FALSE;
-
- Instance *instance;
- Instance_map::Iterator iterator(instance_map);
-
- instance_map->lock();
-
- while ((instance= iterator.next()))
- {
- Buffer send_buf; /* buffer for packets */
- size_t pos= 0;
-
- instance->lock();
-
- const char *instance_name= instance->options.instance_name.str;
- const char *state_name= instance->get_state_name();
-
- if (store_to_protocol_packet(&send_buf, instance_name, &pos) ||
- store_to_protocol_packet(&send_buf, state_name, &pos) ||
- my_net_write(net, send_buf.buffer, pos))
- {
- err_status= TRUE;
- }
-
- instance->unlock();
-
- if (err_status)
- break;
- }
-
- instance_map->unlock();
-
- return err_status ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-/**************************************************************************
- Implementation of Flush_instances.
-**************************************************************************/
-
-/**
- Implementation of FLUSH INSTANCES statement.
-
- Possible error codes:
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
- ER_THERE_IS_ACTIVE_INSTACE If there is an active instance
-*/
-
-int Flush_instances::execute(st_net *net, ulong connection_id)
-{
- int err_status= Manager::flush_instances();
-
- if (err_status)
- return err_status;
-
- return net_send_ok(net, connection_id, NULL) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-/**************************************************************************
- Implementation of Instance_cmd.
-**************************************************************************/
-
-Instance_cmd::Instance_cmd(const LEX_STRING *instance_name_arg):
- instance_name(instance_name_arg)
-{
- /*
- MT-NOTE: we can not make a search for Instance object here,
- because it can dissappear after releasing the lock.
- */
-}
-
-
-/**************************************************************************
- Implementation of Abstract_instance_cmd.
-**************************************************************************/
-
-Abstract_instance_cmd::Abstract_instance_cmd(
- const LEX_STRING *instance_name_arg)
- :Instance_cmd(instance_name_arg)
-{
-}
-
-
-int Abstract_instance_cmd::execute(st_net *net, ulong connection_id)
-{
- int err_code;
- Instance *instance;
-
- instance_map->lock();
-
- instance= instance_map->find(get_instance_name());
-
- if (!instance)
- {
- instance_map->unlock();
- return ER_BAD_INSTANCE_NAME;
- }
-
- instance->lock();
- instance_map->unlock();
-
- err_code= execute_impl(net, instance);
-
- instance->unlock();
-
- if (!err_code)
- err_code= send_ok_response(net, connection_id);
-
- return err_code;
-}
-
-
-/**************************************************************************
- Implementation of Show_instance_status.
-**************************************************************************/
-
-Show_instance_status::Show_instance_status(const LEX_STRING *instance_name_arg)
- :Abstract_instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of SHOW INSTANCE STATUS statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Show_instance_status::execute_impl(st_net *net, Instance *instance)
-{
- int err_code;
-
- if ((err_code= write_header(net)) ||
- (err_code= write_data(net, instance)))
- return err_code;
-
- return 0;
-}
-
-
-int Show_instance_status::send_ok_response(st_net *net,
- ulong /* connection_id */)
-{
- if (send_eof(net) || net_flush(net))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-int Show_instance_status::write_header(st_net *net)
-{
- LIST name, state, version, version_number, mysqld_compatible;
- LIST *field_list;
- LEX_STRING name_field, state_field, version_field,
- version_number_field, mysqld_compatible_field;
-
- /* Create list of the fileds to be passed to send_fields(). */
-
- name_field.str= (char *) "instance_name";
- name_field.length= DEFAULT_FIELD_LENGTH;
- name.data= &name_field;
-
- state_field.str= (char *) "state";
- state_field.length= DEFAULT_FIELD_LENGTH;
- state.data= &state_field;
-
- version_field.str= (char *) "version";
- version_field.length= MAX_VERSION_LENGTH;
- version.data= &version_field;
-
- version_number_field.str= (char *) "version_number";
- version_number_field.length= MAX_VERSION_LENGTH;
- version_number.data= &version_number_field;
-
- mysqld_compatible_field.str= (char *) "mysqld_compatible";
- mysqld_compatible_field.length= DEFAULT_FIELD_LENGTH;
- mysqld_compatible.data= &mysqld_compatible_field;
-
- field_list= list_add(NULL, &mysqld_compatible);
- field_list= list_add(field_list, &version);
- field_list= list_add(field_list, &version_number);
- field_list= list_add(field_list, &state);
- field_list= list_add(field_list, &name);
-
- return send_fields(net, field_list) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-int Show_instance_status::write_data(st_net *net, Instance *instance)
-{
- Buffer send_buf; /* buffer for packets */
- char version_num_buf[MAX_VERSION_LENGTH];
- size_t pos= 0;
-
- const char *state_name= instance->get_state_name();
- const char *version_tag= "unknown";
- const char *version_num= "unknown";
- const char *mysqld_compatible_status=
- instance->is_mysqld_compatible() ? "yes" : "no";
-
- if (instance->options.mysqld_version)
- {
- if (parse_version_number(instance->options.mysqld_version, version_num_buf,
- sizeof(version_num_buf)))
- return ER_OUT_OF_RESOURCES;
-
- version_num= version_num_buf;
- version_tag= instance->options.mysqld_version;
- }
-
- if (store_to_protocol_packet(&send_buf, get_instance_name()->str, &pos) ||
- store_to_protocol_packet(&send_buf, state_name, &pos) ||
- store_to_protocol_packet(&send_buf, version_num, &pos) ||
- store_to_protocol_packet(&send_buf, version_tag, &pos) ||
- store_to_protocol_packet(&send_buf, mysqld_compatible_status, &pos) ||
- my_net_write(net, send_buf.buffer, pos))
- {
- return ER_OUT_OF_RESOURCES;
- }
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Show_instance_options.
-**************************************************************************/
-
-Show_instance_options::Show_instance_options(
- const LEX_STRING *instance_name_arg)
- :Abstract_instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of SHOW INSTANCE OPTIONS statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Show_instance_options::execute_impl(st_net *net, Instance *instance)
-{
- int err_code;
-
- if ((err_code= write_header(net)) ||
- (err_code= write_data(net, instance)))
- return err_code;
-
- return 0;
-}
-
-
-int Show_instance_options::send_ok_response(st_net *net,
- ulong /* connection_id */)
-{
- if (send_eof(net) || net_flush(net))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-int Show_instance_options::write_header(st_net *net)
-{
- LIST name, option;
- LIST *field_list;
- LEX_STRING name_field, option_field;
-
- /* Create list of the fileds to be passed to send_fields(). */
-
- name_field.str= (char *) "option_name";
- name_field.length= DEFAULT_FIELD_LENGTH;
- name.data= &name_field;
-
- option_field.str= (char *) "value";
- option_field.length= DEFAULT_FIELD_LENGTH;
- option.data= &option_field;
-
- field_list= list_add(NULL, &option);
- field_list= list_add(field_list, &name);
-
- return send_fields(net, field_list) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-int Show_instance_options::write_data(st_net *net, Instance *instance)
-{
- Buffer send_buff; /* buffer for packets */
- size_t pos= 0;
-
- if (store_to_protocol_packet(&send_buff, "instance_name", &pos) ||
- store_to_protocol_packet(&send_buff, get_instance_name()->str, &pos) ||
- my_net_write(net, send_buff.buffer, pos))
- {
- return ER_OUT_OF_RESOURCES;
- }
-
- /* Loop through the options. */
-
- for (int i= 0; i < instance->options.get_num_options(); i++)
- {
- Named_value option= instance->options.get_option(i);
- const char *option_value= option.get_value()[0] ? option.get_value() : "";
-
- pos= 0;
-
- if (store_to_protocol_packet(&send_buff, option.get_name(), &pos) ||
- store_to_protocol_packet(&send_buff, option_value, &pos) ||
- my_net_write(net, send_buff.buffer, pos))
- {
- return ER_OUT_OF_RESOURCES;
- }
- }
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Start_instance.
-**************************************************************************/
-
-Start_instance::Start_instance(const LEX_STRING *instance_name_arg)
- :Abstract_instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of START INSTANCE statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_INSTANCE_MISCONFIGURED The instance configuration is invalid
- ER_INSTANCE_ALREADY_STARTED The instance is already started
- ER_CANNOT_START_INSTANCE The instance could not have been started
-
- TODO: as soon as this method operates only with Instance, we probably
- should introduce a new method (execute_stop_instance()) in Instance and
- just call it from here.
-*/
-
-int Start_instance::execute_impl(st_net * /* net */, Instance *instance)
-{
- if (!instance->is_configured())
- return ER_INSTANCE_MISCONFIGURED;
-
- if (instance->is_active())
- return ER_INSTANCE_ALREADY_STARTED;
-
- if (instance->start_mysqld())
- return ER_CANNOT_START_INSTANCE;
-
- instance->reset_stat();
- instance->set_state(Instance::NOT_STARTED);
-
- return 0;
-}
-
-
-int Start_instance::send_ok_response(st_net *net, ulong connection_id)
-{
- if (net_send_ok(net, connection_id, "Instance started"))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Stop_instance.
-**************************************************************************/
-
-Stop_instance::Stop_instance(const LEX_STRING *instance_name_arg)
- :Abstract_instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of STOP INSTANCE statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-
- TODO: as soon as this method operates only with Instance, we probably
- should introduce a new method (execute_stop_instance()) in Instance and
- just call it from here.
-*/
-
-int Stop_instance::execute_impl(st_net * /* net */, Instance *instance)
-{
- if (!instance->is_active())
- return ER_INSTANCE_IS_NOT_STARTED;
-
- instance->set_state(Instance::STOPPED);
-
- return instance->stop_mysqld() ? ER_STOP_INSTANCE : 0;
-}
-
-
-int Stop_instance::send_ok_response(st_net *net, ulong connection_id)
-{
- if (net_send_ok(net, connection_id, NULL))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation for Create_instance.
-**************************************************************************/
-
-Create_instance::Create_instance(const LEX_STRING *instance_name_arg)
- :Instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- This operation initializes Create_instance object.
-
- SYNOPSIS
- text [IN/OUT] a pointer to the text containing instance options.
-
- RETURN
- FALSE On success.
- TRUE On error.
-*/
-
-bool Create_instance::init(const char **text)
-{
- return options.init() || parse_args(text);
-}
-
-
-/**
- This operation parses CREATE INSTANCE options.
-
- SYNOPSIS
- text [IN/OUT] a pointer to the text containing instance options.
-
- RETURN
- FALSE On success.
- TRUE On syntax error.
-*/
-
-bool Create_instance::parse_args(const char **text)
-{
- size_t len;
-
- /* Check if we have something (and trim leading spaces). */
-
- get_word(text, &len, NONSPACE);
-
- if (len == 0)
- return FALSE; /* OK: no option. */
-
- /* Main parsing loop. */
-
- while (TRUE)
- {
- LEX_STRING option_name;
- char *option_name_str;
- char *option_value_str= NULL;
-
- /* Looking for option name. */
-
- get_word(text, &option_name.length, OPTION_NAME);
-
- if (option_name.length == 0)
- return TRUE; /* Syntax error: option name expected. */
-
- option_name.str= (char *) *text;
- *text+= option_name.length;
-
- /* Looking for equal sign. */
-
- skip_spaces(text);
-
- if (**text == '=')
- {
- ++(*text); /* Skip an equal sign. */
-
- /* Looking for option value. */
-
- skip_spaces(text);
-
- if (!**text)
- return TRUE; /* Syntax error: EOS when option value expected. */
-
- if (**text != '\'' && **text != '"')
- {
- /* Option value is a simple token. */
-
- LEX_STRING option_value;
-
- get_word(text, &option_value.length, ALPHANUM);
-
- if (option_value.length == 0)
- return TRUE; /* internal parser error. */
-
- option_value.str= (char *) *text;
- *text+= option_value.length;
-
- if (!(option_value_str= Named_value::alloc_str(&option_value)))
- return TRUE; /* out of memory during parsing. */
- }
- else
- {
- /* Option value is a string. */
-
- if (parse_option_value(*text, &len, &option_value_str))
- return TRUE; /* Syntax error: invalid string specification. */
-
- *text+= len;
- }
- }
-
- if (!option_value_str)
- {
- LEX_STRING empty_str= { C_STRING_WITH_LEN("") };
-
- if (!(option_value_str= Named_value::alloc_str(&empty_str)))
- return TRUE; /* out of memory during parsing. */
- }
-
- if (!(option_name_str= Named_value::alloc_str(&option_name)))
- {
- Named_value::free_str(&option_value_str);
- return TRUE; /* out of memory during parsing. */
- }
-
- {
- Named_value option(option_name_str, option_value_str);
-
- if (options.add_element(&option))
- {
- option.free();
- return TRUE; /* out of memory during parsing. */
- }
- }
-
- skip_spaces(text);
-
- if (!**text)
- return FALSE; /* OK: end of options. */
-
- if (**text != ',')
- return TRUE; /* Syntax error: comma expected. */
-
- ++(*text);
- }
-}
-
-
-/**
- Implementation of CREATE INSTANCE statement.
-
- Possible error codes:
- ER_MALFORMED_INSTANCE_NAME Instance name is malformed
- ER_CREATE_EXISTING_INSTANCE There is an instance with the given name
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Create_instance::execute(st_net *net, ulong connection_id)
-{
- int err_code;
- Instance *instance;
-
- /* Check that the name is valid and there is no instance with such name. */
-
- if (!Instance::is_name_valid(get_instance_name()))
- return ER_MALFORMED_INSTANCE_NAME;
-
- /*
- NOTE: In order to prevent race condition, we should perform all operations
- on under acquired lock.
- */
-
- instance_map->lock();
-
- if (instance_map->find(get_instance_name()))
- {
- instance_map->unlock();
- return ER_CREATE_EXISTING_INSTANCE;
- }
-
- if ((err_code= instance_map->create_instance(get_instance_name(), &options)))
- {
- instance_map->unlock();
- return err_code;
- }
-
- instance= instance_map->find(get_instance_name());
- DBUG_ASSERT(instance);
-
- if ((err_code= create_instance_in_file(get_instance_name(), &options)))
- {
- instance_map->remove_instance(instance); /* instance is deleted here. */
-
- instance_map->unlock();
- return err_code;
- }
-
- /*
- CREATE INSTANCE must not lead to start instance, even if it guarded.
-
- TODO: The problem however is that if Instance Manager restarts after
- creating instance, the instance will be restarted (see also BUG#19718).
- */
-
- instance->set_state(Instance::STOPPED);
-
- /* That's all. */
-
- instance_map->unlock();
-
- /* Send the result. */
-
- if (net_send_ok(net, connection_id, NULL))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation for Drop_instance.
-**************************************************************************/
-
-Drop_instance::Drop_instance(const LEX_STRING *instance_name_arg)
- :Instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of DROP INSTANCE statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_DROP_ACTIVE_INSTANCE The specified instance is active
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Drop_instance::execute(st_net *net, ulong connection_id)
-{
- int err_code;
- Instance *instance;
-
- /* Lock Guardian, then Instance_map. */
-
- instance_map->lock();
-
- /* Find an instance. */
-
- instance= instance_map->find(get_instance_name());
-
- if (!instance)
- {
- instance_map->unlock();
- return ER_BAD_INSTANCE_NAME;
- }
-
- instance->lock();
-
- /* Check that the instance is offline. */
-
- if (instance->is_active())
- {
- instance->unlock();
- instance_map->unlock();
-
- return ER_DROP_ACTIVE_INSTANCE;
- }
-
- /* Try to remove instance from the file. */
-
- err_code= modify_defaults_file(Options::Main::config_file, NULL, NULL,
- get_instance_name()->str, MY_REMOVE_SECTION);
- DBUG_ASSERT(err_code >= 0 && err_code <= 2);
-
- if (err_code)
- {
- log_error("Can not remove instance '%s' from defaults file (%s). "
- "Original error code: %d.",
- (const char *) get_instance_name()->str,
- (const char *) Options::Main::config_file,
- (int) err_code);
-
- instance->unlock();
- instance_map->unlock();
-
- return modify_defaults_to_im_error[err_code];
- }
-
- /* Unlock the instance before destroy. */
-
- instance->unlock();
-
- /*
- Remove instance from the instance map
- (the instance will be also destroyed here).
- */
-
- instance_map->remove_instance(instance);
-
- /* Unlock the instance map. */
-
- instance_map->unlock();
-
- /* That's all: send ok. */
-
- if (net_send_ok(net, connection_id, "Instance dropped"))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation for Show_instance_log.
-**************************************************************************/
-
-Show_instance_log::Show_instance_log(const LEX_STRING *instance_name_arg,
- Log_type log_type_arg,
- uint size_arg, uint offset_arg)
- :Abstract_instance_cmd(instance_name_arg),
- log_type(log_type_arg),
- size(size_arg),
- offset(offset_arg)
-{
-}
-
-
-/**
- Implementation of SHOW INSTANCE LOG statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_OFFSET_ERROR We were requested to read negative number of
- bytes from the log
- ER_NO_SUCH_LOG The specified type of log is not available for
- the given instance
- ER_GUESS_LOGFILE IM wasn't able to figure out the log
- placement, while it is enabled. Probably user
- should specify the path to the logfile
- explicitly.
- ER_OPEN_LOGFILE Cannot open the logfile
- ER_READ_FILE Cannot read the logfile
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Show_instance_log::execute_impl(st_net *net, Instance *instance)
-{
- int err_code;
-
- if ((err_code= check_params(instance)))
- return err_code;
-
- if ((err_code= write_header(net)) ||
- (err_code= write_data(net, instance)))
- return err_code;
-
- return 0;
-}
-
-
-int Show_instance_log::send_ok_response(st_net *net,
- ulong /* connection_id */)
-{
- if (send_eof(net) || net_flush(net))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-int Show_instance_log::check_params(Instance *instance)
-{
- const char *logpath= instance->options.logs[log_type];
-
- /* Cannot read negative number of bytes. */
-
- if (offset > size)
- return ER_OFFSET_ERROR;
-
- /* Instance has no such log. */
-
- if (logpath == NULL)
- return ER_NO_SUCH_LOG;
-
- if (*logpath == '\0')
- return ER_GUESS_LOGFILE;
-
- return 0;
-}
-
-
-int Show_instance_log::write_header(st_net *net)
-{
- LIST name;
- LIST *field_list;
- LEX_STRING name_field;
-
- /* Create list of the fields to be passed to send_fields(). */
-
- name_field.str= (char *) "Log";
- name_field.length= DEFAULT_FIELD_LENGTH;
-
- name.data= &name_field;
-
- field_list= list_add(NULL, &name);
-
- return send_fields(net, field_list) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-int Show_instance_log::write_data(st_net *net, Instance *instance)
-{
- Buffer send_buff; /* buffer for packets */
- size_t pos= 0;
-
- const char *logpath= instance->options.logs[log_type];
- File fd;
-
- size_t buff_size;
- size_t read_len;
-
- MY_STAT file_stat;
- Buffer read_buff;
-
- if ((fd= my_open(logpath, O_RDONLY | O_BINARY, MYF(MY_WME))) <= 0)
- return ER_OPEN_LOGFILE;
-
- /* my_fstat doesn't use the flag parameter */
- if (my_fstat(fd, &file_stat, MYF(0)))
- {
- close(fd);
- return ER_OUT_OF_RESOURCES;
- }
-
- /* calculate buffer size */
- buff_size= (size - offset);
-
- read_buff.reserve(0, buff_size);
-
- /* read in one chunk */
- read_len= (int)my_seek(fd, file_stat.st_size - size, MY_SEEK_SET, MYF(0));
-
- if ((read_len= my_read(fd, read_buff.buffer, buff_size, MYF(0))) ==
- MY_FILE_ERROR)
- {
- close(fd);
- return ER_READ_FILE;
- }
-
- close(fd);
-
- if (store_to_protocol_packet(&send_buff, (char*) read_buff.buffer, &pos,
- read_len) ||
- my_net_write(net, send_buff.buffer, pos))
- {
- return ER_OUT_OF_RESOURCES;
- }
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Show_instance_log_files.
-**************************************************************************/
-
-Show_instance_log_files::Show_instance_log_files
- (const LEX_STRING *instance_name_arg)
- :Abstract_instance_cmd(instance_name_arg)
-{
-}
-
-
-/**
- Implementation of SHOW INSTANCE LOG FILES statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Show_instance_log_files::execute_impl(st_net *net, Instance *instance)
-{
- int err_code;
-
- if ((err_code= write_header(net)) ||
- (err_code= write_data(net, instance)))
- return err_code;
-
- return 0;
-}
-
-
-int Show_instance_log_files::send_ok_response(st_net *net,
- ulong /* connection_id */)
-{
- if (send_eof(net) || net_flush(net))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-int Show_instance_log_files::write_header(st_net *net)
-{
- LIST name, path, size;
- LIST *field_list;
- LEX_STRING name_field, path_field, size_field;
-
- /* Create list of the fileds to be passed to send_fields(). */
-
- name_field.str= (char *) "Logfile";
- name_field.length= DEFAULT_FIELD_LENGTH;
- name.data= &name_field;
-
- path_field.str= (char *) "Path";
- path_field.length= DEFAULT_FIELD_LENGTH;
- path.data= &path_field;
-
- size_field.str= (char *) "File size";
- size_field.length= DEFAULT_FIELD_LENGTH;
- size.data= &size_field;
-
- field_list= list_add(NULL, &size);
- field_list= list_add(field_list, &path);
- field_list= list_add(field_list, &name);
-
- return send_fields(net, field_list) ? ER_OUT_OF_RESOURCES : 0;
-}
-
-
-int Show_instance_log_files::write_data(st_net *net, Instance *instance)
-{
- Buffer send_buff; /* buffer for packets */
-
- /*
- We have alike structure in instance_options.cc. We use such to be able
- to loop through the options, which we need to handle in some common way.
- */
- struct log_files_st
- {
- const char *name;
- const char *value;
- } logs[]=
- {
- {"ERROR LOG", instance->options.logs[IM_LOG_ERROR]},
- {"GENERAL LOG", instance->options.logs[IM_LOG_GENERAL]},
- {"SLOW LOG", instance->options.logs[IM_LOG_SLOW]},
- {NULL, NULL}
- };
- struct log_files_st *log_files;
-
- for (log_files= logs; log_files->name; log_files++)
- {
- if (!log_files->value)
- continue;
-
- struct stat file_stat;
- /*
- Save some more space for the log file names. In fact all
- we need is strlen("GENERAL_LOG") + 1
- */
- enum { LOG_NAME_BUFFER_SIZE= 20 };
- char buff[LOG_NAME_BUFFER_SIZE];
-
- size_t pos= 0;
-
- const char *log_path= "";
- const char *log_size= "0";
-
- if (!stat(log_files->value, &file_stat) &&
- MY_S_ISREG(file_stat.st_mode))
- {
- int10_to_str(file_stat.st_size, buff, 10);
-
- log_path= log_files->value;
- log_size= buff;
- }
-
- if (store_to_protocol_packet(&send_buff, log_files->name, &pos) ||
- store_to_protocol_packet(&send_buff, log_path, &pos) ||
- store_to_protocol_packet(&send_buff, log_size, &pos) ||
- my_net_write(net, send_buff.buffer, pos))
- return ER_OUT_OF_RESOURCES;
- }
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Abstract_option_cmd.
-**************************************************************************/
-
-/**
- Instance_options_list -- a data class representing a list of options for
- some instance.
-*/
-
-class Instance_options_list
-{
-public:
- Instance_options_list(const LEX_STRING *instance_name_arg);
-
-public:
- bool init();
-
- const LEX_STRING *get_instance_name() const
- {
- return instance_name.get_str();
- }
-
-public:
- /*
- This member is set and used only in Abstract_option_cmd::execute_impl().
- Normally it is not used (and should not).
-
- The problem is that construction and execution of commands are made not
- in one transaction (not under one lock session). So, we can not initialize
- instance in constructor and use it in execution.
- */
- Instance *instance;
-
- Named_value_arr options;
-
-private:
- Instance_name instance_name;
-};
-
-
-/**************************************************************************/
-
-Instance_options_list::Instance_options_list(
- const LEX_STRING *instance_name_arg)
- :instance(NULL),
- instance_name(instance_name_arg)
-{
-}
-
-
-bool Instance_options_list::init()
-{
- return options.init();
-}
-
-
-/**************************************************************************/
-
-C_MODE_START
-
-static uchar* get_item_key(const uchar* item, size_t* len,
- my_bool __attribute__((unused)) t)
-{
- const Instance_options_list *lst= (const Instance_options_list *) item;
- *len= lst->get_instance_name()->length;
- return (uchar *) lst->get_instance_name()->str;
-}
-
-static void delete_item(void *item)
-{
- delete (Instance_options_list *) item;
-}
-
-C_MODE_END
-
-
-/**************************************************************************/
-
-Abstract_option_cmd::Abstract_option_cmd()
- :initialized(FALSE)
-{
-}
-
-
-Abstract_option_cmd::~Abstract_option_cmd()
-{
- if (initialized)
- hash_free(&instance_options_map);
-}
-
-
-bool Abstract_option_cmd::add_option(const LEX_STRING *instance_name,
- Named_value *option)
-{
- Instance_options_list *lst= get_instance_options_list(instance_name);
-
- if (!lst)
- return TRUE;
-
- lst->options.add_element(option);
-
- return FALSE;
-}
-
-
-bool Abstract_option_cmd::init(const char **text)
-{
- static const int INITIAL_HASH_SIZE= 16;
-
- if (hash_init(&instance_options_map, default_charset_info,
- INITIAL_HASH_SIZE, 0, 0, get_item_key, delete_item, 0))
- return TRUE;
-
- if (parse_args(text))
- return TRUE;
-
- initialized= TRUE;
-
- return FALSE;
-}
-
-
-/**
- Correct the option file. The "skip" option is used to remove the found
- option.
-
- SYNOPSIS
- Abstract_option_cmd::correct_file()
- skip Skip the option, being searched while writing the result file.
- That is, to delete it.
-
- RETURN
- 0 Success
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
- ER_ACCESS_OPTION_FILE Cannot access the option file
-*/
-
-int Abstract_option_cmd::correct_file(Instance *instance, Named_value *option,
- bool skip)
-{
- int err_code= modify_defaults_file(Options::Main::config_file,
- option->get_name(),
- option->get_value(),
- instance->get_name()->str,
- skip);
-
- DBUG_ASSERT(err_code >= 0 && err_code <= 2);
-
- if (err_code)
- {
- log_error("Can not modify option (%s) in defaults file (%s). "
- "Original error code: %d.",
- (const char *) option->get_name(),
- (const char *) Options::Main::config_file,
- (int) err_code);
- }
-
- return modify_defaults_to_im_error[err_code];
-}
-
-
-/**
- Lock Instance Map and call execute_impl().
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance with the given name does not exist
- ER_INCOMPATIBLE_OPTION The specified option can not be set for
- mysqld-compatible instance
- ER_INSTANCE_IS_ACTIVE The specified instance is active
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Abstract_option_cmd::execute(st_net *net, ulong connection_id)
-{
- int err_code;
-
- instance_map->lock();
-
- err_code= execute_impl(net, connection_id);
-
- instance_map->unlock();
-
- return err_code;
-}
-
-
-Instance_options_list *
-Abstract_option_cmd::get_instance_options_list(const LEX_STRING *instance_name)
-{
- Instance_options_list *lst=
- (Instance_options_list *) hash_search(&instance_options_map,
- (uchar *) instance_name->str,
- instance_name->length);
-
- if (!lst)
- {
- lst= new Instance_options_list(instance_name);
-
- if (!lst)
- return NULL;
-
- if (lst->init() || my_hash_insert(&instance_options_map, (uchar *) lst))
- {
- delete lst;
- return NULL;
- }
- }
-
- return lst;
-}
-
-
-/**
- Skeleton implementation of option-management command.
-
- MT-NOTE: Instance Map is locked before calling this operation.
-*/
-int Abstract_option_cmd::execute_impl(st_net *net, ulong connection_id)
-{
- int err_code= 0;
-
- /* Check that all the specified instances exist and are offline. */
-
- for (uint i= 0; i < instance_options_map.records; ++i)
- {
- Instance_options_list *lst=
- (Instance_options_list *) hash_element(&instance_options_map, i);
-
- bool instance_is_active;
-
- lst->instance= instance_map->find(lst->get_instance_name());
-
- if (!lst->instance)
- return ER_BAD_INSTANCE_NAME;
-
- lst->instance->lock();
- instance_is_active= lst->instance->is_active();
- lst->instance->unlock();
-
- if (instance_is_active)
- return ER_INSTANCE_IS_ACTIVE;
- }
-
- /* Perform command-specific (SET/UNSET) actions. */
-
- for (uint i= 0; i < instance_options_map.records; ++i)
- {
- Instance_options_list *lst=
- (Instance_options_list *) hash_element(&instance_options_map, i);
-
- lst->instance->lock();
-
- for (int j= 0; j < lst->options.get_size(); ++j)
- {
- Named_value option= lst->options.get_element(j);
- err_code= process_option(lst->instance, &option);
-
- if (err_code)
- break;
- }
-
- lst->instance->unlock();
-
- if (err_code)
- break;
- }
-
- if (err_code == 0)
- net_send_ok(net, connection_id, NULL);
-
- return err_code;
-}
-
-
-/**************************************************************************
- Implementation of Set_option.
-**************************************************************************/
-
-/**
- This operation parses SET options.
-
- SYNOPSIS
- text [IN/OUT] a pointer to the text containing options.
-
- RETURN
- FALSE On success.
- TRUE On syntax error.
-*/
-
-bool Set_option::parse_args(const char **text)
-{
- size_t len;
-
- /* Check if we have something (and trim leading spaces). */
-
- get_word(text, &len, NONSPACE);
-
- if (len == 0)
- return TRUE; /* Syntax error: no option. */
-
- /* Main parsing loop. */
-
- while (TRUE)
- {
- LEX_STRING instance_name;
- LEX_STRING option_name;
- char *option_name_str;
- char *option_value_str= NULL;
-
- /* Looking for instance name. */
-
- get_word(text, &instance_name.length, ALPHANUM);
-
- if (instance_name.length == 0)
- return TRUE; /* Syntax error: instance name expected. */
-
- instance_name.str= (char *) *text;
- *text+= instance_name.length;
-
- skip_spaces(text);
-
- /* Check the the delimiter is a dot. */
-
- if (**text != '.')
- return TRUE; /* Syntax error: dot expected. */
-
- ++(*text);
-
- /* Looking for option name. */
-
- get_word(text, &option_name.length, OPTION_NAME);
-
- if (option_name.length == 0)
- return TRUE; /* Syntax error: option name expected. */
-
- option_name.str= (char *) *text;
- *text+= option_name.length;
-
- /* Looking for equal sign. */
-
- skip_spaces(text);
-
- if (**text == '=')
- {
- ++(*text); /* Skip an equal sign. */
-
- /* Looking for option value. */
-
- skip_spaces(text);
-
- if (!**text)
- return TRUE; /* Syntax error: EOS when option value expected. */
-
- if (**text != '\'' && **text != '"')
- {
- /* Option value is a simple token. */
-
- LEX_STRING option_value;
-
- get_word(text, &option_value.length, ALPHANUM);
-
- if (option_value.length == 0)
- return TRUE; /* internal parser error. */
-
- option_value.str= (char *) *text;
- *text+= option_value.length;
-
- if (!(option_value_str= Named_value::alloc_str(&option_value)))
- return TRUE; /* out of memory during parsing. */
- }
- else
- {
- /* Option value is a string. */
-
- if (parse_option_value(*text, &len, &option_value_str))
- return TRUE; /* Syntax error: invalid string specification. */
-
- *text+= len;
- }
- }
-
- if (!option_value_str)
- {
- LEX_STRING empty_str= { C_STRING_WITH_LEN("") };
-
- if (!(option_value_str= Named_value::alloc_str(&empty_str)))
- return TRUE; /* out of memory during parsing. */
- }
-
- if (!(option_name_str= Named_value::alloc_str(&option_name)))
- {
- Named_value::free_str(&option_name_str);
- return TRUE; /* out of memory during parsing. */
- }
-
- {
- Named_value option(option_name_str, option_value_str);
-
- if (add_option(&instance_name, &option))
- {
- option.free();
- return TRUE; /* out of memory during parsing. */
- }
- }
-
- skip_spaces(text);
-
- if (!**text)
- return FALSE; /* OK: end of options. */
-
- if (**text != ',')
- return TRUE; /* Syntax error: comma expected. */
-
- ++(*text); /* Skip a comma. */
- }
-}
-
-
-int Set_option::process_option(Instance *instance, Named_value *option)
-{
- /* Check that the option is valid. */
-
- if (instance->is_mysqld_compatible() &&
- Instance_options::is_option_im_specific(option->get_name()))
- {
- log_error("IM-option (%s) can not be used "
- "in the configuration of mysqld-compatible instance (%s).",
- (const char *) option->get_name(),
- (const char *) instance->get_name()->str);
- return ER_INCOMPATIBLE_OPTION;
- }
-
- /* Update the configuration file. */
-
- int err_code= correct_file(instance, option, FALSE);
-
- if (err_code)
- return err_code;
-
- /* Update the internal cache. */
-
- if (instance->options.set_option(option))
- return ER_OUT_OF_RESOURCES;
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Unset_option.
-**************************************************************************/
-
-/**
- This operation parses UNSET options.
-
- SYNOPSIS
- text [IN/OUT] a pointer to the text containing options.
-
- RETURN
- FALSE On success.
- TRUE On syntax error.
-*/
-
-bool Unset_option::parse_args(const char **text)
-{
- size_t len;
-
- /* Check if we have something (and trim leading spaces). */
-
- get_word(text, &len, NONSPACE);
-
- if (len == 0)
- return TRUE; /* Syntax error: no option. */
-
- /* Main parsing loop. */
-
- while (TRUE)
- {
- LEX_STRING instance_name;
- LEX_STRING option_name;
- char *option_name_str;
- char *option_value_str;
-
- /* Looking for instance name. */
-
- get_word(text, &instance_name.length, ALPHANUM);
-
- if (instance_name.length == 0)
- return TRUE; /* Syntax error: instance name expected. */
-
- instance_name.str= (char *) *text;
- *text+= instance_name.length;
-
- skip_spaces(text);
-
- /* Check the the delimiter is a dot. */
-
- if (**text != '.')
- return TRUE; /* Syntax error: dot expected. */
-
- ++(*text); /* Skip a dot. */
-
- /* Looking for option name. */
-
- get_word(text, &option_name.length, OPTION_NAME);
-
- if (option_name.length == 0)
- return TRUE; /* Syntax error: option name expected. */
-
- option_name.str= (char *) *text;
- *text+= option_name.length;
-
- if (!(option_name_str= Named_value::alloc_str(&option_name)))
- return TRUE; /* out of memory during parsing. */
-
- {
- LEX_STRING empty_str= { C_STRING_WITH_LEN("") };
-
- if (!(option_value_str= Named_value::alloc_str(&empty_str)))
- {
- Named_value::free_str(&option_name_str);
- return TRUE;
- }
- }
-
- {
- Named_value option(option_name_str, option_value_str);
-
- if (add_option(&instance_name, &option))
- {
- option.free();
- return TRUE; /* out of memory during parsing. */
- }
- }
-
- skip_spaces(text);
-
- if (!**text)
- return FALSE; /* OK: end of options. */
-
- if (**text != ',')
- return TRUE; /* Syntax error: comma expected. */
-
- ++(*text); /* Skip a comma. */
- }
-}
-
-
-/**
- Implementation of UNSET statement.
-
- Possible error codes:
- ER_BAD_INSTANCE_NAME The instance name specified is not valid
- ER_INSTANCE_IS_ACTIVE The specified instance is active
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
-*/
-
-int Unset_option::process_option(Instance *instance, Named_value *option)
-{
- /* Update the configuration file. */
-
- int err_code= correct_file(instance, option, TRUE);
-
- if (err_code)
- return err_code;
-
- /* Update the internal cache. */
-
- instance->options.unset_option(option->get_name());
-
- return 0;
-}
-
-
-/**************************************************************************
- Implementation of Syntax_error.
-**************************************************************************/
-
-int Syntax_error::execute(st_net * /* net */, ulong /* connection_id */)
-{
- return ER_SYNTAX_ERROR;
-}
diff --git a/server-tools/instance-manager/commands.h b/server-tools/instance-manager/commands.h
deleted file mode 100644
index 5c2b2f9bbb7..00000000000
--- a/server-tools/instance-manager/commands.h
+++ /dev/null
@@ -1,393 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <hash.h>
-
-#include "command.h"
-#include "instance.h"
-#include "parse.h"
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-
-/**
- Print all instances of this instance manager.
- Grammar: SHOW INSTANCES
-*/
-
-class Show_instances: public Command
-{
-public:
- Show_instances()
- { }
-
-public:
- int execute(st_net *net, ulong connection_id);
-
-private:
- int write_header(st_net *net);
- int write_data(st_net *net);
-};
-
-
-/**
- Reread configuration file and refresh internal cache.
- Grammar: FLUSH INSTANCES
-*/
-
-class Flush_instances: public Command
-{
-public:
- Flush_instances()
- { }
-
-public:
- int execute(st_net *net, ulong connection_id);
-};
-
-
-/**
- Base class for Instance-specific commands
- (commands that operate on one instance).
-
- Instance_cmd extends Command class by:
- - an attribute for storing instance name;
- - code to initialize instance name in constructor;
- - an accessor to get instance name.
-*/
-
-class Instance_cmd : public Command
-{
-public:
- Instance_cmd(const LEX_STRING *instance_name_arg);
-
-protected:
- inline const LEX_STRING *get_instance_name() const
- {
- return instance_name.get_str();
- }
-
-private:
- Instance_name instance_name;
-};
-
-
-/**
- Abstract class for Instance-specific commands.
-
- Abstract_instance_cmd extends Instance_cmd by providing a common
- framework for writing command-implementations. Basically, the class
- implements Command::execute() pure virtual function in the following
- way:
- - Lock Instance_map;
- - Get an instance by name. Return an error, if there is no such
- instance;
- - Lock the instance;
- - Unlock Instance_map;
- - Call execute_impl(), which should be implemented in derived class;
- - Unlock the instance;
- - Send response to the client and return error status.
-*/
-
-class Abstract_instance_cmd: public Instance_cmd
-{
-public:
- Abstract_instance_cmd(const LEX_STRING *instance_name_arg);
-
-public:
- virtual int execute(st_net *net, ulong connection_id);
-
-protected:
- /**
- This operation is intended to contain command-specific implementation.
-
- MT-NOTE: this operation is called under acquired Instance's lock.
- */
- virtual int execute_impl(st_net *net, Instance *instance) = 0;
-
- /**
- This operation is invoked on successful return of execute_impl() and is
- intended to send closing data.
-
- MT-NOTE: this operation is called under released Instance's lock.
- */
- virtual int send_ok_response(st_net *net, ulong connection_id) = 0;
-};
-
-
-/**
- Print status of an instance.
- Grammar: SHOW INSTANCE STATUS <instance_name>
-*/
-
-class Show_instance_status: public Abstract_instance_cmd
-{
-public:
- Show_instance_status(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-
-private:
- int write_header(st_net *net);
- int write_data(st_net *net, Instance *instance);
-};
-
-
-/**
- Print options of chosen instance.
- Grammar: SHOW INSTANCE OPTIONS <instance_name>
-*/
-
-class Show_instance_options: public Abstract_instance_cmd
-{
-public:
- Show_instance_options(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-
-private:
- int write_header(st_net *net);
- int write_data(st_net *net, Instance *instance);
-};
-
-
-/**
- Start an instance.
- Grammar: START INSTANCE <instance_name>
-*/
-
-class Start_instance: public Abstract_instance_cmd
-{
-public:
- Start_instance(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-};
-
-
-/**
- Stop an instance.
- Grammar: STOP INSTANCE <instance_name>
-*/
-
-class Stop_instance: public Abstract_instance_cmd
-{
-public:
- Stop_instance(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-};
-
-
-/**
- Create an instance.
- Grammar: CREATE INSTANCE <instance_name> [<options>]
-*/
-
-class Create_instance: public Instance_cmd
-{
-public:
- Create_instance(const LEX_STRING *instance_name_arg);
-
-public:
- bool init(const char **text);
-
-protected:
- virtual int execute(st_net *net, ulong connection_id);
-
-private:
- bool parse_args(const char **text);
-
-private:
- Named_value_arr options;
-};
-
-
-/**
- Drop an instance.
- Grammar: DROP INSTANCE <instance_name>
-
- Operation is permitted only if the instance is stopped. On successful
- completion the instance section is removed from config file and the instance
- is removed from the instance map.
-*/
-
-class Drop_instance: public Instance_cmd
-{
-public:
- Drop_instance(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute(st_net *net, ulong connection_id);
-};
-
-
-/**
- Print requested part of the log.
- Grammar:
- SHOW <instance_name> LOG {ERROR | SLOW | GENERAL} size[, offset_from_end]
-*/
-
-class Show_instance_log: public Abstract_instance_cmd
-{
-public:
- Show_instance_log(const LEX_STRING *instance_name_arg,
- Log_type log_type_arg, uint size_arg, uint offset_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-
-private:
- int check_params(Instance *instance);
- int write_header(st_net *net);
- int write_data(st_net *net, Instance *instance);
-
-private:
- Log_type log_type;
- uint size;
- uint offset;
-};
-
-
-/**
- Shows the list of the log files, used by an instance.
- Grammar: SHOW <instance_name> LOG FILES
-*/
-
-class Show_instance_log_files: public Abstract_instance_cmd
-{
-public:
- Show_instance_log_files(const LEX_STRING *instance_name_arg);
-
-protected:
- virtual int execute_impl(st_net *net, Instance *instance);
- virtual int send_ok_response(st_net *net, ulong connection_id);
-
-private:
- int write_header(st_net *net);
- int write_data(st_net *net, Instance *instance);
-};
-
-
-/**
- Abstract class for option-management commands.
-*/
-
-class Instance_options_list;
-
-class Abstract_option_cmd: public Command
-{
-public:
- ~Abstract_option_cmd();
-
-public:
- bool add_option(const LEX_STRING *instance_name, Named_value *option);
-
-public:
- bool init(const char **text);
-
- virtual int execute(st_net *net, ulong connection_id);
-
-protected:
- Abstract_option_cmd();
-
- int correct_file(Instance *instance, Named_value *option, bool skip);
-
-protected:
- virtual bool parse_args(const char **text) = 0;
- virtual int process_option(Instance *instance, Named_value *option) = 0;
-
-private:
- Instance_options_list *
- get_instance_options_list(const LEX_STRING *instance_name);
-
- int execute_impl(st_net *net, ulong connection_id);
-
-private:
- HASH instance_options_map;
- bool initialized;
-};
-
-
-/**
- Set an option for the instance.
- Grammar: SET instance_name.option[=option_value][, ...]
-*/
-
-class Set_option: public Abstract_option_cmd
-{
-public:
- Set_option()
- { }
-
-protected:
- virtual bool parse_args(const char **text);
- virtual int process_option(Instance *instance, Named_value *option);
-};
-
-
-/**
- Remove option of the instance.
- Grammar: UNSET instance_name.option[, ...]
-*/
-
-class Unset_option: public Abstract_option_cmd
-{
-public:
- Unset_option()
- { }
-
-protected:
- virtual bool parse_args(const char **text);
- virtual int process_option(Instance *instance, Named_value *option);
-};
-
-
-/**
- Syntax error command.
-
- This command is issued if parser reported a syntax error. We need it to
- distinguish between syntax error and internal parser error. E.g. parsing
- failed because we hadn't had enought memory. In the latter case the parser
- just returns NULL.
-*/
-
-class Syntax_error: public Command
-{
-public:
- Syntax_error()
- { }
-
-public:
- int execute(st_net *net, ulong connection_id);
-};
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H */
diff --git a/server-tools/instance-manager/exit_codes.h b/server-tools/instance-manager/exit_codes.h
deleted file mode 100644
index 1609debd8f9..00000000000
--- a/server-tools/instance-manager/exit_codes.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
-
-/*
- Copyright (C) 2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- This file contains a list of exit codes, which are used when Instance
- Manager is working in user-management mode.
-*/
-
-const int ERR_OK = 0;
-
-const int ERR_OUT_OF_MEMORY = 1;
-const int ERR_INVALID_USAGE = 2;
-const int ERR_INTERNAL_ERROR = 3;
-const int ERR_IO_ERROR = 4;
-const int ERR_PASSWORD_FILE_CORRUPTED = 5;
-const int ERR_PASSWORD_FILE_DOES_NOT_EXIST = 6;
-
-const int ERR_CAN_NOT_READ_USER_NAME = 10;
-const int ERR_CAN_NOT_READ_PASSWORD = 11;
-const int ERR_USER_ALREADY_EXISTS = 12;
-const int ERR_USER_NOT_FOUND = 13;
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
deleted file mode 100644
index b49b0ec0a00..00000000000
--- a/server-tools/instance-manager/guardian.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "guardian.h"
-#include <string.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include "instance.h"
-#include "instance_map.h"
-#include "log.h"
-#include "mysql_manager_error.h"
-#include "options.h"
-
-
-/*************************************************************************
- {{{ Constructor & destructor.
-*************************************************************************/
-
-/**
- Guardian constructor.
-
- SYNOPSIS
- Guardian()
- thread_registry_arg
- instance_map_arg
-
- DESCRIPTION
- Nominal contructor intended for assigning references and initialize
- trivial objects. Real initialization is made by init() method.
-*/
-
-Guardian::Guardian(Thread_registry *thread_registry_arg,
- Instance_map *instance_map_arg)
- :shutdown_requested(FALSE),
- stopped(FALSE),
- thread_registry(thread_registry_arg),
- instance_map(instance_map_arg)
-{
- pthread_mutex_init(&LOCK_guardian, 0);
- pthread_cond_init(&COND_guardian, 0);
-}
-
-
-Guardian::~Guardian()
-{
- /*
- NOTE: it's necessary to synchronize here, because Guiardian thread can be
- still alive an hold the mutex (because it is detached and we have no
- control over it).
- */
-
- lock();
- unlock();
-
- pthread_mutex_destroy(&LOCK_guardian);
- pthread_cond_destroy(&COND_guardian);
-}
-
-/*************************************************************************
- }}}
-*************************************************************************/
-
-
-/**
- Send request to stop Guardian.
-
- SYNOPSIS
- request_shutdown()
-*/
-
-void Guardian::request_shutdown()
-{
- stop_instances();
-
- lock();
- shutdown_requested= TRUE;
- unlock();
-
- ping();
-}
-
-
-/**
- Process an instance.
-
- SYNOPSIS
- process_instance()
- instance a pointer to the instance for processing
-
- MT-NOTE:
- - the given instance must be locked before calling this operation;
- - Guardian must be locked before calling this operation.
-*/
-
-void Guardian::process_instance(Instance *instance)
-{
- int restart_retry= 100;
- time_t current_time= time(NULL);
-
- if (instance->get_state() == Instance::STOPPING)
- {
- /* This brach is executed during shutdown. */
-
- /* This returns TRUE if and only if an instance was stopped for sure. */
- if (instance->is_crashed())
- {
- log_info("Guardian: '%s' stopped.",
- (const char *) instance->get_name()->str);
-
- instance->set_state(Instance::STOPPED);
- }
- else if ((uint) (current_time - instance->last_checked) >=
- instance->options.get_shutdown_delay())
- {
- log_info("Guardian: '%s' hasn't stopped within %d secs.",
- (const char *) instance->get_name()->str,
- (int) instance->options.get_shutdown_delay());
-
- instance->kill_mysqld(SIGKILL);
-
- log_info("Guardian: pretend that '%s' is killed.",
- (const char *) instance->get_name()->str);
-
- instance->set_state(Instance::STOPPED);
- }
- else
- {
- log_info("Guardian: waiting for '%s' to stop (%d secs left).",
- (const char *) instance->get_name()->str,
- (int) (instance->options.get_shutdown_delay() -
- current_time + instance->last_checked));
- }
-
- return;
- }
-
- if (instance->is_mysqld_running())
- {
- /* The instance can be contacted on it's port */
-
- /* If STARTING also check that pidfile has been created */
- if (instance->get_state() == Instance::STARTING &&
- instance->options.load_pid() == 0)
- {
- /* Pid file not created yet, don't go to STARTED state yet */
- }
- else if (instance->get_state() != Instance::STARTED)
- {
- /* clear status fields */
- log_info("Guardian: '%s' is running, set state to STARTED.",
- (const char *) instance->options.instance_name.str);
- instance->reset_stat();
- instance->set_state(Instance::STARTED);
- }
- }
- else
- {
- switch (instance->get_state()) {
- case Instance::NOT_STARTED:
- log_info("Guardian: starting '%s'...",
- (const char *) instance->options.instance_name.str);
-
- /* NOTE: set state to STARTING _before_ start() is called. */
- instance->set_state(Instance::STARTING);
- instance->last_checked= current_time;
-
- instance->start_mysqld();
-
- return;
-
- case Instance::STARTED: /* fallthrough */
- case Instance::STARTING: /* let the instance start or crash */
- if (!instance->is_crashed())
- return;
-
- instance->crash_moment= current_time;
- instance->last_checked= current_time;
- instance->set_state(Instance::JUST_CRASHED);
- /* fallthrough -- restart an instance immediately */
-
- case Instance::JUST_CRASHED:
- if (current_time - instance->crash_moment <= 2)
- {
- if (instance->is_crashed())
- {
- instance->start_mysqld();
- log_info("Guardian: starting '%s'...",
- (const char *) instance->options.instance_name.str);
- }
- }
- else
- instance->set_state(Instance::CRASHED);
-
- return;
-
- case Instance::CRASHED: /* just regular restarts */
- if ((ulong) (current_time - instance->last_checked) <=
- (ulong) Options::Main::monitoring_interval)
- return;
-
- if (instance->restart_counter < restart_retry)
- {
- if (instance->is_crashed())
- {
- instance->start_mysqld();
- instance->last_checked= current_time;
-
- log_info("Guardian: restarting '%s'...",
- (const char *) instance->options.instance_name.str);
- }
- }
- else
- {
- log_info("Guardian: can not start '%s'. "
- "Abandoning attempts to (re)start it",
- (const char *) instance->options.instance_name.str);
-
- instance->set_state(Instance::CRASHED_AND_ABANDONED);
- }
-
- return;
-
- case Instance::CRASHED_AND_ABANDONED:
- return; /* do nothing */
-
- default:
- DBUG_ASSERT(0);
- }
- }
-}
-
-
-/**
- Main function of Guardian thread.
-
- SYNOPSIS
- run()
-
- DESCRIPTION
- Check for all guarded instances and restart them if needed.
-*/
-
-void Guardian::run()
-{
- struct timespec timeout;
-
- log_info("Guardian: started.");
-
- thread_registry->register_thread(&thread_info);
-
- /* Loop, until all instances were shut down at the end. */
-
- while (true)
- {
- Instance_map::Iterator instances_it(instance_map);
- Instance *instance;
- bool all_instances_stopped= TRUE;
-
- instance_map->lock();
-
- while ((instance= instances_it.next()))
- {
- instance->lock();
-
- if (!instance->is_guarded() ||
- instance->get_state() == Instance::STOPPED)
- {
- instance->unlock();
- continue;
- }
-
- process_instance(instance);
-
- if (instance->get_state() != Instance::STOPPED)
- all_instances_stopped= FALSE;
-
- instance->unlock();
- }
-
- instance_map->unlock();
-
- lock();
-
- if (shutdown_requested && all_instances_stopped)
- {
- log_info("Guardian: all guarded mysqlds stopped.");
-
- stopped= TRUE;
- unlock();
- break;
- }
-
- set_timespec(timeout, Options::Main::monitoring_interval);
-
- thread_registry->cond_timedwait(&thread_info, &COND_guardian,
- &LOCK_guardian, &timeout);
- unlock();
- }
-
- log_info("Guardian: stopped.");
-
- /* Now, when the Guardian is stopped we can stop the IM. */
-
- thread_registry->unregister_thread(&thread_info);
- thread_registry->request_shutdown();
-
- log_info("Guardian: finished.");
-}
-
-
-/**
- Return the value of stopped flag.
-*/
-
-bool Guardian::is_stopped()
-{
- int var;
-
- lock();
- var= stopped;
- unlock();
-
- return var;
-}
-
-
-/**
- Wake up Guardian thread.
-
- MT-NOTE: though usually the mutex associated with condition variable should
- be acquired before signalling the variable, here this is not needed.
- Signalling under locked mutex is used to avoid lost signals. In the current
- logic however locking mutex does not guarantee that the signal will not be
- lost.
-*/
-
-void Guardian::ping()
-{
- pthread_cond_signal(&COND_guardian);
-}
-
-
-/**
- Prepare list of instances.
-
- SYNOPSIS
- init()
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-void Guardian::init()
-{
- Instance *instance;
- Instance_map::Iterator iterator(instance_map);
-
- while ((instance= iterator.next()))
- {
- instance->lock();
-
- instance->reset_stat();
- instance->set_state(Instance::NOT_STARTED);
-
- instance->unlock();
- }
-}
-
-
-/**
- An internal method which is called at shutdown to unregister instances and
- attempt to stop them if requested.
-
- SYNOPSIS
- stop_instances()
-
- DESCRIPTION
- Loops through the guarded_instances list and prepares them for shutdown.
- For each instance we issue a stop command and change the state
- accordingly.
-
- NOTE
- Guardian object should be locked by the caller.
-
-*/
-
-void Guardian::stop_instances()
-{
- static const int NUM_STOP_ATTEMPTS = 100;
-
- Instance_map::Iterator instances_it(instance_map);
- Instance *instance;
-
- instance_map->lock();
-
- while ((instance= instances_it.next()))
- {
- instance->lock();
-
- if (!instance->is_guarded() ||
- instance->get_state() == Instance::STOPPED)
- {
- instance->unlock();
- continue;
- }
-
- /*
- If instance is running or was running (and now probably hanging),
- request stop.
- */
-
- if (instance->is_mysqld_running() ||
- instance->get_state() == Instance::STARTED)
- {
- instance->set_state(Instance::STOPPING);
- instance->last_checked= time(NULL);
- }
- else
- {
- /* Otherwise mark it as STOPPED. */
- instance->set_state(Instance::STOPPED);
- }
-
- /* Request mysqld to stop. */
-
- bool instance_stopped= FALSE;
-
- for (int cur_attempt= 0; cur_attempt < NUM_STOP_ATTEMPTS; ++cur_attempt)
- {
- if (!instance->kill_mysqld(SIGTERM))
- {
- instance_stopped= TRUE;
- break;
- }
-
- if (!instance->is_active())
- {
- instance_stopped= TRUE;
- break;
- }
-
- /* Sleep for 0.3 sec and check again. */
-
- my_sleep(300000);
- }
-
- /*
- Abort if we failed to stop mysqld instance. That should not happen,
- but if it happened, we don't know what to do and prefer to have clear
- failure with coredump.
- */
-
- DBUG_ASSERT(instance_stopped);
-
- instance->unlock();
- }
-
- instance_map->unlock();
-}
-
-
-/**
- Lock Guardian.
-*/
-
-void Guardian::lock()
-{
- pthread_mutex_lock(&LOCK_guardian);
-}
-
-
-/**
- Unlock Guardian.
-*/
-
-void Guardian::unlock()
-{
- pthread_mutex_unlock(&LOCK_guardian);
-}
diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h
deleted file mode 100644
index d78058a6fc5..00000000000
--- a/server-tools/instance-manager/guardian.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <my_list.h>
-
-#include "thread_registry.h"
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-class Instance;
-class Instance_map;
-class Thread_registry;
-
-/**
- The guardian thread is responsible for monitoring and restarting of guarded
- instances.
-*/
-
-class Guardian: public Thread
-{
-public:
- Guardian(Thread_registry *thread_registry_arg,
- Instance_map *instance_map_arg);
- ~Guardian();
-
- void init();
-
-public:
- void request_shutdown();
-
- bool is_stopped();
-
- void lock();
- void unlock();
-
- void ping();
-
-protected:
- virtual void run();
-
-private:
- void stop_instances();
-
- void process_instance(Instance *instance);
-
-private:
- /*
- LOCK_guardian protectes the members in this section:
- - shutdown_requested;
- - stopped;
-
- Also, it is used for COND_guardian.
- */
- pthread_mutex_t LOCK_guardian;
-
- /*
- Guardian's main loop waits on this condition. So, it should be signalled
- each time, when instance state has been changed and we want Guardian to
- wake up.
-
- TODO: Change this to having data-scoped conditions, i.e. conditions,
- which indicate that some data has been changed.
- */
- pthread_cond_t COND_guardian;
-
- /*
- This variable is set to TRUE, when Manager thread is shutting down.
- The flag is used by Guardian thread to understand that it's time to
- finish.
- */
- bool shutdown_requested;
-
- /*
- This flag is set to TRUE on shutdown by Guardian thread, when all guarded
- mysqlds are stopped.
-
- The flag is used in the Manager thread to wait for Guardian to stop all
- mysqlds.
- */
- bool stopped;
-
- Thread_info thread_info;
- Thread_registry *thread_registry;
- Instance_map *instance_map;
-
-private:
- Guardian(const Guardian &);
- Guardian&operator =(const Guardian &);
-};
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H */
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
deleted file mode 100644
index 1ad728d40eb..00000000000
--- a/server-tools/instance-manager/instance.cc
+++ /dev/null
@@ -1,944 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include <my_global.h>
-#include <mysql.h>
-
-#include <signal.h>
-#ifndef __WIN__
-#include <sys/wait.h>
-#endif
-
-#include "manager.h"
-#include "guardian.h"
-#include "instance.h"
-#include "log.h"
-#include "mysql_manager_error.h"
-#include "portability.h"
-#include "priv.h"
-#include "thread_registry.h"
-#include "instance_map.h"
-
-
-/*************************************************************************
- {{{ Platform-specific functions.
-*************************************************************************/
-
-#ifndef __WIN__
-typedef pid_t My_process_info;
-#else
-typedef PROCESS_INFORMATION My_process_info;
-#endif
-
-/*
- Wait for an instance
-
- SYNOPSIS
- wait_process()
- pi Pointer to the process information structure
- (platform-dependent).
-
- RETURN
- 0 - Success
- 1 - Error
-*/
-
-#ifndef __WIN__
-static int wait_process(My_process_info *pi)
-{
- /*
- Here we wait for the child created. This process differs for systems
- running LinuxThreads and POSIX Threads compliant systems. This is because
- according to POSIX we could wait() for a child in any thread of the
- process. While LinuxThreads require that wait() is called by the thread,
- which created the child.
- On the other hand we could not expect mysqld to return the pid, we
- got in from fork(), to wait4() fucntion when running on LinuxThreads.
- This is because MySQL shutdown thread is not the one, which was created
- by our fork() call.
- So basically we have two options: whether the wait() call returns only in
- the creator thread, but we cannot use waitpid() since we have no idea
- which pid we should wait for (in fact it should be the pid of shutdown
- thread, but we don't know this one). Or we could use waitpid(), but
- couldn't use wait(), because it could return in any wait() in the program.
- */
-
- if (Manager::is_linux_threads())
- wait(NULL); /* LinuxThreads were detected */
- else
- waitpid(*pi, NULL, 0);
-
- return 0;
-}
-#else
-static int wait_process(My_process_info *pi)
-{
- /* Wait until child process exits. */
- WaitForSingleObject(pi->hProcess, INFINITE);
-
- DWORD exitcode;
- ::GetExitCodeProcess(pi->hProcess, &exitcode);
-
- /* Close process and thread handles. */
- CloseHandle(pi->hProcess);
- CloseHandle(pi->hThread);
-
- /*
- GetExitCodeProces returns zero on failure. We should revert this value
- to report an error.
- */
- return (!exitcode);
-}
-#endif
-
-/*
- Launch an instance
-
- SYNOPSIS
- start_process()
- instance_options Pointer to the options of the instance to be
- launched.
- pi Pointer to the process information structure
- (platform-dependent).
-
- RETURN
- FALSE - Success
- TRUE - Cannot create an instance
-*/
-
-#ifndef __WIN__
-static bool start_process(Instance_options *instance_options,
- My_process_info *pi)
-{
-#ifndef __QNX__
- *pi= fork();
-#else
- /*
- On QNX one cannot use fork() in multithreaded environment and we
- should use spawn() or one of it's siblings instead.
- Here we use spawnv(), which is a combination of fork() and execv()
- in one call. It returns the pid of newly created process (>0) or -1
- */
- *pi= spawnv(P_NOWAIT, instance_options->mysqld_path, instance_options->argv);
-#endif
-
- switch (*pi) {
- case 0: /* never happens on QNX */
- execv(instance_options->mysqld_path.str, instance_options->argv);
- /* exec never returns */
- exit(1);
- case -1:
- log_error("Instance '%s': can not start mysqld: fork() failed.",
- (const char *) instance_options->instance_name.str);
- return TRUE;
- }
-
- return FALSE;
-}
-#else
-static bool start_process(Instance_options *instance_options,
- My_process_info *pi)
-{
- STARTUPINFO si;
-
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb= sizeof(STARTUPINFO);
- ZeroMemory(pi, sizeof(PROCESS_INFORMATION));
-
- int cmdlen= 0;
- for (int i= 0; instance_options->argv[i] != 0; i++)
- cmdlen+= (uint) strlen(instance_options->argv[i]) + 3;
- cmdlen++; /* make room for the null */
-
- char *cmdline= new char[cmdlen];
- if (cmdline == NULL)
- return TRUE;
-
- cmdline[0]= 0;
- for (int i= 0; instance_options->argv[i] != 0; i++)
- {
- strcat(cmdline, "\"");
- strcat(cmdline, instance_options->argv[i]);
- strcat(cmdline, "\" ");
- }
-
- /* Start the child process */
- BOOL result=
- CreateProcess(NULL, /* Put it all in cmdline */
- cmdline, /* Command line */
- NULL, /* Process handle not inheritable */
- NULL, /* Thread handle not inheritable */
- FALSE, /* Set handle inheritance to FALSE */
- 0, /* No creation flags */
- NULL, /* Use parent's environment block */
- NULL, /* Use parent's starting directory */
- &si, /* Pointer to STARTUPINFO structure */
- pi); /* Pointer to PROCESS_INFORMATION structure */
- delete cmdline;
-
- return !result;
-}
-#endif
-
-#ifdef __WIN__
-
-BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
-{
- DWORD dwTID, dwCode, dwErr= 0;
- HANDLE hProcessDup= INVALID_HANDLE_VALUE;
- HANDLE hRT= NULL;
- HINSTANCE hKernel= GetModuleHandle("Kernel32");
- BOOL bSuccess= FALSE;
-
- BOOL bDup= DuplicateHandle(GetCurrentProcess(),
- hProcess, GetCurrentProcess(), &hProcessDup,
- PROCESS_ALL_ACCESS, FALSE, 0);
-
- // Detect the special case where the process is
- // already dead...
- if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
- (dwCode == STILL_ACTIVE))
- {
- FARPROC pfnExitProc;
-
- pfnExitProc= GetProcAddress(hKernel, "ExitProcess");
-
- hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0,
- (LPTHREAD_START_ROUTINE)pfnExitProc,
- (PVOID)uExitCode, 0, &dwTID);
-
- if (hRT == NULL)
- dwErr= GetLastError();
- }
- else
- dwErr= ERROR_PROCESS_ABORTED;
-
- if (hRT)
- {
- // Must wait process to terminate to
- // guarantee that it has exited...
- WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
-
- CloseHandle(hRT);
- bSuccess= TRUE;
- }
-
- if (bDup)
- CloseHandle(hProcessDup);
-
- if (!bSuccess)
- SetLastError(dwErr);
-
- return bSuccess;
-}
-
-int kill(pid_t pid, int signum)
-{
- HANDLE processhandle= ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (signum == SIGTERM)
- ::SafeTerminateProcess(processhandle, 0);
- else
- ::TerminateProcess(processhandle, -1);
- return 0;
-}
-#endif
-
-/*************************************************************************
- }}}
-*************************************************************************/
-
-
-/*************************************************************************
- {{{ Static constants.
-*************************************************************************/
-
-const LEX_STRING
-Instance::DFLT_INSTANCE_NAME= { C_STRING_WITH_LEN("mysqld") };
-
-/*************************************************************************
- }}}
-*************************************************************************/
-
-
-/*************************************************************************
- {{{ Instance Monitor thread.
-*************************************************************************/
-
-/**
- Proxy thread is a simple way to avoid all pitfalls of the threads
- implementation in the OS (e.g. LinuxThreads). With such a thread we
- don't have to process SIGCHLD, which is a tricky business if we want
- to do it in a portable way.
-
- Instance Monitor Thread forks a child process, execs mysqld and waits for
- the child to die.
-
- Instance Monitor assumes that the monitoring instance will not be dropped.
- This is guaranteed by having flag monitoring_thread_active and
- Instance::is_active() operation.
-*/
-
-class Instance_monitor: public Thread
-{
-public:
- Instance_monitor(Instance *instance_arg) :instance(instance_arg) {}
-protected:
- virtual void run();
- void start_and_monitor_instance();
-private:
- Instance *instance;
-};
-
-
-void Instance_monitor::run()
-{
- start_and_monitor_instance();
- delete this;
-}
-
-
-void Instance_monitor::start_and_monitor_instance()
-{
- Thread_registry *thread_registry= Manager::get_thread_registry();
- Guardian *guardian= Manager::get_guardian();
-
- My_process_info mysqld_process_info;
- Thread_info monitor_thread_info;
-
- log_info("Instance '%s': Monitor: started.",
- (const char *) instance->get_name()->str);
-
- /*
- For guarded instance register the thread in Thread_registry to wait for
- the thread to stop on shutdown (nonguarded instances are not stopped on
- shutdown, so the thread will no finish).
- */
-
- if (instance->is_guarded())
- {
- thread_registry->register_thread(&monitor_thread_info, FALSE);
- }
-
- /* Starting mysqld. */
-
- log_info("Instance '%s': Monitor: starting mysqld...",
- (const char *) instance->get_name()->str);
-
- if (start_process(&instance->options, &mysqld_process_info))
- {
- instance->lock();
- instance->monitoring_thread_active= FALSE;
- instance->unlock();
-
- return;
- }
-
- /* Waiting for mysqld to die. */
-
- log_info("Instance '%s': Monitor: waiting for mysqld to stop...",
- (const char *) instance->get_name()->str);
-
- wait_process(&mysqld_process_info); /* Don't check for return value. */
-
- log_info("Instance '%s': Monitor: mysqld stopped.",
- (const char *) instance->get_name()->str);
-
- /* Update instance status. */
-
- instance->lock();
-
- if (instance->is_guarded())
- thread_registry->unregister_thread(&monitor_thread_info);
-
- instance->crashed= TRUE;
- instance->monitoring_thread_active= FALSE;
-
- log_info("Instance '%s': Monitor: finished.",
- (const char *) instance->get_name()->str);
-
- instance->unlock();
-
- /* Wake up guardian. */
-
- guardian->ping();
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
-
-
-/**************************************************************************
- {{{ Static operations.
-**************************************************************************/
-
-/**
- The operation is intended to check whether string is a well-formed
- instance name or not.
-
- SYNOPSIS
- is_name_valid()
- name string to check
-
- RETURN
- TRUE string is a valid instance name
- FALSE string is not a valid instance name
-
- TODO: Move to Instance_name class: Instance_name::is_valid().
-*/
-
-bool Instance::is_name_valid(const LEX_STRING *name)
-{
- const char *name_suffix= name->str + DFLT_INSTANCE_NAME.length;
-
- if (strncmp(name->str, Instance::DFLT_INSTANCE_NAME.str,
- Instance::DFLT_INSTANCE_NAME.length) != 0)
- return FALSE;
-
- return *name_suffix == 0 || my_isdigit(default_charset_info, *name_suffix);
-}
-
-
-/**
- The operation is intended to check if the given instance name is
- mysqld-compatible or not.
-
- SYNOPSIS
- is_mysqld_compatible_name()
- name name to check
-
- RETURN
- TRUE name is mysqld-compatible
- FALSE otherwise
-
- TODO: Move to Instance_name class: Instance_name::is_mysqld_compatible().
-*/
-
-bool Instance::is_mysqld_compatible_name(const LEX_STRING *name)
-{
- return strcmp(name->str, DFLT_INSTANCE_NAME.str) == 0;
-}
-
-
-/**
- Return client state name. Must not be used outside the class.
- Use Instance::get_state_name() instead.
-*/
-
-const char * Instance::get_instance_state_name(enum_instance_state state)
-{
- switch (state) {
- case STOPPED:
- return "offline";
-
- case NOT_STARTED:
- return "not started";
-
- case STARTING:
- return "starting";
-
- case STARTED:
- return "online";
-
- case JUST_CRASHED:
- return "failed";
-
- case CRASHED:
- return "crashed";
-
- case CRASHED_AND_ABANDONED:
- return "abandoned";
-
- case STOPPING:
- return "stopping";
- }
-
- return NULL; /* just to ignore compiler warning. */
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
-
-
-/**************************************************************************
- {{{ Initialization & deinitialization.
-**************************************************************************/
-
-Instance::Instance()
- :monitoring_thread_active(FALSE),
- crashed(FALSE),
- configured(FALSE),
- /* mysqld_compatible is initialized in init() */
- state(NOT_STARTED),
- restart_counter(0),
- crash_moment(0),
- last_checked(0)
-{
- pthread_mutex_init(&LOCK_instance, 0);
-}
-
-
-Instance::~Instance()
-{
- log_info("Instance '%s': destroying...", (const char *) get_name()->str);
-
- pthread_mutex_destroy(&LOCK_instance);
-}
-
-
-/**
- Initialize instance options.
-
- SYNOPSIS
- init()
- name_arg name of the instance
-
- RETURN:
- FALSE - ok
- TRUE - error
-*/
-
-bool Instance::init(const LEX_STRING *name_arg)
-{
- mysqld_compatible= is_mysqld_compatible_name(name_arg);
-
- return options.init(name_arg);
-}
-
-
-/**
- @brief Complete instance options initialization.
-
- @return Error status.
- @retval FALSE ok
- @retval TRUE error
-*/
-
-bool Instance::complete_initialization()
-{
- configured= ! options.complete_initialization();
- return !configured;
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
-
-
-/**************************************************************************
- {{{ Instance: public interface implementation.
-**************************************************************************/
-
-/**
- Determine if there is some activity with the instance.
-
- SYNOPSIS
- is_active()
-
- DESCRIPTION
- An instance is active if one of the following conditions is true:
- - Instance-monitoring thread is running;
- - Instance is guarded and its state is other than STOPPED;
- - Corresponding mysqld-server accepts connections.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- RETURN
- TRUE - instance is active
- FALSE - otherwise.
-*/
-
-bool Instance::is_active()
-{
- if (monitoring_thread_active)
- return TRUE;
-
- if (is_guarded() && get_state() != STOPPED)
- return TRUE;
-
- return is_mysqld_running();
-}
-
-
-/**
- Determine if mysqld is accepting connections.
-
- SYNOPSIS
- is_mysqld_running()
-
- DESCRIPTION
- Try to connect to mysqld with fake login/password to check whether it is
- accepting connections or not.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- RETURN
- TRUE - mysqld is alive and accept connections
- FALSE - otherwise.
-*/
-
-bool Instance::is_mysqld_running()
-{
- MYSQL mysql;
- uint port= options.get_mysqld_port(); /* 0 if not specified. */
- const char *socket= NULL;
- static const char *password= "check_connection";
- static const char *username= "MySQL_Instance_Manager";
- static const char *access_denied_message= "Access denied for user";
- bool return_val;
-
- if (options.mysqld_socket)
- socket= options.mysqld_socket;
-
- /* no port was specified => instance falled back to default value */
- if (!port && !options.mysqld_socket)
- port= SERVER_DEFAULT_PORT;
-
- mysql_init(&mysql);
- /* try to connect to a server with a fake username/password pair */
- if (mysql_real_connect(&mysql, LOCAL_HOST, username,
- password,
- NullS, port,
- socket, 0))
- {
- /*
- We have successfully connected to the server using fake
- username/password. Write a warning to the logfile.
- */
- log_error("Instance '%s': was able to log into mysqld.",
- (const char *) get_name()->str);
- return_val= TRUE; /* server is alive */
- }
- else
- return_val= test(!strncmp(access_denied_message, mysql_error(&mysql),
- sizeof(access_denied_message) - 1));
-
- mysql_close(&mysql);
-
- return return_val;
-}
-
-
-/**
- @brief Start mysqld.
-
- Reset flags and start Instance Monitor thread, which will start mysqld.
-
- @note Instance must be locked before calling the operation.
-
- @return Error status code
- @retval FALSE Ok
- @retval TRUE Could not start instance
-*/
-
-bool Instance::start_mysqld()
-{
- Instance_monitor *instance_monitor;
-
- if (!configured)
- return TRUE;
-
- /*
- Prepare instance to start Instance Monitor thread.
-
- NOTE: It's important to set these actions here in order to avoid
- race conditions -- these actions must be done under acquired lock on
- Instance.
- */
-
- crashed= FALSE;
- monitoring_thread_active= TRUE;
-
- remove_pid();
-
- /* Create and start the Instance Monitor thread. */
-
- instance_monitor= new Instance_monitor(this);
-
- if (instance_monitor == NULL || instance_monitor->start(Thread::DETACHED))
- {
- delete instance_monitor;
- monitoring_thread_active= FALSE;
-
- log_error("Instance '%s': can not create instance monitor thread.",
- (const char *) get_name()->str);
-
- return TRUE;
- }
-
- ++restart_counter;
-
- /* The Instance Monitor thread will delete itself when it's finished. */
-
- return FALSE;
-}
-
-
-/**
- Stop mysqld.
-
- SYNOPSIS
- stop_mysqld()
-
- DESCRIPTION
- Try to stop mysqld gracefully. Otherwise kill it with SIGKILL.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- RETURN
- FALSE - ok
- TRUE - could not stop the instance
-*/
-
-bool Instance::stop_mysqld()
-{
- log_info("Instance '%s': stopping mysqld...",
- (const char *) get_name()->str);
-
- kill_mysqld(SIGTERM);
-
- if (!wait_for_stop())
- {
- log_info("Instance '%s': mysqld stopped gracefully.",
- (const char *) get_name()->str);
- return FALSE;
- }
-
- log_info("Instance '%s': mysqld failed to stop gracefully within %d seconds.",
- (const char *) get_name()->str,
- (int) options.get_shutdown_delay());
-
- log_info("Instance'%s': killing mysqld...",
- (const char *) get_name()->str);
-
- kill_mysqld(SIGKILL);
-
- if (!wait_for_stop())
- {
- log_info("Instance '%s': mysqld has been killed.",
- (const char *) get_name()->str);
- return FALSE;
- }
-
- log_info("Instance '%s': can not kill mysqld within %d seconds.",
- (const char *) get_name()->str,
- (int) options.get_shutdown_delay());
-
- return TRUE;
-}
-
-
-/**
- Send signal to mysqld.
-
- SYNOPSIS
- kill_mysqld()
-
- DESCRIPTION
- Load pid from the pid file and send the given signal to that process.
- If the signal is SIGKILL, remove the pid file after sending the signal.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- TODO
- This too low-level and OS-specific operation for public interface.
- Also, it has some implicit behaviour for SIGKILL signal. Probably, we
- should have the following public operations instead:
- - start_mysqld() -- as is;
- - stop_mysqld -- request mysqld to shutdown gracefully (send SIGTERM);
- don't wait for complete shutdown;
- - wait_for_stop() (or join_mysqld()) -- wait for mysqld to stop within
- time interval;
- - kill_mysqld() -- request to terminate mysqld; don't wait for
- completion.
- These operations should also be used in Guardian to manage instances.
-*/
-
-bool Instance::kill_mysqld(int signum)
-{
- pid_t mysqld_pid= options.load_pid();
-
- if (mysqld_pid == 0)
- {
- log_info("Instance '%s': no pid file to send a signal (%d).",
- (const char *) get_name()->str,
- (int) signum);
- return TRUE;
- }
-
- log_info("Instance '%s': sending %d to %d...",
- (const char *) get_name()->str,
- (int) signum,
- (int) mysqld_pid);
-
- if (kill(mysqld_pid, signum))
- {
- log_info("Instance '%s': kill() failed.",
- (const char *) get_name()->str);
- return TRUE;
- }
-
- /* Kill suceeded */
- if (signum == SIGKILL) /* really killed instance with SIGKILL */
- {
- log_error("Instance '%s': killed.",
- (const char *) options.instance_name.str);
-
- /* After sucessful hard kill the pidfile need to be removed */
- options.unlink_pidfile();
- }
-
- return FALSE;
-}
-
-
-/**
- Lock instance.
-*/
-
-void Instance::lock()
-{
- pthread_mutex_lock(&LOCK_instance);
-}
-
-
-/**
- Unlock instance.
-*/
-
-void Instance::unlock()
-{
- pthread_mutex_unlock(&LOCK_instance);
-}
-
-
-/**
- Return instance state name.
-
- SYNOPSIS
- get_state_name()
-
- DESCRIPTION
- The operation returns user-friendly state name. The operation can be
- used both for guarded and non-guarded instances.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- TODO: Replace with the static get_state_name(state_code) function.
-*/
-
-const char *Instance::get_state_name()
-{
- if (!is_configured())
- return "misconfigured";
-
- if (is_guarded())
- {
- /* The instance is managed by Guardian: we can report precise state. */
-
- return get_instance_state_name(get_state());
- }
-
- /* The instance is not managed by Guardian: we can report status only. */
-
- return is_active() ? "online" : "offline";
-}
-
-
-/**
- Reset statistics.
-
- SYNOPSIS
- reset_stat()
-
- DESCRIPTION
- The operation resets statistics used for guarding the instance.
-
- MT-NOTE: instance must be locked before calling the operation.
-
- TODO: Make private.
-*/
-
-void Instance::reset_stat()
-{
- restart_counter= 0;
- crash_moment= 0;
- last_checked= 0;
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
-
-
-/**************************************************************************
- {{{ Instance: implementation of private operations.
-**************************************************************************/
-
-/**
- Remove pid file.
-*/
-
-void Instance::remove_pid()
-{
- int mysqld_pid= options.load_pid();
-
- if (mysqld_pid == 0)
- return;
-
- if (options.unlink_pidfile())
- {
- log_error("Instance '%s': can not unlink pid file.",
- (const char *) options.instance_name.str);
- }
-}
-
-
-/**
- Wait for mysqld to stop within shutdown interval.
-*/
-
-bool Instance::wait_for_stop()
-{
- int start_time= (int) time(NULL);
- int finish_time= start_time + options.get_shutdown_delay();
-
- log_info("Instance '%s': waiting for mysqld to stop "
- "(timeout: %d seconds)...",
- (const char *) get_name()->str,
- (int) options.get_shutdown_delay());
-
- while (true)
- {
- if (options.load_pid() == 0 && !is_mysqld_running())
- return FALSE;
-
- if (time(NULL) >= finish_time)
- return TRUE;
-
- /* Sleep for 0.3 sec and check again. */
-
- my_sleep(300000);
- }
-}
-
-/**************************************************************************
- }}}
-**************************************************************************/
diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h
deleted file mode 100644
index aa9c923cba1..00000000000
--- a/server-tools/instance-manager/instance.h
+++ /dev/null
@@ -1,273 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <m_string.h>
-
-#include "instance_options.h"
-#include "priv.h"
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-class Instance_map;
-class Thread_registry;
-
-
-/**
- Instance_name -- the class represents instance name -- a string of length
- less than MAX_INSTANCE_NAME_SIZE.
-
- Generally, this is just a string with self-memory-management and should be
- eliminated in the future.
-*/
-
-class Instance_name
-{
-public:
- Instance_name(const LEX_STRING *name);
-
-public:
- inline const LEX_STRING *get_str() const
- {
- return &str;
- }
-
- inline const char *get_c_str() const
- {
- return str.str;
- }
-
- inline uint get_length() const
- {
- return str.length;
- }
-
-private:
- LEX_STRING str;
- char str_buffer[MAX_INSTANCE_NAME_SIZE];
-};
-
-
-class Instance
-{
-public:
- /* States of an instance. */
- enum enum_instance_state
- {
- STOPPED,
- NOT_STARTED,
- STARTING,
- STARTED,
- JUST_CRASHED,
- CRASHED,
- CRASHED_AND_ABANDONED,
- STOPPING
- };
-
-public:
- /**
- The constant defines name of the default mysqld-instance ("mysqld").
- */
- static const LEX_STRING DFLT_INSTANCE_NAME;
-
-public:
- static bool is_name_valid(const LEX_STRING *name);
- static bool is_mysqld_compatible_name(const LEX_STRING *name);
-
-public:
- Instance();
- ~Instance();
-
- bool init(const LEX_STRING *name_arg);
- bool complete_initialization();
-
-public:
- bool is_active();
-
- bool is_mysqld_running();
-
- bool start_mysqld();
- bool stop_mysqld();
- bool kill_mysqld(int signo);
-
- void lock();
- void unlock();
-
- const char *get_state_name();
-
- void reset_stat();
-
-public:
- /**
- The operation is intended to check if the instance is mysqld-compatible
- or not.
- */
- inline bool is_mysqld_compatible() const;
-
- /**
- The operation is intended to check if the instance is configured properly
- or not. Misconfigured instances are not managed.
- */
- inline bool is_configured() const;
-
- /**
- The operation returns TRUE if the instance is guarded and FALSE otherwise.
- */
- inline bool is_guarded() const;
-
- /**
- The operation returns name of the instance.
- */
- inline const LEX_STRING *get_name() const;
-
- /**
- The operation returns the current state of the instance.
-
- NOTE: At the moment should be used only for guarded instances.
- */
- inline enum_instance_state get_state() const;
-
- /**
- The operation changes the state of the instance.
-
- NOTE: At the moment should be used only for guarded instances.
- TODO: Make private.
- */
- inline void set_state(enum_instance_state new_state);
-
- /**
- The operation returns crashed flag.
- */
- inline bool is_crashed();
-
-public:
- /**
- This attributes contains instance options.
-
- TODO: Make private.
- */
- Instance_options options;
-
-private:
- /**
- monitoring_thread_active is TRUE if there is a thread that monitors the
- corresponding mysqld-process.
- */
- bool monitoring_thread_active;
-
- /**
- crashed is TRUE when corresponding mysqld-process has been died after
- start.
- */
- bool crashed;
-
- /**
- configured is TRUE when the instance is configured and FALSE otherwise.
- Misconfigured instances are not managed.
- */
- bool configured;
-
- /*
- mysqld_compatible specifies whether the instance is mysqld-compatible
- or not. Mysqld-compatible instances can contain only mysqld-specific
- options. At the moment an instance is mysqld-compatible if its name is
- "mysqld".
-
- The idea is that [mysqld] section should contain only mysqld-specific
- options (no Instance Manager-specific options) to be readable by mysqld
- program.
- */
- bool mysqld_compatible;
-
- /*
- Mutex protecting the instance.
- */
- pthread_mutex_t LOCK_instance;
-
-private:
- /* Guarded-instance attributes. */
-
- /* state of an instance (i.e. STARTED, CRASHED, etc.) */
- enum_instance_state state;
-
-public:
- /* the amount of attemts to restart instance (cleaned up at success) */
- int restart_counter;
-
- /* triggered at a crash */
- time_t crash_moment;
-
- /* General time field. Used to provide timeouts (at shutdown and restart) */
- time_t last_checked;
-
-private:
- static const char *get_instance_state_name(enum_instance_state state);
-
-private:
- void remove_pid();
-
- bool wait_for_stop();
-
-private:
- friend class Instance_monitor;
-};
-
-
-inline bool Instance::is_mysqld_compatible() const
-{
- return mysqld_compatible;
-}
-
-
-inline bool Instance::is_configured() const
-{
- return configured;
-}
-
-
-inline bool Instance::is_guarded() const
-{
- return !options.nonguarded;
-}
-
-
-inline const LEX_STRING *Instance::get_name() const
-{
- return &options.instance_name;
-}
-
-
-inline Instance::enum_instance_state Instance::get_state() const
-{
- return state;
-}
-
-
-inline void Instance::set_state(enum_instance_state new_state)
-{
- state= new_state;
-}
-
-
-inline bool Instance::is_crashed()
-{
- return crashed;
-}
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H */
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
deleted file mode 100644
index b137370b50a..00000000000
--- a/server-tools/instance-manager/instance_map.cc
+++ /dev/null
@@ -1,649 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "instance_map.h"
-
-#include <my_global.h>
-#include <m_ctype.h>
-#include <mysql_com.h>
-
-#include "buffer.h"
-#include "instance.h"
-#include "log.h"
-#include "mysqld_error.h"
-#include "mysql_manager_error.h"
-#include "options.h"
-#include "priv.h"
-
-C_MODE_START
-
-/**
- HASH-routines: get key of instance for storing in hash.
-*/
-
-static uchar* get_instance_key(const uchar* u, size_t* len,
- my_bool __attribute__((unused)) t)
-{
- const Instance *instance= (const Instance *) u;
- *len= instance->options.instance_name.length;
- return (uchar *) instance->options.instance_name.str;
-}
-
-/**
- HASH-routines: cleanup handler.
-*/
-
-static void delete_instance(void *u)
-{
- Instance *instance= (Instance *) u;
- delete instance;
-}
-
-/**
- The option handler to pass to the process_default_option_files function.
-
- SYNOPSIS
- process_option()
- ctx Handler context. Here it is an instance_map structure.
- group_name The name of the group the option belongs to.
- option The very option to be processed. It is already
- prepared to be used in argv (has -- prefix)
-
- DESCRIPTION
-
- This handler checks whether a group is an instance group and adds
- an option to the appropriate instance class. If this is the first
- occurence of an instance name, we'll also create the instance
- with such name and add it to the instance map.
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-static int process_option(void *ctx, const char *group, const char *option)
-{
- Instance_map *map= (Instance_map*) ctx;
- LEX_STRING group_str;
-
- group_str.str= (char *) group;
- group_str.length= strlen(group);
-
- return map->process_one_option(&group_str, option);
-}
-
-C_MODE_END
-
-
-/**
- Parse option string.
-
- SYNOPSIS
- parse_option()
- option_str [IN] option string (e.g. "--name=value")
- option_name_buf [OUT] parsed name of the option.
- Must be of (MAX_OPTION_LEN + 1) size.
- option_value_buf [OUT] parsed value of the option.
- Must be of (MAX_OPTION_LEN + 1) size.
-
- DESCRIPTION
- This is an auxiliary function and should not be used externally. It is
- intended to parse whole option string into option name and option value.
-*/
-
-static void parse_option(const char *option_str,
- char *option_name_buf,
- char *option_value_buf)
-{
- const char *eq_pos;
- const char *ptr= option_str;
-
- while (*ptr == '-')
- ++ptr;
-
- strmake(option_name_buf, ptr, MAX_OPTION_LEN + 1);
-
- eq_pos= strchr(ptr, '=');
- if (eq_pos)
- {
- option_name_buf[eq_pos - ptr]= 0;
- strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN + 1);
- }
- else
- {
- option_value_buf[0]= 0;
- }
-}
-
-
-/**
- Process one option from the configuration file.
-
- SYNOPSIS
- Instance_map::process_one_option()
- group group name
- option option string (e.g. "--name=value")
-
- DESCRIPTION
- This is an auxiliary function and should not be used externally.
- It is used only by flush_instances(), which pass it to
- process_option(). The caller ensures proper locking
- of the instance map object.
-*/
- /*
- Process a given option and assign it to appropricate instance. This is
- required for the option handler, passed to my_search_option_files().
- */
-
-int Instance_map::process_one_option(const LEX_STRING *group,
- const char *option)
-{
- Instance *instance= NULL;
-
- if (!Instance::is_name_valid(group))
- {
- /*
- Current section name is not a valid instance name.
- We should skip it w/o error.
- */
- return 0;
- }
-
- if (!(instance= (Instance *) hash_search(&hash, (uchar *) group->str,
- group->length)))
- {
- if (!(instance= new Instance()))
- return 1;
-
- if (instance->init(group) || add_instance(instance))
- {
- delete instance;
- return 1;
- }
-
- if (instance->is_mysqld_compatible())
- log_info("Warning: instance name '%s' is mysqld-compatible.",
- (const char *) group->str);
-
- log_info("mysqld instance '%s' has been added successfully.",
- (const char *) group->str);
- }
-
- if (option)
- {
- char option_name[MAX_OPTION_LEN + 1];
- char option_value[MAX_OPTION_LEN + 1];
-
- parse_option(option, option_name, option_value);
-
- if (instance->is_mysqld_compatible() &&
- Instance_options::is_option_im_specific(option_name))
- {
- log_info("Warning: configuration of mysqld-compatible instance '%s' "
- "contains IM-specific option '%s'. "
- "This breaks backward compatibility for the configuration file.",
- (const char *) group->str,
- (const char *) option_name);
- }
-
- Named_value option(option_name, option_value);
-
- if (instance->options.set_option(&option))
- return 1; /* the instance'll be deleted when we destroy the map */
- }
-
- return 0;
-}
-
-
-/**
- Instance_map constructor.
-*/
-
-Instance_map::Instance_map()
-{
- pthread_mutex_init(&LOCK_instance_map, 0);
-}
-
-
-/**
- Initialize Instance_map internals.
-*/
-
-bool Instance_map::init()
-{
- return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
- get_instance_key, delete_instance, 0);
-}
-
-
-/**
- Reset Instance_map data.
-*/
-
-bool Instance_map::reset()
-{
- hash_free(&hash);
- return init();
-}
-
-
-/**
- Instance_map destructor.
-*/
-
-Instance_map::~Instance_map()
-{
- lock();
-
- /*
- NOTE: it's necessary to synchronize on each instance before removal,
- because Instance-monitoring thread can be still alive an hold the mutex
- (because it is detached and we have no control over it).
- */
-
- while (true)
- {
- Iterator it(this);
- Instance *instance= it.next();
-
- if (!instance)
- break;
-
- instance->lock();
- instance->unlock();
-
- remove_instance(instance);
- }
-
- hash_free(&hash);
- unlock();
-
- pthread_mutex_destroy(&LOCK_instance_map);
-}
-
-
-/**
- Lock Instance_map.
-*/
-
-void Instance_map::lock()
-{
- pthread_mutex_lock(&LOCK_instance_map);
-}
-
-
-/**
- Unlock Instance_map.
-*/
-
-void Instance_map::unlock()
-{
- pthread_mutex_unlock(&LOCK_instance_map);
-}
-
-
-/**
- Check if there is an active instance or not.
-*/
-
-bool Instance_map::is_there_active_instance()
-{
- Instance *instance;
- Iterator iterator(this);
-
- while ((instance= iterator.next()))
- {
- bool active_instance_found;
-
- instance->lock();
- active_instance_found= instance->is_active();
- instance->unlock();
-
- if (active_instance_found)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/**
- Add an instance into the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::add_instance(Instance *instance)
-{
- return my_hash_insert(&hash, (uchar *) instance);
-}
-
-
-/**
- Remove instance from the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::remove_instance(Instance *instance)
-{
- return hash_delete(&hash, (uchar *) instance);
-}
-
-
-/**
- Create a new instance and register it in the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::create_instance(const LEX_STRING *instance_name,
- const Named_value_arr *options)
-{
- Instance *instance= new Instance();
-
- if (!instance)
- {
- log_error("Can not allocate instance (name: '%s').",
- (const char *) instance_name->str);
- return ER_OUT_OF_RESOURCES;
- }
-
- if (instance->init(instance_name))
- {
- log_error("Can not initialize instance (name: '%s').",
- (const char *) instance_name->str);
- delete instance;
- return ER_OUT_OF_RESOURCES;
- }
-
- for (int i= 0; options && i < options->get_size(); ++i)
- {
- Named_value option= options->get_element(i);
-
- if (instance->is_mysqld_compatible() &&
- Instance_options::is_option_im_specific(option.get_name()))
- {
- log_error("IM-option (%s) can not be used "
- "in configuration of mysqld-compatible instance (%s).",
- (const char *) option.get_name(),
- (const char *) instance_name->str);
- delete instance;
- return ER_INCOMPATIBLE_OPTION;
- }
-
- instance->options.set_option(&option);
- }
-
- if (instance->is_mysqld_compatible())
- log_info("Warning: instance name '%s' is mysqld-compatible.",
- (const char *) instance_name->str);
-
- if (instance->complete_initialization())
- {
- log_error("Can not complete initialization of instance (name: '%s').",
- (const char *) instance_name->str);
- delete instance;
- return ER_OUT_OF_RESOURCES;
- /* TODO: return more appropriate error code in this case. */
- }
-
- if (add_instance(instance))
- {
- log_error("Can not register instance (name: '%s').",
- (const char *) instance_name->str);
- delete instance;
- return ER_OUT_OF_RESOURCES;
- }
-
- return 0;
-}
-
-
-/**
- Return a pointer to the instance or NULL, if there is no such instance.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-Instance * Instance_map::find(const LEX_STRING *name)
-{
- return (Instance *) hash_search(&hash, (uchar *) name->str, name->length);
-}
-
-
-/**
- Init instances command line arguments after all options have been loaded.
-*/
-
-bool Instance_map::complete_initialization()
-{
- bool mysqld_found;
-
- /* Complete initialization of all registered instances. */
-
- for (uint i= 0; i < hash.records; ++i)
- {
- Instance *instance= (Instance *) hash_element(&hash, i);
-
- if (instance->complete_initialization())
- return TRUE;
- }
-
- /* That's all if we are runnning in an ordinary mode. */
-
- if (!Options::Main::mysqld_safe_compatible)
- return FALSE;
-
- /* In mysqld-compatible mode we must ensure that there 'mysqld' instance. */
-
- mysqld_found= find(&Instance::DFLT_INSTANCE_NAME) != NULL;
-
- if (mysqld_found)
- return FALSE;
-
- if (create_instance(&Instance::DFLT_INSTANCE_NAME, NULL))
- {
- log_error("Can not create default instance.");
- return TRUE;
- }
-
- switch (create_instance_in_file(&Instance::DFLT_INSTANCE_NAME, NULL))
- {
- case 0:
- case ER_CONF_FILE_DOES_NOT_EXIST:
- /*
- Continue if the instance has been added to the config file
- successfully, or the config file just does not exist.
- */
- break;
-
- default:
- log_error("Can not add default instance to the config file.");
-
- Instance *instance= find(&Instance::DFLT_INSTANCE_NAME);
-
- if (instance)
- remove_instance(instance); /* instance is deleted here. */
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/**
- Load options from config files and create appropriate instance
- structures.
-*/
-
-int Instance_map::load()
-{
- int argc= 1;
- /* this is a dummy variable for search_option_files() */
- uint args_used= 0;
- const char *argv_options[3];
- char **argv= (char **) &argv_options;
- char defaults_file_arg[FN_REFLEN];
-
- /* the name of the program may be orbitrary here in fact */
- argv_options[0]= "mysqlmanager";
-
- /*
- If the option file was forced by the user when starting
- the IM with --defaults-file=xxxx, make sure it is also
- passed as --defaults-file, not only as Options::config_file.
- This is important for option files given with relative path:
- e.g. --defaults-file=my.cnf.
- Otherwise my_search_option_files will treat "my.cnf" as a group
- name and start looking for files named "my.cnf.cnf" in all
- default dirs. Which is not what we want.
- */
- if (Options::Main::is_forced_default_file)
- {
- snprintf(defaults_file_arg, FN_REFLEN, "--defaults-file=%s",
- Options::Main::config_file);
-
- argv_options[1]= defaults_file_arg;
- argv_options[2]= '\0';
-
- argc= 2;
- }
- else
- argv_options[1]= '\0';
-
- /*
- If the routine failed, we'll simply fallback to defaults in
- complete_initialization().
- */
- if (my_search_option_files(Options::Main::config_file, &argc,
- (char ***) &argv, &args_used,
- process_option, (void*) this,
- Options::default_directories))
- log_info("Falling back to compiled-in defaults.");
-
- return complete_initialization();
-}
-
-
-/*************************************************************************
- {{{ Instance_map::Iterator implementation.
-*************************************************************************/
-
-void Instance_map::Iterator::go_to_first()
-{
- current_instance=0;
-}
-
-
-Instance *Instance_map::Iterator::next()
-{
- if (current_instance < instance_map->hash.records)
- return (Instance *) hash_element(&instance_map->hash, current_instance++);
-
- return NULL;
-}
-
-/*************************************************************************
- }}}
-*************************************************************************/
-
-
-/**
- Create a new configuration section for mysqld-instance in the config file.
-
- SYNOPSIS
- create_instance_in_file()
- instance_name mysqld-instance name
- options options for the new mysqld-instance
-
- RETURN
- 0 On success
- ER_CONF_FILE_DOES_NOT_EXIST If config file does not exist
- ER_ACCESS_OPTION_FILE If config file is not writable or some I/O
- error ocurred during writing configuration
-*/
-
-int create_instance_in_file(const LEX_STRING *instance_name,
- const Named_value_arr *options)
-{
- File cnf_file;
-
- if (my_access(Options::Main::config_file, W_OK))
- {
- log_error("Configuration file (%s) does not exist.",
- (const char *) Options::Main::config_file);
- return ER_CONF_FILE_DOES_NOT_EXIST;
- }
-
- cnf_file= my_open(Options::Main::config_file, O_WRONLY | O_APPEND, MYF(0));
-
- if (cnf_file <= 0)
- {
- log_error("Can not open configuration file (%s): %s.",
- (const char *) Options::Main::config_file,
- (const char *) strerror(errno));
- return ER_ACCESS_OPTION_FILE;
- }
-
- if (my_write(cnf_file, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)"[", 1, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)instance_name->str, instance_name->length,
- MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)"]", 1, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
- {
- log_error("Can not write to configuration file (%s): %s.",
- (const char *) Options::Main::config_file,
- (const char *) strerror(errno));
- my_close(cnf_file, MYF(0));
- return ER_ACCESS_OPTION_FILE;
- }
-
- for (int i= 0; options && i < options->get_size(); ++i)
- {
- char option_str[MAX_OPTION_STR_LEN];
- char *ptr;
- int option_str_len;
- Named_value option= options->get_element(i);
-
- ptr= strxnmov(option_str, MAX_OPTION_LEN + 1, option.get_name(), NullS);
-
- if (option.get_value()[0])
- ptr= strxnmov(ptr, MAX_OPTION_LEN + 2, "=", option.get_value(), NullS);
-
- option_str_len= ptr - option_str;
-
- if (my_write(cnf_file, (uchar*)option_str, option_str_len, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
- {
- log_error("Can not write to configuration file (%s): %s.",
- (const char *) Options::Main::config_file,
- (const char *) strerror(errno));
- my_close(cnf_file, MYF(0));
- return ER_ACCESS_OPTION_FILE;
- }
- }
-
- my_close(cnf_file, MYF(0));
-
- return 0;
-}
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
deleted file mode 100644
index af2f1868195..00000000000
--- a/server-tools/instance-manager/instance_map.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <hash.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-class Guardian;
-class Instance;
-class Named_value_arr;
-class Thread_registry;
-
-extern int load_all_groups(char ***groups, const char *filename);
-extern void free_groups(char **groups);
-
-extern int create_instance_in_file(const LEX_STRING *instance_name,
- const Named_value_arr *options);
-
-
-/**
- Instance_map - stores all existing instances
-*/
-
-class Instance_map
-{
-public:
- /**
- Instance_map iterator
- */
-
- class Iterator
- {
- private:
- uint current_instance;
- Instance_map *instance_map;
- public:
- Iterator(Instance_map *instance_map_arg) :
- current_instance(0), instance_map(instance_map_arg)
- {}
-
- void go_to_first();
- Instance *next();
- };
-
-public:
- Instance *find(const LEX_STRING *name);
-
- bool is_there_active_instance();
-
- void lock();
- void unlock();
-
- bool init();
- bool reset();
-
- int load();
-
- int process_one_option(const LEX_STRING *group, const char *option);
-
- int add_instance(Instance *instance);
-
- int remove_instance(Instance *instance);
-
- int create_instance(const LEX_STRING *instance_name,
- const Named_value_arr *options);
-
-public:
- Instance_map();
- ~Instance_map();
-
-private:
- bool complete_initialization();
-
-private:
- enum { START_HASH_SIZE = 16 };
- pthread_mutex_t LOCK_instance_map;
- HASH hash;
-
-private:
- friend class Iterator;
-};
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H */
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
deleted file mode 100644
index 8b96d6f0f96..00000000000
--- a/server-tools/instance-manager/instance_options.cc
+++ /dev/null
@@ -1,753 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "instance_options.h"
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-
-#include <signal.h>
-
-#include "buffer.h"
-#include "instance.h"
-#include "log.h"
-#include "options.h"
-#include "parse_output.h"
-#include "priv.h"
-
-
-/* Create "mysqld ..." command in the buffer */
-
-static inline bool create_mysqld_command(Buffer *buf,
- const LEX_STRING *mysqld_path,
- const LEX_STRING *option)
-{
- int position= 0;
-
- if (buf->get_size()) /* malloc succeeded */
- {
-#ifdef __WIN__
- buf->append(position++, "\"", 1);
-#endif
- buf->append(position, mysqld_path->str, mysqld_path->length);
- position+= mysqld_path->length;
-#ifdef __WIN__
- buf->append(position++, "\"", 1);
-#endif
- /* here the '\0' character is copied from the option string */
- buf->append(position, option->str, option->length + 1);
-
- return buf->is_error() ? TRUE : FALSE;
- }
- return TRUE;
-}
-
-static inline bool is_path_separator(char ch)
-{
-#if defined(__WIN__) || defined(__NETWARE__)
- /* On windows and netware more delimiters are possible */
- return ch == FN_LIBCHAR || ch == FN_DEVCHAR || ch == '/';
-#else
- return ch == FN_LIBCHAR; /* Unixes */
-#endif
-}
-
-
-static char *find_last_path_separator(char *path, uint length)
-{
- while (length)
- {
- if (is_path_separator(path[length]))
- return path + length;
- length--;
- }
- return NULL; /* No path separator found */
-}
-
-
-
-bool Instance_options::is_option_im_specific(const char *option_name)
-{
- static const char *IM_SPECIFIC_OPTIONS[] =
- {
- "nonguarded",
- "mysqld-path",
- "shutdown-delay",
- NULL
- };
-
- for (int i= 0; IM_SPECIFIC_OPTIONS[i]; ++i)
- {
- if (!strcmp(option_name, IM_SPECIFIC_OPTIONS[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-Instance_options::Instance_options()
- :mysqld_version(NULL), mysqld_socket(NULL), mysqld_datadir(NULL),
- mysqld_pid_file(NULL),
- nonguarded(NULL),
- mysqld_port(NULL),
- mysqld_port_val(0),
- shutdown_delay(NULL),
- shutdown_delay_val(0),
- filled_default_options(0)
-{
- mysqld_path.str= NULL;
- mysqld_path.length= 0;
-
- mysqld_real_path.str= NULL;
- mysqld_real_path.length= 0;
-
- memset(logs, 0, sizeof(logs));
-}
-
-
-/*
- Get compiled-in value of default_option
-
- SYNOPSIS
- get_default_option()
- result buffer to put found value
- result_len buffer size
- option_name the name of the option, prefixed with "--"
-
- DESCRIPTION
-
- Get compile-in value of requested option from server
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-
-int Instance_options::get_default_option(char *result, size_t result_len,
- const char *option_name)
-{
- int rc= 1;
- LEX_STRING verbose_option=
- { C_STRING_WITH_LEN(" --no-defaults --verbose --help") };
-
- /* reserve space for the path + option + final '\0' */
- Buffer cmd(mysqld_path.length + verbose_option.length + 1);
-
- if (create_mysqld_command(&cmd, &mysqld_path, &verbose_option))
- goto err;
-
- /* +2 eats first "--" from the option string (E.g. "--datadir") */
- rc= parse_output_and_get_value((char*) cmd.buffer,
- option_name + 2, strlen(option_name + 2),
- result, result_len, GET_VALUE);
-err:
- return rc;
-}
-
-
-/*
- Fill mysqld_version option (used at initialization stage)
-
- SYNOPSIS
- fill_instance_version()
-
- DESCRIPTION
-
- Get mysqld version string from "mysqld --version" output.
-
- RETURN
- FALSE - ok
- TRUE - error occured
-*/
-
-bool Instance_options::fill_instance_version()
-{
- char result[MAX_VERSION_LENGTH];
- LEX_STRING version_option=
- { C_STRING_WITH_LEN(" --no-defaults --version") };
- Buffer cmd(mysqld_path.length + version_option.length + 1);
-
- if (create_mysqld_command(&cmd, &mysqld_path, &version_option))
- {
- log_error("Failed to get version of '%s': out of memory.",
- (const char *) mysqld_path.str);
- return TRUE;
- }
-
- bzero(result, MAX_VERSION_LENGTH);
-
- if (parse_output_and_get_value((char*) cmd.buffer, STRING_WITH_LEN("Ver"),
- result, MAX_VERSION_LENGTH, GET_LINE))
- {
- log_error("Failed to get version of '%s': unexpected output.",
- (const char *) mysqld_path.str);
- return TRUE;
- }
-
- DBUG_ASSERT(*result != '\0');
-
- {
- char *start;
-
- /* trim leading whitespaces */
- start= result;
- while (my_isspace(default_charset_info, *start))
- ++start;
-
- mysqld_version= strdup_root(&alloc, start);
- }
-
- return FALSE;
-}
-
-
-/*
- Fill mysqld_real_path
-
- SYNOPSIS
- fill_mysqld_real_path()
-
- DESCRIPTION
-
- Get the real path to mysqld from "mysqld --help" output.
- Will print the realpath of mysqld between "Usage: " and "[OPTIONS]"
-
- This is needed if the mysqld_path variable is pointing at a
- script(for example libtool) or a symlink.
-
- RETURN
- FALSE - ok
- TRUE - error occured
-*/
-
-bool Instance_options::fill_mysqld_real_path()
-{
- char result[FN_REFLEN];
- LEX_STRING help_option=
- { C_STRING_WITH_LEN(" --no-defaults --help") };
- Buffer cmd(mysqld_path.length + help_option.length);
-
- if (create_mysqld_command(&cmd, &mysqld_path, &help_option))
- {
- log_error("Failed to get real path of '%s': out of memory.",
- (const char *) mysqld_path.str);
- return TRUE;
- }
-
- bzero(result, FN_REFLEN);
-
- if (parse_output_and_get_value((char*) cmd.buffer,
- STRING_WITH_LEN("Usage: "),
- result, FN_REFLEN,
- GET_LINE))
- {
- log_error("Failed to get real path of '%s': unexpected output.",
- (const char *) mysqld_path.str);
- return TRUE;
- }
-
- DBUG_ASSERT(*result != '\0');
-
- {
- char* options_str;
- /* chop the path of at [OPTIONS] */
- if ((options_str= strstr(result, "[OPTIONS]")))
- *options_str= '\0';
- mysqld_real_path.str= strdup_root(&alloc, result);
- mysqld_real_path.length= strlen(mysqld_real_path.str);
- }
-
- return FALSE;
-}
-
-
-/*
- Fill various log options
-
- SYNOPSIS
- fill_log_options()
-
- DESCRIPTION
-
- Compute paths to enabled log files. If the path is not specified in the
- instance explicitly (I.e. log=/home/user/mysql.log), we try to guess the
- file name and placement.
-
- RETURN
- FALSE - ok
- TRUE - error occured
-*/
-
-bool Instance_options::fill_log_options()
-{
- Buffer buff;
- enum { MAX_LOG_OPTION_LENGTH= 256 };
- char datadir[MAX_LOG_OPTION_LENGTH];
- char hostname[MAX_LOG_OPTION_LENGTH];
- uint hostname_length;
- struct log_files_st
- {
- const char *name;
- uint length;
- char **value;
- const char *default_suffix;
- } logs_st[]=
- {
- {"--log-error", 11, &(logs[IM_LOG_ERROR]), ".err"},
- {"--log", 5, &(logs[IM_LOG_GENERAL]), ".log"},
- {"--log-slow-queries", 18, &(logs[IM_LOG_SLOW]), "-slow.log"},
- {NULL, 0, NULL, NULL}
- };
- struct log_files_st *log_files;
-
- /* compute hostname and datadir for the instance */
- if (mysqld_datadir == NULL)
- {
- if (get_default_option(datadir, MAX_LOG_OPTION_LENGTH, "--datadir"))
- return TRUE;
- }
- else
- {
- /* below is safe, as --datadir always has a value */
- strmake(datadir, mysqld_datadir, MAX_LOG_OPTION_LENGTH - 1);
- }
-
- if (gethostname(hostname,sizeof(hostname)-1) < 0)
- strmov(hostname, "mysql");
-
- hostname[MAX_LOG_OPTION_LENGTH - 1]= 0; /* Safety */
- hostname_length= strlen(hostname);
-
-
- for (log_files= logs_st; log_files->name; log_files++)
- {
- for (int i=0; (argv[i] != 0); i++)
- {
- if (!strncmp(argv[i], log_files->name, log_files->length))
- {
- /*
- This is really log_files->name option if and only if it is followed
- by '=', '\0' or space character. This way we can distinguish such
- options as '--log' and '--log-bin'. This is checked in the following
- two statements.
- */
- if (argv[i][log_files->length] == '\0' ||
- my_isspace(default_charset_info, argv[i][log_files->length]))
- {
- char full_name[MAX_LOG_OPTION_LENGTH];
-
- fn_format(full_name, hostname, datadir, "",
- MY_UNPACK_FILENAME | MY_SAFE_PATH);
-
-
- if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) <=
- strlen(log_files->default_suffix))
- return TRUE;
-
- strmov(full_name + strlen(full_name), log_files->default_suffix);
-
- /*
- If there were specified two identical logfiles options,
- we would loose some memory in MEM_ROOT here. However
- this situation is not typical.
- */
- *(log_files->value)= strdup_root(&alloc, full_name);
- }
-
- if (argv[i][log_files->length] == '=')
- {
- char full_name[MAX_LOG_OPTION_LENGTH];
-
- fn_format(full_name, argv[i] +log_files->length + 1,
- datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH);
-
- if (!(*(log_files->value)= strdup_root(&alloc, full_name)))
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
-}
-
-
-/*
- Get the full pid file name with path
-
- SYNOPSIS
- get_pid_filaname()
- result buffer to sotre the pidfile value
-
- IMPLEMENTATION
- Get the data directory, then get the pid filename
- (which is always set for an instance), then load the
- full path with my_load_path(). It takes into account
- whether it is already an absolute path or it should be
- prefixed with the datadir and so on.
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-int Instance_options::get_pid_filename(char *result)
-{
- char datadir[MAX_PATH_LEN];
-
- if (mysqld_datadir == NULL)
- {
- /* we might get an error here if we have wrong path to the mysqld binary */
- if (get_default_option(datadir, sizeof(datadir), "--datadir"))
- return 1;
- }
- else
- strxnmov(datadir, MAX_PATH_LEN - 1, mysqld_datadir, "/", NullS);
-
- /* get the full path to the pidfile */
- my_load_path(result, mysqld_pid_file, datadir);
- return 0;
-}
-
-
-int Instance_options::unlink_pidfile()
-{
- return unlink(pid_file_with_path);
-}
-
-
-pid_t Instance_options::load_pid()
-{
- FILE *pid_file_stream;
-
- /* get the pid */
- if ((pid_file_stream= my_fopen(pid_file_with_path,
- O_RDONLY | O_BINARY, MYF(0))) != NULL)
- {
- pid_t pid;
-
- if (fscanf(pid_file_stream, "%i", &pid) != 1)
- pid= -1;
- my_fclose(pid_file_stream, MYF(0));
- return pid;
- }
- return 0;
-}
-
-
-bool Instance_options::complete_initialization()
-{
- int arg_idx;
- const char *tmp;
- char *end;
- char bin_name_firstchar;
-
- if (!mysqld_path.str)
- {
- /*
- Need to copy the path to allocated memory, as convert_dirname() might
- need to change it
- */
- mysqld_path.str= strdup_root(&alloc, Options::Main::default_mysqld_path);
- if (!mysqld_path.str)
- return TRUE;
- }
-
- mysqld_path.length= strlen(mysqld_path.str);
-
- /*
- If we found path with no slashes (end == NULL), we should not call
- convert_dirname() at all. As we have got relative path to the binary.
- That is, user supposes that mysqld resides in the same dir as
- mysqlmanager.
- */
- if ((end= find_last_path_separator(mysqld_path.str, mysqld_path.length)))
- {
- bin_name_firstchar= end[1];
-
- /*
- Below we will conver the path to mysqld in the case, it was given
- in a format of another OS (e.g. uses '/' instead of '\' etc).
- Here we strip the path to get rid of the binary name ("mysqld"),
- we do it by removing first letter of the binary name (e.g. 'm'
- in "mysqld"). Later we put it back.
- */
- end[1]= 0;
-
- /* convert dirname to the format of current OS */
- convert_dirname((char*)mysqld_path.str, mysqld_path.str, NullS);
-
- /* put back the first character of the binary name*/
- end[1]= bin_name_firstchar;
- }
-
- if (mysqld_port)
- mysqld_port_val= atoi(mysqld_port);
-
- if (shutdown_delay)
- shutdown_delay_val= atoi(shutdown_delay);
-
- if (!(tmp= strdup_root(&alloc, "--no-defaults")))
- return TRUE;
-
- if (!mysqld_pid_file)
- {
- char pidfilename[MAX_PATH_LEN];
- char hostname[MAX_PATH_LEN];
-
- /*
- If we created only one istance [mysqld], because no config. files were
- found, we would like to model mysqld pid file values.
- */
-
- if (!gethostname(hostname, sizeof(hostname) - 1))
- {
- if (Instance::is_mysqld_compatible_name(&instance_name))
- strxnmov(pidfilename, MAX_PATH_LEN - 1, hostname, ".pid", NullS);
- else
- strxnmov(pidfilename, MAX_PATH_LEN - 1, instance_name.str, "-",
- hostname, ".pid", NullS);
- }
- else
- {
- if (Instance::is_mysqld_compatible_name(&instance_name))
- strxnmov(pidfilename, MAX_PATH_LEN - 1, "mysql", ".pid", NullS);
- else
- strxnmov(pidfilename, MAX_PATH_LEN - 1, instance_name.str, ".pid",
- NullS);
- }
-
- Named_value option((char *) "pid-file", pidfilename);
-
- set_option(&option);
- }
-
- if (get_pid_filename(pid_file_with_path))
- return TRUE;
-
- /* we need to reserve space for the final zero + possible default options */
- if (!(argv= (char**)
- alloc_root(&alloc, (get_num_options() + 1
- + MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
- return TRUE;
- filled_default_options= 0;
-
- /* the path must be first in the argv */
- if (add_to_argv(mysqld_path.str))
- return TRUE;
-
- if (add_to_argv(tmp))
- return TRUE;
-
- arg_idx= filled_default_options;
- for (int opt_idx= 0; opt_idx < get_num_options(); ++opt_idx)
- {
- char option_str[MAX_OPTION_STR_LEN];
- Named_value option= get_option(opt_idx);
-
- if (is_option_im_specific(option.get_name()))
- continue;
-
- char *ptr= strxnmov(option_str, MAX_OPTION_LEN + 3, "--", option.get_name(),
- NullS);
-
- if (option.get_value()[0])
- strxnmov(ptr, MAX_OPTION_LEN + 2, "=", option.get_value(), NullS);
-
- argv[arg_idx++]= strdup_root(&alloc, option_str);
- }
-
- argv[arg_idx]= 0;
-
- if (fill_log_options() || fill_mysqld_real_path() || fill_instance_version())
- return TRUE;
-
- return FALSE;
-}
-
-
-bool Instance_options::set_option(Named_value *option)
-{
- bool err_status;
- int idx= find_option(option->get_name());
- char *option_name_str;
- char *option_value_str;
-
- if (!(option_name_str= Named_value::alloc_str(option->get_name())))
- return TRUE;
-
- if (!(option_value_str= Named_value::alloc_str(option->get_value())))
- {
- Named_value::free_str(&option_name_str);
- return TRUE;
- }
-
- Named_value option_copy(option_name_str, option_value_str);
-
- if (idx < 0)
- err_status= options.add_element(&option_copy);
- else
- err_status= options.replace_element(idx, &option_copy);
-
- if (!err_status)
- update_var(option_copy.get_name(), option_copy.get_value());
- else
- option_copy.free();
-
- return err_status;
-}
-
-
-void Instance_options::unset_option(const char *option_name)
-{
- int idx= find_option(option_name);
-
- if (idx < 0)
- return; /* the option has not been set. */
-
- options.remove_element(idx);
-
- update_var(option_name, NULL);
-}
-
-
-void Instance_options::update_var(const char *option_name,
- const char *option_value)
-{
- struct options_st
- {
- const char *name;
- uint name_len;
- const char **var;
- } options_def[]=
- {
- {"socket", 6, &mysqld_socket},
- {"port", 4, &mysqld_port},
- {"datadir", 7, &mysqld_datadir},
- {"pid-file", 8, &mysqld_pid_file},
- {"nonguarded", 10, &nonguarded},
- {"mysqld-path", 11, (const char **) &mysqld_path.str},
- {"shutdown-delay", 14, &shutdown_delay},
- {NULL, 0, NULL}
- };
-
- for (options_st *opt= options_def; opt->name; ++opt)
- {
- if (!strncmp(opt->name, option_name, opt->name_len))
- {
- *(opt->var)= option_value;
- break;
- }
- }
-}
-
-
-int Instance_options::find_option(const char *option_name)
-{
- for (int i= 0; i < get_num_options(); i++)
- {
- if (!strcmp(get_option(i).get_name(), option_name))
- return i;
- }
-
- return -1;
-}
-
-
-int Instance_options::add_to_argv(const char* option)
-{
- DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS);
-
- if (option)
- argv[filled_default_options++]= (char*) option;
- return 0;
-}
-
-
-/* function for debug purposes */
-void Instance_options::print_argv()
-{
- int i;
-
- printf("printing out an instance %s argv:\n",
- (const char *) instance_name.str);
-
- for (i=0; argv[i] != NULL; i++)
- printf("argv: %s\n", argv[i]);
-}
-
-
-/*
- We execute this function to initialize some options.
-
- RETURN
- FALSE - ok
- TRUE - memory allocation error
-*/
-
-bool Instance_options::init(const LEX_STRING *instance_name_arg)
-{
- instance_name.length= instance_name_arg->length;
-
- init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
-
- if (options.init())
- return TRUE;
-
- if (!(instance_name.str= strmake_root(&alloc, instance_name_arg->str,
- instance_name_arg->length)))
- return TRUE;
-
- return FALSE;
-}
-
-
-Instance_options::~Instance_options()
-{
- free_root(&alloc, MYF(0));
-}
-
-
-uint Instance_options::get_shutdown_delay() const
-{
- static const uint DEFAULT_SHUTDOWN_DELAY= 35;
-
- /*
- NOTE: it is important to check shutdown_delay here, but use
- shutdown_delay_val. The idea is that if the option is unset,
- shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
- */
-
- return shutdown_delay ? shutdown_delay_val : DEFAULT_SHUTDOWN_DELAY;
-}
-
-int Instance_options::get_mysqld_port() const
-{
- /*
- NOTE: it is important to check mysqld_port here, but use mysqld_port_val.
- The idea is that if the option is unset, mysqld_port will be NULL, but
- mysqld_port_val will not be reset.
- */
-
- return mysqld_port ? mysqld_port_val : 0;
-}
-
diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h
deleted file mode 100644
index b0503815036..00000000000
--- a/server-tools/instance-manager/instance_options.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_sys.h>
-
-#include "parse.h"
-#include "portability.h" /* for pid_t on Win32 */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-
-/*
- This class contains options of an instance and methods to operate them.
-
- We do not provide this class with the means of synchronization as it is
- supposed that options for instances are all loaded at once during the
- instance_map initilization and we do not change them later. This way we
- don't have to synchronize between threads.
-*/
-
-class Instance_options
-{
-public:
- /* The operation is used to check if the option is IM-specific or not. */
- static bool is_option_im_specific(const char *option_name);
-
-public:
- Instance_options();
- ~Instance_options();
-
- bool complete_initialization();
-
- bool set_option(Named_value *option);
- void unset_option(const char *option_name);
-
- inline int get_num_options() const;
- inline Named_value get_option(int idx) const;
-
-public:
- bool init(const LEX_STRING *instance_name_arg);
- pid_t load_pid();
- int get_pid_filename(char *result);
- int unlink_pidfile();
- void print_argv();
-
- uint get_shutdown_delay() const;
- int get_mysqld_port() const;
-
-public:
- /*
- We need this value to be greater or equal then FN_REFLEN found in
- my_global.h to use my_load_path()
- */
- enum { MAX_PATH_LEN= 512 };
- enum { MAX_NUMBER_OF_DEFAULT_OPTIONS= 2 };
- char pid_file_with_path[MAX_PATH_LEN];
- char **argv;
- /*
- Here we cache the version string, obtained from mysqld --version.
- In the case when mysqld binary is not found we get NULL here.
- */
- const char *mysqld_version;
- /* We need the some options, so we store them as a separate pointers */
- const char *mysqld_socket;
- const char *mysqld_datadir;
- const char *mysqld_pid_file;
- LEX_STRING instance_name;
- LEX_STRING mysqld_path;
- LEX_STRING mysqld_real_path;
- const char *nonguarded;
- /* log enums are defined in parse.h */
- char *logs[3];
-
-private:
- bool fill_log_options();
- bool fill_instance_version();
- bool fill_mysqld_real_path();
- int add_to_argv(const char *option);
- int get_default_option(char *result, size_t result_len,
- const char *option_name);
-
- void update_var(const char *option_name, const char *option_value);
- int find_option(const char *option_name);
-
-private:
- const char *mysqld_port;
- uint mysqld_port_val;
- const char *shutdown_delay;
- uint shutdown_delay_val;
-
- uint filled_default_options;
- MEM_ROOT alloc;
-
- Named_value_arr options;
-};
-
-
-inline int Instance_options::get_num_options() const
-{
- return options.get_size();
-}
-
-
-inline Named_value Instance_options::get_option(int idx) const
-{
- return options.get_element(idx);
-}
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H */
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
deleted file mode 100644
index 4d8a33e7db1..00000000000
--- a/server-tools/instance-manager/listener.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "listener.h"
-
-#include <my_global.h>
-#include <mysql.h>
-#include <violite.h>
-
-#include <sys/stat.h>
-#ifndef __WIN__
-#include <sys/un.h>
-#endif
-
-#include "log.h"
-#include "mysql_connection.h"
-#include "options.h"
-#include "portability.h"
-#include "priv.h"
-#include "thread_registry.h"
-
-
-static void set_non_blocking(int socket)
-{
-#ifndef __WIN__
- int flags= fcntl(socket, F_GETFL, 0);
- fcntl(socket, F_SETFL, flags | O_NONBLOCK);
-#else
- u_long arg= 1;
- ioctlsocket(socket, FIONBIO, &arg);
-#endif
-}
-
-
-static void set_no_inherit(int socket)
-{
-#ifndef __WIN__
- int flags= fcntl(socket, F_GETFD, 0);
- fcntl(socket, F_SETFD, flags | FD_CLOEXEC);
-#endif
-}
-
-const int Listener::LISTEN_BACK_LOG_SIZE= 5; /* standard backlog size */
-
-Listener::Listener(Thread_registry *thread_registry_arg,
- User_map *user_map_arg)
- :thread_registry(thread_registry_arg),
- user_map(user_map_arg),
- total_connection_count(0),
- num_sockets(0)
-{
-}
-
-
-/*
- Listener::run() - listen all supported sockets and spawn a thread
- to handle incoming connection.
- Using 'die' in case of syscall failure is OK now - we don't hold any
- resources and 'die' kills the signal thread automatically. To be rewritten
- one day.
- See also comments in mysqlmanager.cc to picture general Instance Manager
- architecture.
-*/
-
-void Listener::run()
-{
- int i, n= 0;
-
-#ifndef __WIN__
- struct sockaddr_un unix_socket_address;
-#endif
-
- log_info("Listener: started.");
-
- thread_registry->register_thread(&thread_info);
-
- FD_ZERO(&read_fds);
-
- /* I. prepare 'listen' sockets */
- if (create_tcp_socket())
- goto err;
-
-#ifndef __WIN__
- if (create_unix_socket(unix_socket_address))
- goto err;
-#endif
-
- /* II. Listen sockets and spawn childs */
- for (i= 0; i < num_sockets; i++)
- n= max(n, sockets[i]);
- n++;
-
- timeval tv;
- while (!thread_registry->is_shutdown())
- {
- fd_set read_fds_arg= read_fds;
- /*
- We should reintialize timer as on linux it is modified
- to reflect amount of time not slept.
- */
- tv.tv_sec= 0;
- tv.tv_usec= 100000;
-
- /*
- When using valgrind 2.0 this syscall doesn't get kicked off by a
- signal during shutdown. This results in failing assert
- (Thread_registry::~Thread_registry). Valgrind 2.2 works fine.
- */
- int rc= select(n, &read_fds_arg, 0, 0, &tv);
-
- if (rc == 0 || rc == -1)
- {
- if (rc == -1 && errno != EINTR)
- log_error("Listener: select() failed: %s.",
- (const char *) strerror(errno));
- continue;
- }
-
-
- for (int socket_index= 0; socket_index < num_sockets; socket_index++)
- {
- /* Assuming that rc > 0 as we asked to wait forever */
- if (FD_ISSET(sockets[socket_index], &read_fds_arg))
- {
- int client_fd= accept(sockets[socket_index], 0, 0);
- /* accept may return -1 (failure or spurious wakeup) */
- if (client_fd >= 0) // connection established
- {
- set_no_inherit(client_fd);
-
- struct st_vio *vio=
- vio_new(client_fd,
- socket_index == 0 ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
- socket_index == 0 ? 1 : 0);
-
- if (vio != NULL)
- handle_new_mysql_connection(vio);
- else
- {
- shutdown(client_fd, SHUT_RDWR);
- closesocket(client_fd);
- }
- }
- }
- }
- }
-
- /* III. Release all resources and exit */
-
- log_info("Listener: shutdown requested, exiting...");
-
- for (i= 0; i < num_sockets; i++)
- closesocket(sockets[i]);
-
-#ifndef __WIN__
- unlink(unix_socket_address.sun_path);
-#endif
-
- thread_registry->unregister_thread(&thread_info);
-
- log_info("Listener: finished.");
- return;
-
-err:
- log_error("Listener: failed to initialize. Initiate shutdown...");
-
- // we have to close the ip sockets in case of error
- for (i= 0; i < num_sockets; i++)
- closesocket(sockets[i]);
-
- thread_registry->set_error_status();
- thread_registry->unregister_thread(&thread_info);
- thread_registry->request_shutdown();
- return;
-}
-
-int Listener::create_tcp_socket()
-{
- /* value to be set by setsockopt */
- int arg= 1;
-
- int ip_socket= socket(AF_INET, SOCK_STREAM, 0);
- if (ip_socket == INVALID_SOCKET)
- {
- log_error("Listener: socket(AF_INET) failed: %s.",
- (const char *) strerror(errno));
- return -1;
- }
-
- struct sockaddr_in ip_socket_address;
- bzero(&ip_socket_address, sizeof(ip_socket_address));
-
- ulong im_bind_addr;
- if (Options::Main::bind_address != 0)
- {
- im_bind_addr= (ulong) inet_addr(Options::Main::bind_address);
-
- if (im_bind_addr == (ulong) INADDR_NONE)
- im_bind_addr= htonl(INADDR_ANY);
- }
- else
- im_bind_addr= htonl(INADDR_ANY);
- uint im_port= Options::Main::port_number;
-
- ip_socket_address.sin_family= AF_INET;
- ip_socket_address.sin_addr.s_addr= im_bind_addr;
-
-
- ip_socket_address.sin_port= (unsigned short)
- htons((unsigned short) im_port);
-
- setsockopt(ip_socket, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg));
- if (bind(ip_socket, (struct sockaddr *) &ip_socket_address,
- sizeof(ip_socket_address)))
- {
- log_error("Listener: bind(ip socket) failed: %s.",
- (const char *) strerror(errno));
- closesocket(ip_socket);
- return -1;
- }
-
- if (listen(ip_socket, LISTEN_BACK_LOG_SIZE))
- {
- log_error("Listener: listen(ip socket) failed: %s.",
- (const char *) strerror(errno));
- closesocket(ip_socket);
- return -1;
- }
-
- /* set the socket nonblocking */
- set_non_blocking(ip_socket);
-
- /* make sure that instances won't be listening our sockets */
- set_no_inherit(ip_socket);
-
- FD_SET(ip_socket, &read_fds);
- sockets[num_sockets++]= ip_socket;
- log_info("Listener: accepting connections on ip socket (port: %d)...",
- (int) im_port);
- return 0;
-}
-
-#ifndef __WIN__
-int Listener::
-create_unix_socket(struct sockaddr_un &unix_socket_address)
-{
- int unix_socket= socket(AF_UNIX, SOCK_STREAM, 0);
- if (unix_socket == INVALID_SOCKET)
- {
- log_error("Listener: socket(AF_UNIX) failed: %s.",
- (const char *) strerror(errno));
- return -1;
- }
-
- bzero(&unix_socket_address, sizeof(unix_socket_address));
-
- unix_socket_address.sun_family= AF_UNIX;
- strmake(unix_socket_address.sun_path, Options::Main::socket_file_name,
- sizeof(unix_socket_address.sun_path));
- unlink(unix_socket_address.sun_path); // in case we have stale socket file
-
- /*
- POSIX specifies default permissions for a pathname created by bind
- to be 0777. We need everybody to have access to the socket.
- */
- mode_t old_mask= umask(0);
- if (bind(unix_socket, (struct sockaddr *) &unix_socket_address,
- sizeof(unix_socket_address)))
- {
- log_error("Listener: bind(unix socket) failed for '%s': %s.",
- (const char *) unix_socket_address.sun_path,
- (const char *) strerror(errno));
- close(unix_socket);
- return -1;
- }
-
- umask(old_mask);
-
- if (listen(unix_socket, LISTEN_BACK_LOG_SIZE))
- {
- log_error("Listener: listen(unix socket) failed: %s.",
- (const char *) strerror(errno));
- close(unix_socket);
- return -1;
- }
-
- /* set the socket nonblocking */
- set_non_blocking(unix_socket);
-
- /* make sure that instances won't be listening our sockets */
- set_no_inherit(unix_socket);
-
- log_info("Listener: accepting connections on unix socket '%s'...",
- (const char *) unix_socket_address.sun_path);
- sockets[num_sockets++]= unix_socket;
- FD_SET(unix_socket, &read_fds);
- return 0;
-}
-#endif
-
-
-/*
- Create new mysql connection. Created thread is responsible for deletion of
- the Mysql_connection and Vio instances passed to it.
- SYNOPSIS
- handle_new_mysql_connection()
-*/
-
-void Listener::handle_new_mysql_connection(struct st_vio *vio)
-{
- Mysql_connection *mysql_connection=
- new Mysql_connection(thread_registry, user_map,
- vio, ++total_connection_count);
- if (mysql_connection == NULL || mysql_connection->start(Thread::DETACHED))
- {
- log_error("Listener: can not start connection handler.");
- delete mysql_connection;
- vio_delete(vio);
- }
- /* The connection will delete itself when the thread is finished */
-}
diff --git a/server-tools/instance-manager/listener.h b/server-tools/instance-manager/listener.h
deleted file mode 100644
index 964fb361fb5..00000000000
--- a/server-tools/instance-manager/listener.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_LISTENER_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_LISTENER_H
-
-#include "thread_registry.h"
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-class Thread_registry;
-class User_map;
-
-/**
- Listener - a thread listening on sockets and spawning
- connection threads.
-*/
-
-class Listener: public Thread
-{
-public:
- Listener(Thread_registry *thread_registry_arg, User_map *user_map_arg);
-
-protected:
- virtual void run();
-
-private:
- static const int LISTEN_BACK_LOG_SIZE;
-
-private:
- Thread_info thread_info;
- Thread_registry *thread_registry;
- User_map *user_map;
-
- ulong total_connection_count;
-
- int sockets[2];
- int num_sockets;
- fd_set read_fds;
-
-private:
- void handle_new_mysql_connection(struct st_vio *vio);
- int create_tcp_socket();
- int create_unix_socket(struct sockaddr_un &unix_socket_address);
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_LISTENER_H
diff --git a/server-tools/instance-manager/log.cc b/server-tools/instance-manager/log.cc
deleted file mode 100644
index 9f276523e49..00000000000
--- a/server-tools/instance-manager/log.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "log.h"
-
-#include <my_global.h>
-#include <m_string.h>
-#include <my_sys.h>
-
-#include <stdarg.h>
-
-#include "portability.h" /* for vsnprintf() on Windows. */
-
-/*
- TODO:
- - add flexible header support
- - rewrite all fprintf with fwrite
- - think about using 'write' instead of fwrite/fprintf on POSIX systems
-*/
-
-/*
- Format log entry and write it to the given stream.
- SYNOPSIS
- log()
-*/
-
-static void log(FILE *file,const char *level_tag, const char *format,
- va_list args)
-{
- /*
- log() should be thread-safe; it implies that we either call fprintf()
- once per log(), or use flockfile()/funlockfile(). But flockfile() is
- POSIX, not ANSI C, so we try to vsnprintf the whole message to the
- stack, and if stack buffer is not enough, to malloced string. When
- message is formatted, it is fprintf()'ed to the file.
- */
-
- /* Format time like MYSQL_LOG does. */
- time_t now= time(0);
- struct tm bd_time; // broken-down time
- localtime_r(&now, &bd_time);
-
- char buff_date[128];
- sprintf(buff_date, "[%d/%lu] [%02d/%02d/%02d %02d:%02d:%02d] [%s] ",
- (int) getpid(),
- (unsigned long) pthread_self(),
- (int) bd_time.tm_year % 100,
- (int) bd_time.tm_mon + 1,
- (int) bd_time.tm_mday,
- (int) bd_time.tm_hour,
- (int) bd_time.tm_min,
- (int) bd_time.tm_sec,
- (const char *) level_tag);
- /* Format the message */
- char buff_stack[256];
-
- int n= vsnprintf(buff_stack, sizeof(buff_stack), format, args);
- /*
- return value of vsnprintf can vary, according to various standards;
- try to check all cases.
- */
- char *buff_msg= buff_stack;
- if (n < 0 || n == sizeof(buff_stack))
- {
- int size= sizeof(buff_stack) * 2;
- buff_msg= (char*) my_malloc(size, MYF(0));
- while (TRUE)
- {
- if (buff_msg == 0)
- {
- strmake(buff_stack, "log(): message is too big, my_malloc() failed",
- sizeof(buff_stack) - 1);
- buff_msg= buff_stack;
- break;
- }
- n = vsnprintf(buff_msg, size, format, args);
- if (n >= 0 && n < size)
- break;
- size*= 2;
- /* realloc() does unnecessary memcpy */
- my_free(buff_msg, 0);
- buff_msg= (char*) my_malloc(size, MYF(0));
- }
- }
- else if ((size_t) n > sizeof(buff_stack))
- {
- buff_msg= (char*) my_malloc(n + 1, MYF(0));
-#ifdef DBUG
- DBUG_ASSERT(n == vsnprintf(buff_msg, n + 1, format, args));
-#else
- vsnprintf(buff_msg, n + 1, format, args);
-#endif
- }
- fprintf(file, "%s%s\n", buff_date, buff_msg);
- if (buff_msg != buff_stack)
- my_free(buff_msg, 0);
-
- /* don't fflush() the file: buffering strategy is set in log_init() */
-}
-
-/**************************************************************************
- Logging: implementation of public interface.
-**************************************************************************/
-
-/*
- The function initializes logging sub-system.
-
- SYNOPSIS
- log_init()
-*/
-
-void log_init()
-{
- /*
- stderr is unbuffered by default; there is no good of line buffering,
- as all logging is performed linewise - so remove buffering from stdout
- also
- */
- setbuf(stdout, 0);
-}
-
-
-/*
- The function is intended to log error messages. It precedes a message
- with date, time and [ERROR] tag and print it to the stderr and stdout.
-
- We want to print it on stdout to be able to know in which context we got the
- error
-
- SYNOPSIS
- log_error()
- format [IN] format string
- ... [IN] arguments to format
-*/
-
-void log_error(const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- log(stdout, "ERROR", format, args);
- fflush(stdout);
- log(stderr, "ERROR", format, args);
- fflush(stderr);
- va_end(args);
-}
-
-
-/*
- The function is intended to log information messages. It precedes
- a message with date, time and [INFO] tag and print it to the stdout.
-
- SYNOPSIS
- log_error()
- format [IN] format string
- ... [IN] arguments to format
-*/
-
-void log_info(const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- log(stdout, "INFO", format, args);
- va_end(args);
-}
-
-/*
- The function prints information to the error log and eixt(1).
-
- SYNOPSIS
- die()
- format [IN] format string
- ... [IN] arguments to format
-*/
-
-void die(const char *format, ...)
-{
- va_list args;
- fprintf(stderr,"%s: ", my_progname);
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
- fprintf(stderr, "\n");
- exit(1);
-}
diff --git a/server-tools/instance-manager/log.h b/server-tools/instance-manager/log.h
deleted file mode 100644
index e6c3b55c54c..00000000000
--- a/server-tools/instance-manager/log.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_LOG_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_LOG_H
-
-/*
- Logging facilities.
-
- Two logging streams are supported: error log and info log.
- Additionally libdbug may be used for debug information output.
-
- ANSI C buffered I/O is used to perform logging.
-
- Logging is performed via stdout/stder, so one can reopen them to point to
- ordinary files. To initialize logging environment log_init() must be called.
-
- Rationale:
- - no MYSQL_LOG as it has BIN mode, and not easy to fetch from sql_class.h
- - no constructors/desctructors to make logging available all the time
-*/
-
-
-void log_init();
-
-
-void log_info(const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format(printf, 1, 2)))
-#endif
- ;
-
-
-void log_error(const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 1, 2)))
-#endif
- ;
-
-
-void die(const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 1, 2)))
-#endif
- ;
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_LOG_H
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
deleted file mode 100644
index 792461e41a9..00000000000
--- a/server-tools/instance-manager/manager.cc
+++ /dev/null
@@ -1,526 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "manager.h"
-
-#include <my_global.h>
-#include <m_string.h>
-#include <my_sys.h>
-#include <thr_alarm.h>
-
-#include <signal.h>
-#ifndef __WIN__
-#include <sys/wait.h>
-#endif
-
-#include "exit_codes.h"
-#include "guardian.h"
-#include "instance_map.h"
-#include "listener.h"
-#include "mysql_manager_error.h"
-#include "mysqld_error.h"
-#include "log.h"
-#include "options.h"
-#include "priv.h"
-#include "thread_registry.h"
-#include "user_map.h"
-
-
-/**********************************************************************
- {{{ Platform-specific implementation.
-**********************************************************************/
-
-#ifndef __WIN__
-void set_signals(sigset_t *mask)
-{
- /* block signals */
- sigemptyset(mask);
- sigaddset(mask, SIGINT);
- sigaddset(mask, SIGTERM);
- sigaddset(mask, SIGPIPE);
- sigaddset(mask, SIGHUP);
- signal(SIGPIPE, SIG_IGN);
-
- /*
- We want this signal to be blocked in all theads but the signal
- one. It is needed for the thr_alarm subsystem to work.
- */
- sigaddset(mask,THR_SERVER_ALARM);
-
- /* all new threads will inherite this signal mask */
- pthread_sigmask(SIG_BLOCK, mask, NULL);
-
- /*
- In our case the signal thread also implements functions of alarm thread.
- Here we init alarm thread functionality. We suppose that we won't have
- more then 10 alarms at the same time.
- */
- init_thr_alarm(10);
-}
-#else
-
-bool have_signal;
-
-void onsignal(int signo)
-{
- have_signal= TRUE;
-}
-
-void set_signals(sigset_t *set)
-{
- signal(SIGINT, onsignal);
- signal(SIGTERM, onsignal);
- have_signal= FALSE;
-}
-
-int my_sigwait(const sigset_t *set, int *sig)
-{
- while (!have_signal)
- {
- Sleep(100);
- }
- return 0;
-}
-
-#endif
-
-/**********************************************************************
- }}}
-**********************************************************************/
-
-
-/**********************************************************************
- {{{ Implementation of checking the actual thread model.
-***********************************************************************/
-
-namespace { /* no-indent */
-
-class ThreadModelChecker: public Thread
-{
-public:
- ThreadModelChecker()
- :main_pid(getpid())
- { }
-
-public:
- inline bool is_linux_threads() const
- {
- return linux_threads;
- }
-
-protected:
- virtual void run()
- {
- linux_threads= main_pid != getpid();
- }
-
-private:
- pid_t main_pid;
- bool linux_threads;
-};
-
-bool check_if_linux_threads(bool *linux_threads)
-{
- ThreadModelChecker checker;
-
- if (checker.start() || checker.join())
- return TRUE;
-
- *linux_threads= checker.is_linux_threads();
-
- return FALSE;
-}
-
-}
-
-/**********************************************************************
- }}}
-***********************************************************************/
-
-
-/**********************************************************************
- Manager implementation
-***********************************************************************/
-
-Guardian *Manager::p_guardian;
-Instance_map *Manager::p_instance_map;
-Thread_registry *Manager::p_thread_registry;
-User_map *Manager::p_user_map;
-
-#ifndef __WIN__
-bool Manager::linux_threads;
-#endif // __WIN__
-
-
-/**
- Request shutdown of guardian and threads registered in Thread_registry.
-
- SYNOPSIS
- stop_all_threads()
-*/
-
-void Manager::stop_all_threads()
-{
- /*
- Let Guardian thread know that it should break it's processing cycle,
- once it wakes up.
- */
- p_guardian->request_shutdown();
-
- /* Stop all threads. */
- p_thread_registry->deliver_shutdown();
-
- /* Set error status in the thread registry. */
- p_thread_registry->set_error_status();
-}
-
-
-/**
- Initialize user map and load password file.
-
- SYNOPSIS
- init_user_map()
-
- RETURN
- FALSE on success
- TRUE on failure
-*/
-
-bool Manager::init_user_map(User_map *user_map)
-{
- int err_code;
- const char *err_msg;
-
- if (user_map->init())
- {
- log_error("Manager: can not initialize user list: out of memory.");
- return TRUE;
- }
-
- err_code= user_map->load(Options::Main::password_file_name, &err_msg);
-
- if (!err_code)
- return FALSE;
-
- if (err_code == ERR_PASSWORD_FILE_DOES_NOT_EXIST &&
- Options::Main::mysqld_safe_compatible)
- {
- /*
- The password file does not exist, but we are running in
- mysqld_safe-compatible mode. Continue, but complain in log.
- */
-
- log_info("Warning: password file does not exist, "
- "nobody will be able to connect to Instance Manager.");
-
- return FALSE;
- }
-
- log_error("Manager: %s.", (const char *) err_msg);
-
- return TRUE;
-}
-
-
-/**
- Main manager function.
-
- SYNOPSIS
- main()
-
- DESCRIPTION
- This is an entry point to the main instance manager process:
- start listener thread, write pid file and enter into signal handling.
- See also comments in mysqlmanager.cc to picture general Instance Manager
- architecture.
-
- RETURNS
- main() returns exit status (exit code).
-*/
-
-int Manager::main()
-{
- bool shutdown_complete= FALSE;
- pid_t manager_pid= getpid();
-
- log_info("Manager: initializing...");
-
-#ifndef __WIN__
- if (check_if_linux_threads(&linux_threads))
- {
- log_error("Manager: can not determine thread model.");
- return 1;
- }
-
- log_info("Manager: detected threads model: %s.",
- (const char *) (linux_threads ? "LINUX threads" : "POSIX threads"));
-#endif // __WIN__
-
- /*
- All objects created in the Manager object live as long as thread_registry
- lives, and thread_registry is alive until there are working threads.
-
- There are two main purposes of the Thread Registry:
- 1. Interrupt blocking I/O and signal condition variables in case of
- shutdown;
- 2. Wait for detached threads before shutting down the main thread.
-
- NOTE:
- 1. Handling shutdown can be done in more elegant manner by introducing
- Event (or Condition) object with support of logical operations.
- 2. Using Thread Registry to wait for detached threads is definitely not
- the best way, because when Thread Registry unregisters an thread, the
- thread is still alive. Accurate way to wait for threads to stop is
- not using detached threads and join all threads before shutdown.
- */
-
- Thread_registry thread_registry;
- User_map user_map;
- Instance_map instance_map;
- Guardian guardian(&thread_registry, &instance_map);
-
- Listener listener(&thread_registry, &user_map);
-
- p_instance_map= &instance_map;
- p_guardian= &guardian;
- p_thread_registry= &thread_registry;
- p_user_map= &user_map;
-
- /* Initialize instance map. */
-
- if (instance_map.init())
- {
- log_error("Manager: can not initialize instance list: out of memory.");
- return 1;
- }
-
- /* Initialize user db. */
-
- if (init_user_map(&user_map))
- return 1; /* logging has been already done. */
-
- /* Write Instance Manager pid file. */
-
- if (create_pid_file(Options::Main::pid_file_name, manager_pid))
- return 1; /* necessary logging has been already done. */
-
- log_info("Manager: pid file (%s) created.",
- (const char *) Options::Main::pid_file_name);
-
- /*
- Initialize signals and alarm-infrastructure.
-
- NOTE: To work nicely with LinuxThreads, the signal thread is the first
- thread in the process.
-
- NOTE: After init_thr_alarm() call it's possible to call thr_alarm()
- (from different threads), that results in sending ALARM signal to the
- alarm thread (which can be the main thread). That signal can interrupt
- blocking calls. In other words, a blocking call can be interrupted in
- the main thread after init_thr_alarm().
- */
-
- sigset_t mask;
- set_signals(&mask);
-
- /*
- Create the guardian thread. The newly started thread will block until
- we actually load instances.
-
- NOTE: Guardian should be shutdown first. Only then all other threads
- can be stopped. This should be done in this order because the guardian
- is responsible for shutting down all the guarded instances, and this
- is a long operation.
-
- NOTE: Guardian uses thr_alarm() when detects the current state of an
- instance (is_running()), but this does not interfere with
- flush_instances() call later in the code, because until
- flush_instances() completes in the main thread, Guardian thread is not
- permitted to process instances. And before flush_instances() has
- completed, there are no instances to guard.
- */
-
- if (guardian.start(Thread::DETACHED))
- {
- log_error("Manager: can not start Guardian thread.");
- goto err;
- }
-
- /* Load instances. */
-
- if (Manager::flush_instances())
- {
- log_error("Manager: can not init instances repository.");
- stop_all_threads();
- goto err;
- }
-
- /* Initialize the Listener. */
-
- if (listener.start(Thread::DETACHED))
- {
- log_error("Manager: can not start Listener thread.");
- stop_all_threads();
- goto err;
- }
-
- /*
- After the list of guarded instances have been initialized,
- Guardian should start them.
- */
-
- guardian.ping();
-
- /* Main loop. */
-
- log_info("Manager: started.");
-
- while (!shutdown_complete)
- {
- int signo;
- int status= 0;
-
- if ((status= my_sigwait(&mask, &signo)) != 0)
- {
- log_error("Manager: sigwait() failed");
- stop_all_threads();
- goto err;
- }
-
- /*
- The general idea in this loop is the following:
- - we are waiting for SIGINT, SIGTERM -- signals that mean we should
- shutdown;
- - as shutdown signal is caught, we stop Guardian thread (by calling
- Guardian::request_shutdown());
- - as Guardian is stopped, it sends SIGTERM to this thread
- (by calling Thread_registry::request_shutdown()), so that the
- my_sigwait() above returns;
- - as we catch the second SIGTERM, we send signals to all threads
- registered in Thread_registry (by calling
- Thread_registry::deliver_shutdown()) and waiting for threads to stop;
- */
-
-#ifndef __WIN__
-/*
- On some Darwin kernels SIGHUP is delivered along with most
- signals. This is why we skip it's processing on these
- platforms. For more details and test program see
- Bug #14164 IM tests fail on MacOS X (powermacg5)
-*/
-#ifdef IGNORE_SIGHUP_SIGQUIT
- if (SIGHUP == signo)
- continue;
-#endif
- if (THR_SERVER_ALARM == signo)
- process_alarm(signo);
- else
-#endif
- {
- log_info("Manager: got shutdown signal.");
-
- if (!guardian.is_stopped())
- {
- guardian.request_shutdown();
- }
- else
- {
- thread_registry.deliver_shutdown();
- shutdown_complete= TRUE;
- }
- }
- }
-
- log_info("Manager: finished.");
-
-err:
- /* delete the pid file */
- my_delete(Options::Main::pid_file_name, MYF(0));
-
-#ifndef __WIN__
- /* free alarm structures */
- end_thr_alarm(1);
-#endif
-
- return thread_registry.get_error_status() ? 1 : 0;
-}
-
-
-/**
- Re-read instance configuration file.
-
- SYNOPSIS
- flush_instances()
-
- DESCRIPTION
- This function will:
- - clear the current list of instances. This removes both
- running and stopped instances.
- - load a new instance configuration from the file.
- - pass on the new map to the guardian thread: it will start
- all instances that are marked `guarded' and not yet started.
-
- Note, as the check whether an instance is started is currently
- very simple (returns TRUE if there is a MySQL server running
- at the given port), this function has some peculiar
- side-effects:
- * if the port number of a running instance was changed, the
- old instance is forgotten, even if it was running. The new
- instance will be started at the new port.
- * if the configuration was changed in a way that two
- instances swapped their port numbers, the guardian thread
- will not notice that and simply report that both instances
- are configured successfully and running.
-
- In order to avoid such side effects one should never call
- FLUSH INSTANCES without prior stop of all running instances.
-
- RETURN
- 0 On success
- ER_OUT_OF_RESOURCES Not enough resources to complete the operation
- ER_THERE_IS_ACTIVE_INSTACE If there is an active instance
-*/
-
-int Manager::flush_instances()
-{
- p_instance_map->lock();
-
- if (p_instance_map->is_there_active_instance())
- {
- p_instance_map->unlock();
- return ER_THERE_IS_ACTIVE_INSTACE;
- }
-
- if (p_instance_map->reset())
- {
- p_instance_map->unlock();
- return ER_OUT_OF_RESOURCES;
- }
-
- if (p_instance_map->load())
- {
- p_instance_map->unlock();
-
- /* Don't init guardian if we failed to load instances. */
- return ER_OUT_OF_RESOURCES;
- }
-
- get_guardian()->init();
- get_guardian()->ping();
-
- p_instance_map->unlock();
-
- return 0;
-}
diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h
deleted file mode 100644
index e6956884603..00000000000
--- a/server-tools/instance-manager/manager.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-#include <my_global.h>
-
-class Guardian;
-class Instance_map;
-class Thread_registry;
-class User_map;
-
-class Manager
-{
-public:
- static int main();
-
- static int flush_instances();
-
-public:
- /**
- These methods return a non-NULL value only for the duration
- of main().
- */
- static Instance_map *get_instance_map() { return p_instance_map; }
- static Guardian *get_guardian() { return p_guardian; }
- static Thread_registry *get_thread_registry() { return p_thread_registry; }
- static User_map *get_user_map() { return p_user_map; }
-
-public:
-#ifndef __WIN__
- static bool is_linux_threads() { return linux_threads; }
-#endif // __WIN__
-
-private:
- static void stop_all_threads();
- static bool init_user_map(User_map *user_map);
-
-private:
- static Guardian *p_guardian;
- static Instance_map *p_instance_map;
- static Thread_registry *p_thread_registry;
- static User_map *p_user_map;
-
-#ifndef __WIN__
- /*
- This flag is set if Instance Manager is running on the system using
- LinuxThreads.
- */
- static bool linux_threads;
-#endif // __WIN__
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
diff --git a/server-tools/instance-manager/messages.cc b/server-tools/instance-manager/messages.cc
deleted file mode 100644
index 201ebfd62fc..00000000000
--- a/server-tools/instance-manager/messages.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "messages.h"
-
-#include <my_global.h>
-#include <mysql_com.h>
-
-#include "mysqld_error.h"
-#include "mysql_manager_error.h"
-
-
-static const char *mysqld_error_message(unsigned sql_errno)
-{
- switch (sql_errno) {
- case ER_HANDSHAKE_ERROR:
- return "Bad handshake";
- case ER_OUT_OF_RESOURCES:
- return "Out of memory; Check if mysqld or some other process"
- " uses all available memory. If not you may have to use"
- " 'ulimit' to allow mysqld to use more memory or you can"
- " add more swap space";
- case ER_ACCESS_DENIED_ERROR:
- return "Access denied. Bad username/password pair";
- case ER_NOT_SUPPORTED_AUTH_MODE:
- return "Client does not support authentication protocol requested by"
- " server; consider upgrading MySQL client";
- case ER_UNKNOWN_COM_ERROR:
- return "Unknown command";
- case ER_SYNTAX_ERROR:
- return "You have an error in your command syntax. Check the manual that"
- " corresponds to your MySQL Instance Manager version for the right"
- " syntax to use";
- case ER_BAD_INSTANCE_NAME:
- return "Unknown instance name";
- case ER_INSTANCE_IS_NOT_STARTED:
- return "Cannot stop instance. Perhaps the instance is not started, or was"
- " started manually, so IM cannot find the pidfile.";
- case ER_INSTANCE_ALREADY_STARTED:
- return "The instance is already started";
- case ER_CANNOT_START_INSTANCE:
- return "Cannot start instance. Possible reasons are wrong instance options"
- " or resources shortage";
- case ER_OFFSET_ERROR:
- return "Cannot read negative number of bytes";
- case ER_STOP_INSTANCE:
- return "Cannot stop instance";
- case ER_READ_FILE:
- return "Cannot read requested part of the logfile";
- case ER_NO_SUCH_LOG:
- return "The instance has no such log enabled";
- case ER_OPEN_LOGFILE:
- return "Cannot open log file";
- case ER_GUESS_LOGFILE:
- return "Cannot guess the log filename. Try specifying full log name"
- " in the instance options";
- case ER_ACCESS_OPTION_FILE:
- return "Cannot open the option file to edit. Check permissions";
- case ER_DROP_ACTIVE_INSTANCE:
- return "Cannot drop an active instance. You should stop it first";
- case ER_CREATE_EXISTING_INSTANCE:
- return "Instance already exists";
- case ER_INSTANCE_MISCONFIGURED:
- return "Instance is misconfigured. Cannot start it";
- case ER_MALFORMED_INSTANCE_NAME:
- return "Malformed instance name.";
- case ER_INSTANCE_IS_ACTIVE:
- return "The instance is active. Stop the instance first";
- case ER_THERE_IS_ACTIVE_INSTACE:
- return "At least one instance is active. Stop all instances first";
- case ER_INCOMPATIBLE_OPTION:
- return "Instance Manager-specific options are prohibited from being used "
- "in the configuration of mysqld-compatible instances";
- case ER_CONF_FILE_DOES_NOT_EXIST:
- return "Configuration file does not exist";
- default:
- DBUG_ASSERT(0);
- return 0;
- }
-}
-
-
-const char *message(unsigned sql_errno)
-{
- return mysqld_error_message(sql_errno);
-}
-
-
-const char *errno_to_sqlstate(unsigned sql_errno)
-{
- return mysql_errno_to_sqlstate(sql_errno);
-}
diff --git a/server-tools/instance-manager/messages.h b/server-tools/instance-manager/messages.h
deleted file mode 100644
index 5d9383093bc..00000000000
--- a/server-tools/instance-manager/messages.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_MESSAGES_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_MESSAGES_H
-
-const char *message(unsigned sql_errno);
-
-const char *errno_to_sqlstate(unsigned sql_errno);
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MESSAGES_H
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
deleted file mode 100644
index 12ea0a3ea5a..00000000000
--- a/server-tools/instance-manager/mysql_connection.cc
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "mysql_connection.h"
-
-#include <m_string.h>
-#include <m_string.h>
-#include <my_global.h>
-#include <mysql.h>
-#include <my_sys.h>
-#include <violite.h>
-
-#include "command.h"
-#include "log.h"
-#include "messages.h"
-#include "mysqld_error.h"
-#include "mysql_manager_error.h"
-#include "parse.h"
-#include "priv.h"
-#include "protocol.h"
-#include "thread_registry.h"
-#include "user_map.h"
-
-
-Mysql_connection::Mysql_connection(Thread_registry *thread_registry_arg,
- User_map *user_map_arg,
- struct st_vio *vio_arg, ulong
- connection_id_arg)
- :vio(vio_arg),
- connection_id(connection_id_arg),
- thread_registry(thread_registry_arg),
- user_map(user_map_arg)
-{
-}
-
-
-/*
- NET subsystem requieres its user to provide my_net_local_init extern
- C function (exactly as declared below). my_net_local_init is called by
- my_net_init and is supposed to set NET controlling variables.
- See also priv.h for variables description.
-*/
-
-C_MODE_START
-
-void my_net_local_init(NET *net)
-{
- net->max_packet= net_buffer_length;
- my_net_set_read_timeout(net, (uint)net_read_timeout);
- my_net_set_write_timeout(net, (uint)net_write_timeout);
- net->retry_count= net_retry_count;
- net->max_packet_size= max_allowed_packet;
-}
-
-C_MODE_END
-
-/*
- Unused stub hook required for linking the client API.
-*/
-
-C_MODE_START
-
-void slave_io_thread_detach_vio()
-{
-}
-
-C_MODE_END
-
-
-/*
- Every resource, which we can fail to acquire, is allocated in init().
- This function is complementary to cleanup().
-*/
-
-bool Mysql_connection::init()
-{
- /* Allocate buffers for network I/O */
- if (my_net_init(&net, vio))
- return TRUE;
-
- net.return_status= &status;
-
- /* Initialize random number generator */
- {
- ulong seed1= (ulong) &rand_st + rand();
- ulong seed2= (ulong) rand() + (ulong) time(0);
- randominit(&rand_st, seed1, seed2);
- }
-
- /* Fill scramble - server's random message used for handshake */
- create_random_string(scramble, SCRAMBLE_LENGTH, &rand_st);
-
- /* We don't support transactions, every query is atomic */
- status= SERVER_STATUS_AUTOCOMMIT;
-
- thread_registry->register_thread(&thread_info);
-
- return FALSE;
-}
-
-
-void Mysql_connection::cleanup()
-{
- net_end(&net);
- thread_registry->unregister_thread(&thread_info);
-}
-
-
-Mysql_connection::~Mysql_connection()
-{
- /* vio_delete closes the socket if necessary */
- vio_delete(vio);
-}
-
-
-void Mysql_connection::main()
-{
- log_info("Connection %lu: accepted.", (unsigned long) connection_id);
-
- if (check_connection())
- {
- log_info("Connection %lu: failed to authorize the user.",
- (unsigned long) connection_id);
-
- return;
- }
-
- log_info("Connection %lu: the user was authorized successfully.",
- (unsigned long) connection_id);
-
- vio_keepalive(vio, TRUE);
-
- while (!net.error && net.vio && !thread_registry->is_shutdown())
- {
- if (do_command())
- break;
- }
-}
-
-
-int Mysql_connection::check_connection()
-{
- ulong pkt_len=0; // to hold client reply length
-
- /* buffer for the first packet */ /* packet contains: */
- uchar buff[MAX_VERSION_LENGTH + 1 + // server version, 0-ended
- 4 + // connection id
- SCRAMBLE_LENGTH + 2 + // scramble (in 2 pieces)
- 18]; // server variables: flags,
- // charset number, status,
- uchar *pos= buff;
- ulong server_flags;
-
- memcpy(pos, mysqlmanager_version.str, mysqlmanager_version.length + 1);
- pos+= mysqlmanager_version.length + 1;
-
- int4store((uchar*) pos, connection_id);
- pos+= 4;
-
- /*
- Old clients does not understand long scrambles, but can ignore packet
- tail: that's why first part of the scramble is placed here, and second
- part at the end of packet (even though we don't support old clients,
- we must follow standard packet format.)
- */
- memcpy(pos, scramble, SCRAMBLE_LENGTH_323);
- pos+= SCRAMBLE_LENGTH_323;
- *pos++= '\0';
-
- server_flags= CLIENT_LONG_FLAG | CLIENT_PROTOCOL_41 |
- CLIENT_SECURE_CONNECTION;
-
- /*
- 18-bytes long section for various flags/variables
-
- Every flag occupies a bit in first half of ulong; int2store will
- gracefully pick up all flags.
- */
- int2store(pos, server_flags);
- pos+= 2;
- *pos++= (char) default_charset_info->number; // global mysys variable
- int2store(pos, status); // connection status
- pos+= 2;
- bzero(pos, 13); // not used now
- pos+= 13;
-
- /* second part of the scramble, null-terminated */
- memcpy(pos, scramble + SCRAMBLE_LENGTH_323,
- SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1);
- pos+= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1;
-
- /* write connection message and read reply */
- enum { MIN_HANDSHAKE_SIZE= 2 };
- if (net_write_command(&net, protocol_version, (uchar*) "", 0,
- buff, pos - buff) ||
- (pkt_len= my_net_read(&net)) == packet_error ||
- pkt_len < MIN_HANDSHAKE_SIZE)
- {
- net_send_error(&net, ER_HANDSHAKE_ERROR);
- return 1;
- }
-
- client_capabilities= uint2korr(net.read_pos);
- if (!(client_capabilities & CLIENT_PROTOCOL_41))
- {
- net_send_error_323(&net, ER_NOT_SUPPORTED_AUTH_MODE);
- return 1;
- }
- client_capabilities|= ((ulong) uint2korr(net.read_pos + 2)) << 16;
-
- pos= net.read_pos + 32;
-
- /* At least one byte for username and one byte for password */
- if (pos >= net.read_pos + pkt_len + 2)
- {
- /*TODO add user and password handling in error messages*/
- net_send_error(&net, ER_HANDSHAKE_ERROR);
- return 1;
- }
-
- const char *user= (char*) pos;
- const char *password= strend(user)+1;
- ulong password_len= *password++;
- LEX_STRING user_name= { (char *) user, password - user - 2 };
-
- if (password_len != SCRAMBLE_LENGTH)
- {
- net_send_error(&net, ER_ACCESS_DENIED_ERROR);
- return 1;
- }
- if (user_map->authenticate(&user_name, password, scramble))
- {
- net_send_error(&net, ER_ACCESS_DENIED_ERROR);
- return 1;
- }
- net_send_ok(&net, connection_id, NULL);
- return 0;
-}
-
-
-int Mysql_connection::do_command()
-{
- char *packet;
- ulong packet_length;
-
- /* We start to count packets from 0 for each new command */
- net.pkt_nr= 0;
-
- if ((packet_length=my_net_read(&net)) == packet_error)
- {
- /* Check if we can continue without closing the connection */
- if (net.error != 3) // what is 3 - find out
- return 1;
- if (thread_registry->is_shutdown())
- return 1;
- net_send_error(&net, net.last_errno);
- net.error= 0;
- return 0;
- }
- else
- {
- if (thread_registry->is_shutdown())
- return 1;
- packet= (char*) net.read_pos;
- enum enum_server_command command= (enum enum_server_command)
- (uchar) *packet;
- log_info("Connection %lu: received packet (length: %lu; command: %d).",
- (unsigned long) connection_id,
- (unsigned long) packet_length,
- (int) command);
-
- return dispatch_command(command, packet + 1);
- }
-}
-
-int Mysql_connection::dispatch_command(enum enum_server_command command,
- const char *packet)
-{
- switch (command) {
- case COM_QUIT: // client exit
- log_info("Connection %lu: received QUIT command.",
- (unsigned long) connection_id);
- return 1;
-
- case COM_PING:
- log_info("Connection %lu: received PING command.",
- (unsigned long) connection_id);
- net_send_ok(&net, connection_id, NULL);
- return 0;
-
- case COM_QUERY:
- {
- log_info("Connection %lu: received QUERY command: '%s'.",
- (unsigned long) connection_id,
- (const char *) packet);
-
- if (Command *com= parse_command(packet))
- {
- int res= 0;
-
- log_info("Connection %lu: query parsed successfully.",
- (unsigned long) connection_id);
-
- res= com->execute(&net, connection_id);
- delete com;
- if (!res)
- {
- log_info("Connection %lu: query executed successfully",
- (unsigned long) connection_id);
- }
- else
- {
- log_info("Connection %lu: can not execute query (error: %d).",
- (unsigned long) connection_id,
- (int) res);
-
- net_send_error(&net, res);
- }
- }
- else
- {
- log_error("Connection %lu: can not parse query: out ot resources.",
- (unsigned long) connection_id);
-
- net_send_error(&net,ER_OUT_OF_RESOURCES);
- }
-
- return 0;
- }
-
- default:
- log_info("Connection %lu: received unsupported command (%d).",
- (unsigned long) connection_id,
- (int) command);
-
- net_send_error(&net, ER_UNKNOWN_COM_ERROR);
- return 0;
- }
-
- return 0; /* Just to make compiler happy. */
-}
-
-
-void Mysql_connection::run()
-{
- if (init())
- log_error("Connection %lu: can not init handler.",
- (unsigned long) connection_id);
- else
- {
- main();
- cleanup();
- }
-
- delete this;
-}
-
-/*
- vim: fdm=marker
-*/
diff --git a/server-tools/instance-manager/mysql_connection.h b/server-tools/instance-manager/mysql_connection.h
deleted file mode 100644
index 56bbf76e146..00000000000
--- a/server-tools/instance-manager/mysql_connection.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
-
-#include "thread_registry.h"
-#include <mysql_com.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-struct st_vio;
-class User_map;
-
-/*
- MySQL connection - handle one connection with mysql command line client
- See also comments in mysqlmanager.cc to picture general Instance Manager
- architecture.
- We use conventional technique to work with classes without exceptions:
- class acquires all vital resource in init(); Thus if init() succeed,
- a user must call cleanup(). All other methods are valid only between
- init() and cleanup().
-*/
-
-class Mysql_connection: public Thread
-{
-public:
- Mysql_connection(Thread_registry *thread_registry_arg,
- User_map *user_map_arg,
- struct st_vio *vio_arg,
- ulong connection_id_arg);
- virtual ~Mysql_connection();
-
-protected:
- virtual void run();
-
-private:
- struct st_vio *vio;
- ulong connection_id;
- Thread_info thread_info;
- Thread_registry *thread_registry;
- User_map *user_map;
- NET net;
- struct rand_struct rand_st;
- char scramble[SCRAMBLE_LENGTH + 1];
- uint status;
- ulong client_capabilities;
-private:
- /* The main loop implementation triad */
- bool init();
- void main();
- void cleanup();
-
- /* Names are conventionally the same as in mysqld */
- int check_connection();
- int do_command();
- int dispatch_command(enum enum_server_command command, const char *text);
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
diff --git a/server-tools/instance-manager/mysql_manager_error.h b/server-tools/instance-manager/mysql_manager_error.h
deleted file mode 100644
index e50e5d24f6d..00000000000
--- a/server-tools/instance-manager/mysql_manager_error.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Definefile for instance manager error messagenumbers */
-
-#define ER_BAD_INSTANCE_NAME 3000
-#define ER_INSTANCE_IS_NOT_STARTED 3001
-#define ER_INSTANCE_ALREADY_STARTED 3002
-#define ER_CANNOT_START_INSTANCE 3003
-#define ER_STOP_INSTANCE 3004
-#define ER_NO_SUCH_LOG 3005
-#define ER_OPEN_LOGFILE 3006
-#define ER_GUESS_LOGFILE 3007
-#define ER_ACCESS_OPTION_FILE 3008
-#define ER_OFFSET_ERROR 3009
-#define ER_READ_FILE 3010
-#define ER_DROP_ACTIVE_INSTANCE 3011
-#define ER_CREATE_EXISTING_INSTANCE 3012
-#define ER_INSTANCE_MISCONFIGURED 3013
-#define ER_MALFORMED_INSTANCE_NAME 3014
-#define ER_INSTANCE_IS_ACTIVE 3015
-#define ER_THERE_IS_ACTIVE_INSTACE 3016
-#define ER_INCOMPATIBLE_OPTION 3017
-#define ER_CONF_FILE_DOES_NOT_EXIST 3018
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H */
diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc
deleted file mode 100644
index 276d1ca3b49..00000000000
--- a/server-tools/instance-manager/mysqlmanager.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_dir.h>
-#include <my_sys.h>
-
-#include <string.h>
-
-#ifndef __WIN__
-#include <pwd.h>
-#include <grp.h>
-#endif
-
-#include "angel.h"
-#include "log.h"
-#include "manager.h"
-#include "options.h"
-#include "user_management_commands.h"
-
-#ifdef __WIN__
-#include "IMService.h"
-#endif
-
-
-/*
- Instance Manager consists of two processes: the angel process (IM-angel),
- and the manager process (IM-main). Responsibilities of IM-angel is to
- monitor IM-main, and restart it in case of failure/shutdown. IM-angel is
- started only if startup option '--run-as-service' is provided.
-
- IM-main consists of several subsystems (thread sets):
-
- - the signal handling thread
-
- The signal thread handles user signals and propagates them to the
- other threads. All other threads are accounted in the signal handler
- thread Thread Registry.
-
- - the listener
-
- The listener listens to all sockets. There is a listening socket for
- each subsystem (TCP/IP, UNIX socket).
-
- - mysql subsystem
-
- Instance Manager acts like an ordinary MySQL Server, but with very
- restricted command set. Each MySQL client connection is handled in a
- separate thread. All MySQL client connections threads constitute
- mysql subsystem.
-*/
-
-static int main_impl(int argc, char *argv[]);
-
-#ifndef __WIN__
-static struct passwd *check_user();
-static bool switch_user();
-#endif
-
-
-/************************************************************************/
-/**
- The entry point.
-*************************************************************************/
-
-int main(int argc, char *argv[])
-{
- int return_value;
-
- puts("\n"
- "WARNING: This program is deprecated and will be removed in 6.0.\n");
-
- /* Initialize. */
-
- MY_INIT(argv[0]);
- log_init();
- umask(0117);
- srand((uint) time(0));
-
- /* Main function. */
-
- log_info("IM: started.");
-
- return_value= main_impl(argc, argv);
-
- log_info("IM: finished.");
-
- /* Cleanup. */
-
- Options::cleanup();
- my_end(0);
-
- return return_value;
-}
-
-
-/************************************************************************/
-/**
- Instance Manager main functionality.
-*************************************************************************/
-
-int main_impl(int argc, char *argv[])
-{
- int rc;
-
- if ((rc= Options::load(argc, argv)))
- return rc;
-
- if (Options::User_management::cmd)
- return Options::User_management::cmd->execute();
-
-#ifndef __WIN__
-
- if (switch_user())
- return 1;
-
- return Options::Daemon::run_as_service ?
- Angel::main() :
- Manager::main();
-
-#else
-
- return Options::Service::stand_alone ?
- Manager::main() :
- IMService::main();
-
-#endif
-}
-
-/**************************************************************************
- OS-specific functions implementation.
-**************************************************************************/
-
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
-
-/************************************************************************/
-/**
- Change to run as another user if started with --user.
-*************************************************************************/
-
-static struct passwd *check_user()
-{
- const char *user= Options::Daemon::user;
- struct passwd *user_info;
- uid_t user_id= geteuid();
-
- /* Don't bother if we aren't superuser */
- if (user_id)
- {
- if (user)
- {
- /* Don't give a warning, if real user is same as given with --user */
- user_info= getpwnam(user);
- if ((!user_info || user_id != user_info->pw_uid))
- log_info("One can only use the --user switch if running as root\n");
- }
- return NULL;
- }
- if (!user)
- {
- log_info("You are running mysqlmanager as root! This might introduce security problems. It is safer to use --user option istead.\n");
- return NULL;
- }
- if (!strcmp(user, "root"))
- return NULL; /* Avoid problem with dynamic libraries */
- if (!(user_info= getpwnam(user)))
- {
- /* Allow a numeric uid to be used */
- const char *pos;
- for (pos= user; my_isdigit(default_charset_info, *pos); pos++)
- {}
- if (*pos) /* Not numeric id */
- goto err;
- if (!(user_info= getpwuid(atoi(user))))
- goto err;
- else
- return user_info;
- }
- else
- return user_info;
-
-err:
- log_error("Can not start under user '%s'.",
- (const char *) user);
- return NULL;
-}
-
-
-/************************************************************************/
-/**
- Switch user.
-*************************************************************************/
-
-static bool switch_user()
-{
- struct passwd *user_info= check_user();
-
- if (!user_info)
- return FALSE;
-
-#ifdef HAVE_INITGROUPS
- initgroups(Options::Daemon::user, user_info->pw_gid);
-#endif
-
- if (setgid(user_info->pw_gid) == -1)
- {
- log_error("setgid() failed");
- return TRUE;
- }
-
- if (setuid(user_info->pw_uid) == -1)
- {
- log_error("setuid() failed");
- return TRUE;
- }
-
- return FALSE;
-}
-
-#endif
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
deleted file mode 100644
index ebca593bb03..00000000000
--- a/server-tools/instance-manager/options.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "options.h"
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <my_getopt.h>
-#include <mysql_com.h>
-
-#include "exit_codes.h"
-#include "log.h"
-#include "portability.h"
-#include "priv.h"
-#include "user_management_commands.h"
-
-#define QUOTE2(x) #x
-#define QUOTE(x) QUOTE2(x)
-
-#ifdef __WIN__
-
-/* Define holders for default values. */
-
-static char win_dflt_config_file_name[FN_REFLEN];
-static char win_dflt_password_file_name[FN_REFLEN];
-static char win_dflt_pid_file_name[FN_REFLEN];
-
-static char win_dflt_mysqld_path[FN_REFLEN];
-
-/* Define and initialize Windows-specific options. */
-
-my_bool Options::Service::install_as_service;
-my_bool Options::Service::remove_service;
-my_bool Options::Service::stand_alone;
-
-const char *Options::Main::config_file= win_dflt_config_file_name;
-const char *Options::Main::password_file_name= win_dflt_password_file_name;
-const char *Options::Main::pid_file_name= win_dflt_pid_file_name;
-
-const char *Options::Main::default_mysqld_path= win_dflt_mysqld_path;
-
-static int setup_windows_defaults();
-
-#else /* UNIX */
-
-/* Define and initialize UNIX-specific options. */
-
-my_bool Options::Daemon::run_as_service= FALSE;
-const char *Options::Daemon::log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
-const char *Options::Daemon::user= NULL; /* No default value */
-const char *Options::Daemon::angel_pid_file_name= NULL;
-
-const char *Options::Main::config_file= QUOTE(DEFAULT_CONFIG_FILE);
-const char *
-Options::Main::password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
-const char *Options::Main::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
-const char *Options::Main::socket_file_name= QUOTE(DEFAULT_SOCKET_FILE_NAME);
-
-const char *Options::Main::default_mysqld_path= QUOTE(DEFAULT_MYSQLD_PATH);
-
-#endif
-
-/* Remember if the config file was forced. */
-
-bool Options::Main::is_forced_default_file= FALSE;
-
-/* Define and initialize common options. */
-
-const char *Options::Main::bind_address= NULL; /* No default value */
-uint Options::Main::monitoring_interval= DEFAULT_MONITORING_INTERVAL;
-uint Options::Main::port_number= DEFAULT_PORT;
-my_bool Options::Main::mysqld_safe_compatible= FALSE;
-const char **Options::default_directories= NULL;
-
-/* Options::User_management */
-
-char *Options::User_management::user_name= NULL;
-char *Options::User_management::password= NULL;
-
-User_management_cmd *Options::User_management::cmd= NULL;
-
-/* Private members. */
-
-char **Options::saved_argv= NULL;
-
-#ifndef DBUG_OFF
-const char *Options::Debug::config_str= "d:t:i:O,im.trace";
-#endif
-
-static const char * const ANGEL_PID_FILE_SUFFIX= ".angel.pid";
-static const int ANGEL_PID_FILE_SUFFIX_LEN= (uint) strlen(ANGEL_PID_FILE_SUFFIX);
-
-/*
- List of options, accepted by the instance manager.
- List must be closed with empty option.
-*/
-
-enum options {
- OPT_USERNAME= 'u',
- OPT_PASSWORD= 'p',
- OPT_LOG= 256,
- OPT_PID_FILE,
- OPT_SOCKET,
- OPT_PASSWORD_FILE,
- OPT_MYSQLD_PATH,
-#ifdef __WIN__
- OPT_INSTALL_SERVICE,
- OPT_REMOVE_SERVICE,
- OPT_STAND_ALONE,
-#else
- OPT_RUN_AS_SERVICE,
- OPT_USER,
- OPT_ANGEL_PID_FILE,
-#endif
- OPT_MONITORING_INTERVAL,
- OPT_PORT,
- OPT_WAIT_TIMEOUT,
- OPT_BIND_ADDRESS,
- OPT_PRINT_PASSWORD_LINE,
- OPT_ADD_USER,
- OPT_DROP_USER,
- OPT_EDIT_USER,
- OPT_CLEAN_PASSWORD_FILE,
- OPT_CHECK_PASSWORD_FILE,
- OPT_LIST_USERS,
- OPT_MYSQLD_SAFE_COMPATIBLE
-};
-
-static struct my_option my_long_options[] =
-{
- { "help", '?', "Display this help and exit.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "add-user", OPT_ADD_USER,
- "Add a user to the password file",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
-#ifndef __WIN__
- { "angel-pid-file", OPT_ANGEL_PID_FILE, "Pid file for angel process.",
- (uchar* *) &Options::Daemon::angel_pid_file_name,
- (uchar* *) &Options::Daemon::angel_pid_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-#endif
-
- { "bind-address", OPT_BIND_ADDRESS, "Bind address to use for connection.",
- (uchar* *) &Options::Main::bind_address,
- (uchar* *) &Options::Main::bind_address,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "check-password-file", OPT_CHECK_PASSWORD_FILE,
- "Check the password file for consistency",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "clean-password-file", OPT_CLEAN_PASSWORD_FILE,
- "Clean the password file",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
-#ifndef DBUG_OFF
- {"debug", '#', "Debug log.",
- (uchar* *) &Options::Debug::config_str,
- (uchar* *) &Options::Debug::config_str,
- 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#endif
-
- { "default-mysqld-path", OPT_MYSQLD_PATH, "Where to look for MySQL"
- " Server binary.",
- (uchar* *) &Options::Main::default_mysqld_path,
- (uchar* *) &Options::Main::default_mysqld_path,
- 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "drop-user", OPT_DROP_USER,
- "Drop existing user from the password file",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "edit-user", OPT_EDIT_USER,
- "Edit existing user in the password file",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
-#ifdef __WIN__
- { "install", OPT_INSTALL_SERVICE, "Install as system service.",
- (uchar* *) &Options::Service::install_as_service,
- (uchar* *) &Options::Service::install_as_service,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
-#endif
-
- { "list-users", OPT_LIST_USERS,
- "Print out a list of registered users",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
-#ifndef __WIN__
- { "log", OPT_LOG, "Path to log file. Used only with --run-as-service.",
- (uchar* *) &Options::Daemon::log_file_name,
- (uchar* *) &Options::Daemon::log_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-#endif
-
- { "monitoring-interval", OPT_MONITORING_INTERVAL, "Interval to monitor"
- " instances in seconds.",
- (uchar* *) &Options::Main::monitoring_interval,
- (uchar* *) &Options::Main::monitoring_interval,
- 0, GET_UINT, REQUIRED_ARG, DEFAULT_MONITORING_INTERVAL,
- 0, 0, 0, 0, 0 },
-
- { "mysqld-safe-compatible", OPT_MYSQLD_SAFE_COMPATIBLE,
- "Start Instance Manager in mysqld_safe compatible manner",
- (uchar* *) &Options::Main::mysqld_safe_compatible,
- (uchar* *) &Options::Main::mysqld_safe_compatible,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
-
- { "print-password-line", OPT_PRINT_PASSWORD_LINE,
- "Print out a user entry as a line for the password file and exit.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "password", OPT_PASSWORD, "Password to update the password file",
- (uchar* *) &Options::User_management::password,
- (uchar* *) &Options::User_management::password,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "password-file", OPT_PASSWORD_FILE,
- "Look for Instance Manager users and passwords here.",
- (uchar* *) &Options::Main::password_file_name,
- (uchar* *) &Options::Main::password_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "pid-file", OPT_PID_FILE, "Pid file to use.",
- (uchar* *) &Options::Main::pid_file_name,
- (uchar* *) &Options::Main::pid_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "port", OPT_PORT, "Port number to use for connections",
- (uchar* *) &Options::Main::port_number,
- (uchar* *) &Options::Main::port_number,
- 0, GET_UINT, REQUIRED_ARG, DEFAULT_PORT, 0, 0, 0, 0, 0 },
-
-#ifdef __WIN__
- { "remove", OPT_REMOVE_SERVICE, "Remove system service.",
- (uchar* *) &Options::Service::remove_service,
- (uchar* *) &Options::Service::remove_service,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
-#else
- { "run-as-service", OPT_RUN_AS_SERVICE,
- "Daemonize and start angel process.",
- (uchar* *) &Options::Daemon::run_as_service,
- 0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
-#endif
-
-#ifndef __WIN__
- { "socket", OPT_SOCKET, "Socket file to use for connection.",
- (uchar* *) &Options::Main::socket_file_name,
- (uchar* *) &Options::Main::socket_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-#endif
-
-#ifdef __WIN__
- { "standalone", OPT_STAND_ALONE, "Run the application in stand alone mode.",
- (uchar* *) &Options::Service::stand_alone,
- (uchar* *) &Options::Service::stand_alone,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
-#else
- { "user", OPT_USER, "Username to start mysqlmanager",
- (uchar* *) &Options::Daemon::user,
- (uchar* *) &Options::Daemon::user,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-#endif
-
- { "username", OPT_USERNAME,
- "Username to update the password file",
- (uchar* *) &Options::User_management::user_name,
- (uchar* *) &Options::User_management::user_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "version", 'V', "Output version information and exit.", 0, 0, 0,
- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "wait-timeout", OPT_WAIT_TIMEOUT, "The number of seconds IM waits "
- "for activity on a connection before closing it.",
- (uchar* *) &net_read_timeout,
- (uchar* *) &net_read_timeout,
- 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0 },
-
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
-};
-
-static void version()
-{
- printf("%s Ver %s for %s on %s\n", my_progname,
- (const char *) mysqlmanager_version.str,
- SYSTEM_TYPE, MACHINE_TYPE);
-}
-
-
-static const char *default_groups[]= { "manager", 0 };
-
-
-static void usage()
-{
- version();
-
- printf("Copyright (C) 2003, 2004 MySQL AB\n"
- "This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
- "and you are welcome to modify and redistribute it under the GPL license\n");
- printf("Usage: %s [OPTIONS] \n", my_progname);
-
- my_print_help(my_long_options);
- printf("\nThe following options may be given as the first argument:\n"
- "--print-defaults Print the program argument list and exit\n"
- "--defaults-file=# Only read manager configuration and instance\n"
- " setings from the given file #. The same file\n"
- " will be used to modify configuration of instances\n"
- " with SET commands.\n");
- my_print_variables(my_long_options);
-}
-
-
-C_MODE_START
-
-static my_bool
-get_one_option(int optid,
- const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- switch(optid) {
- case 'V':
- version();
- exit(0);
- case OPT_PRINT_PASSWORD_LINE:
- case OPT_ADD_USER:
- case OPT_DROP_USER:
- case OPT_EDIT_USER:
- case OPT_CLEAN_PASSWORD_FILE:
- case OPT_CHECK_PASSWORD_FILE:
- case OPT_LIST_USERS:
- if (Options::User_management::cmd)
- {
- fprintf(stderr, "Error: only one password-management command "
- "can be specified at a time.\n");
- exit(ERR_INVALID_USAGE);
- }
-
- switch (optid) {
- case OPT_PRINT_PASSWORD_LINE:
- Options::User_management::cmd= new Print_password_line_cmd();
- break;
- case OPT_ADD_USER:
- Options::User_management::cmd= new Add_user_cmd();
- break;
- case OPT_DROP_USER:
- Options::User_management::cmd= new Drop_user_cmd();
- break;
- case OPT_EDIT_USER:
- Options::User_management::cmd= new Edit_user_cmd();
- break;
- case OPT_CLEAN_PASSWORD_FILE:
- Options::User_management::cmd= new Clean_db_cmd();
- break;
- case OPT_CHECK_PASSWORD_FILE:
- Options::User_management::cmd= new Check_db_cmd();
- break;
- case OPT_LIST_USERS:
- Options::User_management::cmd= new List_users_cmd();
- break;
- }
-
- break;
- case '?':
- usage();
- exit(0);
- case '#':
-#ifndef DBUG_OFF
- DBUG_SET(argument ? argument : Options::Debug::config_str);
- DBUG_SET_INITIAL(argument ? argument : Options::Debug::config_str);
-#endif
- break;
- }
- return 0;
-}
-
-C_MODE_END
-
-
-/*
- - Process argv of original program: get tid of --defaults-extra-file
- and print a message if met there.
- - call load_defaults to load configuration file section and save the pointer
- for free_defaults.
- - call handle_options to assign defaults and command-line arguments
- to the class members.
- if either of these function fail, return the error code.
-*/
-
-int Options::load(int argc, char **argv)
-{
- if (argc >= 2)
- {
- if (is_prefix(argv[1], "--defaults-file="))
- {
- Main::config_file= strchr(argv[1], '=') + 1;
- Main::is_forced_default_file= TRUE;
- }
- if (is_prefix(argv[1], "--defaults-extra-file=") ||
- is_prefix(argv[1], "--no-defaults"))
- {
- /* the log is not enabled yet */
- fprintf(stderr, "The --defaults-extra-file and --no-defaults options"
- " are not supported by\n"
- "Instance Manager. Program aborted.\n");
- return ERR_INVALID_USAGE;
- }
- }
-
-#ifdef __WIN__
- if (setup_windows_defaults())
- {
- fprintf(stderr, "Internal error: could not setup default values.\n");
- return ERR_OUT_OF_MEMORY;
- }
-#endif
-
- /* load_defaults will reset saved_argv with a new allocated list */
- saved_argv= argv;
-
- /* config-file options are prepended to command-line ones */
-
- log_info("Loading config file '%s'...",
- (const char *) Main::config_file);
-
- my_load_defaults(Main::config_file, default_groups, &argc,
- &saved_argv, &default_directories);
-
- if ((handle_options(&argc, &saved_argv, my_long_options, get_one_option)))
- return ERR_INVALID_USAGE;
-
- if (!User_management::cmd &&
- (User_management::user_name || User_management::password))
- {
- fprintf(stderr,
- "--username and/or --password options have been specified, "
- "but no password-management command has been given.\n");
- return ERR_INVALID_USAGE;
- }
-
-#ifndef __WIN__
- if (Options::Daemon::run_as_service)
- {
- if (Options::Daemon::angel_pid_file_name == NULL)
- {
- /*
- Calculate angel pid file on the IM pid file basis: replace the
- extension (everything after the last dot) of the pid file basename to
- '.angel.pid'.
- */
-
- char *local_angel_pid_file_name;
- char *base_name_ptr;
- char *ext_ptr;
-
- local_angel_pid_file_name=
- (char *) malloc(strlen(Options::Main::pid_file_name) +
- ANGEL_PID_FILE_SUFFIX_LEN);
-
- strcpy(local_angel_pid_file_name, Options::Main::pid_file_name);
-
- base_name_ptr= strrchr(local_angel_pid_file_name, '/');
-
- if (!base_name_ptr)
- base_name_ptr= local_angel_pid_file_name + 1;
-
- ext_ptr= strrchr(base_name_ptr, '.');
- if (ext_ptr)
- *ext_ptr= 0;
-
- strcat(local_angel_pid_file_name, ANGEL_PID_FILE_SUFFIX);
-
- Options::Daemon::angel_pid_file_name= local_angel_pid_file_name;
- }
- else
- {
- Options::Daemon::angel_pid_file_name=
- strdup(Options::Daemon::angel_pid_file_name);
- }
- }
-#endif
-
- return 0;
-}
-
-void Options::cleanup()
-{
- if (saved_argv)
- free_defaults(saved_argv);
-
- delete User_management::cmd;
-
-#ifndef __WIN__
- if (Options::Daemon::run_as_service)
- free((void *) Options::Daemon::angel_pid_file_name);
-#endif
-}
-
-#ifdef __WIN__
-
-static int setup_windows_defaults()
-{
- char module_full_name[FN_REFLEN];
- char dir_name[FN_REFLEN];
- char base_name[FN_REFLEN];
- char im_name[FN_REFLEN];
- char *base_name_ptr;
- char *ptr;
-
- /* Determine dirname and basename. */
-
- if (!GetModuleFileName(NULL, module_full_name, sizeof (module_full_name)) ||
- !GetFullPathName(module_full_name, sizeof (dir_name), dir_name,
- &base_name_ptr))
- {
- return 1;
- }
-
- strmake(base_name, base_name_ptr, FN_REFLEN);
- *base_name_ptr= 0;
-
- strmake(im_name, base_name, FN_REFLEN);
- ptr= strrchr(im_name, '.');
-
- if (!ptr)
- return 1;
-
- *ptr= 0;
-
- /* Initialize the defaults. */
-
- strxmov(win_dflt_config_file_name, dir_name, DFLT_CONFIG_FILE_NAME, NullS);
- strxmov(win_dflt_mysqld_path, dir_name, DFLT_MYSQLD_PATH, NullS);
- strxmov(win_dflt_password_file_name, dir_name, im_name, DFLT_PASSWD_FILE_EXT,
- NullS);
- strxmov(win_dflt_pid_file_name, dir_name, im_name, DFLT_PID_FILE_EXT, NullS);
-
- return 0;
-}
-
-#endif
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
deleted file mode 100644
index 5d4df51faae..00000000000
--- a/server-tools/instance-manager/options.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright (C) 2003-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
-
-/*
- Options - all possible command-line options for the Instance Manager grouped
- in one struct.
-*/
-
-#include <my_global.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-class User_management_cmd;
-
-struct Options
-{
- /*
- NOTE: handle_options() expects value of my_bool type for GET_BOOL
- accessor (i.e. bool must not be used).
- */
-
- struct User_management
- {
- static User_management_cmd *cmd;
-
- static char *user_name;
- static char *password;
- };
-
- struct Main
- {
- /* this is not an option parsed by handle_options(). */
- static bool is_forced_default_file;
-
- static const char *pid_file_name;
-#ifndef __WIN__
- static const char *socket_file_name;
-#endif
- static const char *password_file_name;
- static const char *default_mysqld_path;
- static uint monitoring_interval;
- static uint port_number;
- static const char *bind_address;
- static const char *config_file;
- static my_bool mysqld_safe_compatible;
- };
-
-#ifndef DBUG_OFF
- struct Debug
- {
- static const char *config_str;
- };
-#endif
-
-#ifndef __WIN__
-
- struct Daemon
- {
- static my_bool run_as_service;
- static const char *log_file_name;
- static const char *user;
- static const char *angel_pid_file_name;
- };
-
-#else
-
- struct Service
- {
- static my_bool install_as_service;
- static my_bool remove_service;
- static my_bool stand_alone;
- };
-
-#endif
-
-public:
- /* Array of paths to be passed to my_search_option_files() later */
- static const char **default_directories;
-
- static int load(int argc, char **argv);
- static void cleanup();
-
-private:
- Options(); /* Deny instantiation of this class. */
-
-private:
- /* argv pointer returned by load_defaults() to be used by free_defaults() */
- static char **saved_argv;
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
deleted file mode 100644
index cd20e3bc7ab..00000000000
--- a/server-tools/instance-manager/parse.cc
+++ /dev/null
@@ -1,509 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "parse.h"
-#include "commands.h"
-
-
-enum Token
-{
- TOK_CREATE= 0,
- TOK_DROP,
- TOK_ERROR, /* Encodes the "ERROR" word, it doesn't indicate error. */
- TOK_FILES,
- TOK_FLUSH,
- TOK_GENERAL,
- TOK_INSTANCE,
- TOK_INSTANCES,
- TOK_LOG,
- TOK_OPTIONS,
- TOK_SET,
- TOK_SLOW,
- TOK_START,
- TOK_STATUS,
- TOK_STOP,
- TOK_SHOW,
- TOK_UNSET,
- TOK_NOT_FOUND, // must be after all tokens
- TOK_END
-};
-
-
-struct tokens_st
-{
- uint length;
- const char *tok_name;
-};
-
-
-static struct tokens_st tokens[]= {
- {6, "CREATE"},
- {4, "DROP"},
- {5, "ERROR"},
- {5, "FILES"},
- {5, "FLUSH"},
- {7, "GENERAL"},
- {8, "INSTANCE"},
- {9, "INSTANCES"},
- {3, "LOG"},
- {7, "OPTIONS"},
- {3, "SET"},
- {4, "SLOW"},
- {5, "START"},
- {6, "STATUS"},
- {4, "STOP"},
- {4, "SHOW"},
- {5, "UNSET"}
-};
-
-/************************************************************************/
-
-Named_value_arr::Named_value_arr() :
- initialized(FALSE)
-{
-}
-
-
-bool Named_value_arr::init()
-{
- if (my_init_dynamic_array(&arr, sizeof(Named_value), 0, 32))
- return TRUE;
-
- initialized= TRUE;
-
- return FALSE;
-}
-
-
-Named_value_arr::~Named_value_arr()
-{
- if (!initialized)
- return;
-
- for (int i= 0; i < get_size(); ++i)
- get_element(i).free();
-
- delete_dynamic(&arr);
-}
-
-/************************************************************************/
-
-/*
- Returns token no if word corresponds to some token, otherwise returns
- TOK_NOT_FOUND
-*/
-
-inline Token find_token(const char *word, size_t word_len)
-{
- int i= 0;
- do
- {
- if (my_strnncoll(default_charset_info, (const uchar *) tokens[i].tok_name,
- tokens[i].length, (const uchar *) word, word_len) == 0)
- break;
- }
- while (++i < TOK_NOT_FOUND);
- return (Token) i;
-}
-
-
-Token get_token(const char **text, size_t *word_len)
-{
- get_word(text, word_len);
- if (*word_len)
- return find_token(*text, *word_len);
- return TOK_END;
-}
-
-
-Token shift_token(const char **text, size_t *word_len)
-{
- Token save= get_token(text, word_len);
- (*text)+= *word_len;
- return save;
-}
-
-
-int get_text_id(const char **text, LEX_STRING *token)
-{
- get_word(text, &token->length);
- if (token->length == 0)
- return 1;
- token->str= (char *) *text;
- return 0;
-}
-
-
-static bool parse_long(const LEX_STRING *token, long *value)
-{
- int err_code;
- char *end_ptr= token->str + token->length;
-
- *value= (long)my_strtoll10(token->str, &end_ptr, &err_code);
-
- return err_code != 0;
-}
-
-
-bool parse_option_value(const char *text, size_t *text_len, char **value)
-{
- char beginning_quote;
- const char *text_start_ptr;
- char *v;
- bool escape_mode= FALSE;
-
- if (!*text || (*text != '\'' && *text != '"'))
- return TRUE; /* syntax error: string expected. */
-
- beginning_quote= *text;
-
- ++text; /* skip the beginning quote. */
-
- text_start_ptr= text;
-
- if (!(v= Named_value::alloc_str(text)))
- return TRUE;
-
- *value= v;
-
- while (TRUE)
- {
- if (!*text)
- {
- Named_value::free_str(value);
- return TRUE; /* syntax error: missing terminating ' character. */
- }
-
- if (*text == '\n' || *text == '\r')
- {
- Named_value::free_str(value);
- return TRUE; /* syntax error: option value should be a single line. */
- }
-
- if (!escape_mode && *text == beginning_quote)
- break;
-
- if (escape_mode)
- {
- switch (*text)
- {
- case 'b': /* \b -- backspace */
- if (v > *value)
- --v;
- break;
-
- case 't': /* \t -- tab */
- *v= '\t';
- ++v;
- break;
-
- case 'n': /* \n -- newline */
- *v= '\n';
- ++v;
- break;
-
- case 'r': /* \r -- carriage return */
- *v= '\r';
- ++v;
- break;
-
- case '\\': /* \\ -- back slash */
- *v= '\\';
- ++v;
- break;
-
- case 's': /* \s -- space */
- *v= ' ';
- ++v;
- break;
-
- default: /* Unknown escape sequence. Treat as error. */
- Named_value::free_str(value);
- return TRUE;
- }
-
- escape_mode= FALSE;
- }
- else
- {
- if (*text == '\\')
- {
- escape_mode= TRUE;
- }
- else
- {
- *v= *text;
- ++v;
- }
- }
-
- ++text;
- }
-
- *v= 0;
-
- /* "2" below stands for beginning and ending quotes. */
- *text_len= text - text_start_ptr + 2;
-
- return FALSE;
-}
-
-
-void skip_spaces(const char **text)
-{
- while (**text && my_isspace(default_charset_info, **text))
- ++(*text);
-}
-
-
-Command *parse_command(const char *text)
-{
- size_t word_len;
- LEX_STRING instance_name;
- Command *command= 0;
-
- Token tok1= shift_token(&text, &word_len);
-
- switch (tok1) {
- case TOK_START: // fallthrough
- case TOK_STOP:
- case TOK_CREATE:
- case TOK_DROP:
- if (shift_token(&text, &word_len) != TOK_INSTANCE)
- goto syntax_error;
- get_word(&text, &word_len);
- if (word_len == 0)
- goto syntax_error;
- instance_name.str= (char *) text;
- instance_name.length= word_len;
- text+= word_len;
-
- if (tok1 == TOK_CREATE)
- {
- Create_instance *cmd= new Create_instance(&instance_name);
-
- if (!cmd)
- return NULL; /* Report ER_OUT_OF_RESOURCES. */
-
- if (cmd->init(&text))
- {
- delete cmd;
- goto syntax_error;
- }
-
- command= cmd;
- }
- else
- {
- /* it should be the end of command */
- get_word(&text, &word_len, NONSPACE);
- if (word_len)
- goto syntax_error;
- }
-
- switch (tok1) {
- case TOK_START:
- command= new Start_instance(&instance_name);
- break;
- case TOK_STOP:
- command= new Stop_instance(&instance_name);
- break;
- case TOK_CREATE:
- ; /* command already initialized. */
- break;
- case TOK_DROP:
- command= new Drop_instance(&instance_name);
- break;
- default: /* this is impossible, but nevertheless... */
- DBUG_ASSERT(0);
- }
- break;
- case TOK_FLUSH:
- if (shift_token(&text, &word_len) != TOK_INSTANCES)
- goto syntax_error;
-
- get_word(&text, &word_len, NONSPACE);
- if (word_len)
- goto syntax_error;
-
- command= new Flush_instances();
- break;
- case TOK_UNSET:
- case TOK_SET:
- {
- Abstract_option_cmd *cmd;
-
- if (tok1 == TOK_SET)
- cmd= new Set_option();
- else
- cmd= new Unset_option();
-
- if (!cmd)
- return NULL; /* Report ER_OUT_OF_RESOURCES. */
-
- if (cmd->init(&text))
- {
- delete cmd;
- goto syntax_error;
- }
-
- command= cmd;
-
- break;
- }
- case TOK_SHOW:
- switch (shift_token(&text, &word_len)) {
- case TOK_INSTANCES:
- get_word(&text, &word_len, NONSPACE);
- if (word_len)
- goto syntax_error;
- command= new Show_instances();
- break;
- case TOK_INSTANCE:
- switch (Token tok2= shift_token(&text, &word_len)) {
- case TOK_OPTIONS:
- case TOK_STATUS:
- if (get_text_id(&text, &instance_name))
- goto syntax_error;
- text+= instance_name.length;
- /* check that this is the end of the command */
- get_word(&text, &word_len, NONSPACE);
- if (word_len)
- goto syntax_error;
- if (tok2 == TOK_STATUS)
- command= new Show_instance_status(&instance_name);
- else
- command= new Show_instance_options(&instance_name);
- break;
- default:
- goto syntax_error;
- }
- break;
- default:
- instance_name.str= (char *) text - word_len;
- instance_name.length= word_len;
- if (instance_name.length)
- {
- Log_type log_type;
-
- long log_size;
- LEX_STRING log_size_str;
-
- long log_offset= 0;
- LEX_STRING log_offset_str= { NULL, 0 };
-
- switch (shift_token(&text, &word_len)) {
- case TOK_LOG:
- switch (Token tok3= shift_token(&text, &word_len)) {
- case TOK_FILES:
- get_word(&text, &word_len, NONSPACE);
- /* check that this is the end of the command */
- if (word_len)
- goto syntax_error;
- command= new Show_instance_log_files(&instance_name);
- break;
- case TOK_ERROR:
- case TOK_GENERAL:
- case TOK_SLOW:
- /* define a log type */
- switch (tok3) {
- case TOK_ERROR:
- log_type= IM_LOG_ERROR;
- break;
- case TOK_GENERAL:
- log_type= IM_LOG_GENERAL;
- break;
- case TOK_SLOW:
- log_type= IM_LOG_SLOW;
- break;
- default:
- goto syntax_error;
- }
- /* get the size of the log we want to retrieve */
- if (get_text_id(&text, &log_size_str))
- goto syntax_error;
- text+= log_size_str.length;
-
- /* this parameter is required */
- if (!log_size_str.length)
- goto syntax_error;
-
- /* the next token should be comma, or nothing */
- get_word(&text, &word_len);
- switch (*text) {
- case ',':
- text++; /* swallow the comma */
- /* read the next word */
- get_word(&text, &word_len);
- if (!word_len)
- goto syntax_error;
- log_offset_str.str= (char *) text;
- log_offset_str.length= word_len;
- text+= word_len;
- get_word(&text, &word_len, NONSPACE);
- /* check that this is the end of the command */
- if (word_len)
- goto syntax_error;
- break;
- case '\0':
- break; /* this is ok */
- default:
- goto syntax_error;
- }
-
- /* Parse size parameter. */
-
- if (parse_long(&log_size_str, &log_size))
- goto syntax_error;
-
- if (log_size <= 0)
- goto syntax_error;
-
- /* Parse offset parameter (if specified). */
-
- if (log_offset_str.length)
- {
- if (parse_long(&log_offset_str, &log_offset))
- goto syntax_error;
-
- if (log_offset <= 0)
- goto syntax_error;
- }
-
- command= new Show_instance_log(&instance_name,
- log_type, log_size, log_offset);
- break;
- default:
- goto syntax_error;
- }
- break;
- default:
- goto syntax_error;
- }
- }
- else
- goto syntax_error;
- break;
- }
- break;
- default:
-syntax_error:
- command= new Syntax_error();
- }
-
- DBUG_ASSERT(command);
-
- return command;
-}
diff --git a/server-tools/instance-manager/parse.h b/server-tools/instance-manager/parse.h
deleted file mode 100644
index 9c50ace5948..00000000000
--- a/server-tools/instance-manager/parse.h
+++ /dev/null
@@ -1,212 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-
-class Command;
-
-enum Log_type
-{
- IM_LOG_ERROR= 0,
- IM_LOG_GENERAL,
- IM_LOG_SLOW
-};
-
-Command *parse_command(const char *text);
-
-bool parse_option_value(const char *text, size_t *text_len, char **value);
-
-void skip_spaces(const char **text);
-
-/* define kinds of the word seek method */
-enum enum_seek_method { ALPHANUM= 1, NONSPACE, OPTION_NAME };
-
-/************************************************************************/
-
-class Named_value
-{
-public:
- /*
- The purpose of these methods is just to have one method for
- allocating/deallocating memory for strings for Named_value.
- */
-
- static inline char *alloc_str(const LEX_STRING *str);
- static inline char *alloc_str(const char *str);
- static inline void free_str(char **str);
-
-public:
- inline Named_value();
- inline Named_value(char *name_arg, char *value_arg);
-
- inline char *get_name();
- inline char *get_value();
-
- inline void free();
-
-private:
- char *name;
- char *value;
-};
-
-inline char *Named_value::alloc_str(const LEX_STRING *str)
-{
- return my_strndup(str->str, str->length, MYF(0));
-}
-
-inline char *Named_value::alloc_str(const char *str)
-{
- return my_strdup(str, MYF(0));
-}
-
-inline void Named_value::free_str(char **str)
-{
- my_free(*str, MYF(MY_ALLOW_ZERO_PTR));
- *str= NULL;
-}
-
-inline Named_value::Named_value()
- :name(NULL), value(NULL)
-{ }
-
-inline Named_value::Named_value(char *name_arg, char *value_arg)
- :name(name_arg), value(value_arg)
-{ }
-
-inline char *Named_value::get_name()
-{
- return name;
-}
-
-inline char *Named_value::get_value()
-{
- return value;
-}
-
-void Named_value::free()
-{
- free_str(&name);
- free_str(&value);
-}
-
-/************************************************************************/
-
-class Named_value_arr
-{
-public:
- Named_value_arr();
- ~Named_value_arr();
-
- bool init();
-
- inline int get_size() const;
- inline Named_value get_element(int idx) const;
- inline void remove_element(int idx);
- inline bool add_element(Named_value *option);
- inline bool replace_element(int idx, Named_value *option);
-
-private:
- bool initialized;
- DYNAMIC_ARRAY arr;
-};
-
-
-inline int Named_value_arr::get_size() const
-{
- return arr.elements;
-}
-
-
-inline Named_value Named_value_arr::get_element(int idx) const
-{
- DBUG_ASSERT(0 <= idx && (uint) idx < arr.elements);
-
- Named_value option;
- get_dynamic((DYNAMIC_ARRAY *) &arr, (uchar*) &option, idx);
-
- return option;
-}
-
-
-inline void Named_value_arr::remove_element(int idx)
-{
- DBUG_ASSERT(0 <= idx && (uint) idx < arr.elements);
-
- get_element(idx).free();
-
- delete_dynamic_element(&arr, idx);
-}
-
-
-inline bool Named_value_arr::add_element(Named_value *option)
-{
- return insert_dynamic(&arr, (uchar*) option);
-}
-
-
-inline bool Named_value_arr::replace_element(int idx, Named_value *option)
-{
- DBUG_ASSERT(0 <= idx && (uint) idx < arr.elements);
-
- get_element(idx).free();
-
- return set_dynamic(&arr, (uchar*) option, idx);
-}
-
-/************************************************************************/
-
-/*
- tries to find next word in the text
- if found, returns the beginning and puts word length to word_len argument.
- if not found returns pointer to first non-space or to '\0', word_len == 0
-*/
-
-inline void get_word(const char **text, size_t *word_len,
- enum_seek_method seek_method= ALPHANUM)
-{
- const char *word_end;
-
- /* skip space */
- while (my_isspace(default_charset_info, **text))
- ++(*text);
-
- word_end= *text;
-
- switch (seek_method) {
- case ALPHANUM:
- while (my_isalnum(default_charset_info, *word_end))
- ++word_end;
- break;
- case NONSPACE:
- while (!my_isspace(default_charset_info, *word_end) &&
- (*word_end != '\0'))
- ++word_end;
- break;
- case OPTION_NAME:
- while (my_isalnum(default_charset_info, *word_end) ||
- *word_end == '-' ||
- *word_end == '_')
- ++word_end;
- break;
- }
-
- *word_len= (uint) (word_end - *text);
-}
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc
deleted file mode 100644
index 3511589acd6..00000000000
--- a/server-tools/instance-manager/parse_output.cc
+++ /dev/null
@@ -1,407 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "parse_output.h"
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-
-#include <stdio.h>
-
-#include "parse.h"
-#include "portability.h"
-
-/**************************************************************************
- Private module implementation.
-**************************************************************************/
-
-namespace { /* no-indent */
-
-/*************************************************************************/
-
-void trim_space(const char **text, uint *word_len)
-{
- const char *start= *text;
- while (*start != 0 && *start == ' ')
- start++;
- *text= start;
-
- int len= strlen(start);
- const char *end= start + len - 1;
- while (end > start && my_isspace(&my_charset_latin1, *end))
- end--;
- *word_len= (end - start)+1;
-}
-
-/*************************************************************************/
-
-/**
- @brief A facade to the internal workings of optaining the output from an
- executed system process.
-*/
-
-class Mysqld_output_parser
-{
-public:
- Mysqld_output_parser()
- { }
-
- virtual ~Mysqld_output_parser()
- { }
-
-public:
- bool parse(const char *command,
- const char *option_name_str,
- uint option_name_length,
- char *option_value_buf,
- size_t option_value_buf_size,
- enum_option_type option_type);
-
-protected:
- /**
- @brief Run a process and attach stdout- and stdin-pipes to it.
-
- @param command The path to the process to be executed
-
- @return Error status.
- @retval TRUE An error occurred
- @retval FALSE Operation was a success
- */
-
- virtual bool run_command(const char *command)= 0;
-
-
- /**
- @brief Read a sequence of bytes from the executed process' stdout pipe.
-
- The sequence is terminated by either '\0', LF or CRLF tokens. The
- terminating token is excluded from the result.
-
- @param line_buffer A pointer to a character buffer
- @param line_buffer_size The size of the buffer in bytes
-
- @return Error status.
- @retval TRUE An error occured
- @retval FALSE Operation was a success
- */
-
- virtual bool read_line(char *line_buffer,
- uint line_buffer_size)= 0;
-
-
- /**
- @brief Release any resources needed after a execution and parsing.
- */
-
- virtual bool cleanup()= 0;
-};
-
-/*************************************************************************/
-
-bool Mysqld_output_parser::parse(const char *command,
- const char *option_name_str,
- uint option_name_length,
- char *option_value_buf,
- size_t option_value_buf_size,
- enum_option_type option_type)
-{
- /* should be enough to store the string from the output */
- const int LINE_BUFFER_SIZE= 512;
- char line_buffer[LINE_BUFFER_SIZE];
-
- if (run_command(command))
- return TRUE;
-
- while (true)
- {
- if (read_line(line_buffer, LINE_BUFFER_SIZE))
- {
- cleanup();
- return TRUE;
- }
-
- uint found_word_len= 0;
- char *linep= line_buffer;
-
- line_buffer[sizeof(line_buffer) - 1]= '\0'; /* safety */
-
- /* Find the word(s) we are looking for in the line. */
-
- linep= strstr(linep, option_name_str);
-
- if (!linep)
- continue;
-
- linep+= option_name_length;
-
- switch (option_type)
- {
- case GET_VALUE:
- trim_space((const char**) &linep, &found_word_len);
-
- if (option_value_buf_size <= found_word_len)
- {
- cleanup();
- return TRUE;
- }
-
- strmake(option_value_buf, linep, found_word_len);
-
- break;
-
- case GET_LINE:
- strmake(option_value_buf, linep, option_value_buf_size - 1);
-
- break;
- }
-
- cleanup();
-
- return FALSE;
- }
-}
-
-/**************************************************************************
- Platform-specific implementation: UNIX.
-**************************************************************************/
-
-#ifndef __WIN__
-
-class Mysqld_output_parser_unix : public Mysqld_output_parser
-{
-public:
- Mysqld_output_parser_unix() :
- m_stdout(NULL)
- { }
-
-protected:
- virtual bool run_command(const char *command);
-
- virtual bool read_line(char *line_buffer,
- uint line_buffer_size);
-
- virtual bool cleanup();
-
-private:
- FILE *m_stdout;
-};
-
-bool Mysqld_output_parser_unix::run_command(const char *command)
-{
- if (!(m_stdout= popen(command, "r")))
- return TRUE;
-
- /*
- We want fully buffered stream. We also want system to allocate
- appropriate buffer.
- */
-
- setvbuf(m_stdout, NULL, _IOFBF, 0);
-
- return FALSE;
-}
-
-bool Mysqld_output_parser_unix::read_line(char *line_buffer,
- uint line_buffer_size)
-{
- char *retbuff = fgets(line_buffer, line_buffer_size, m_stdout);
- /* Remove any tailing new line charaters */
- if (line_buffer[line_buffer_size-1] == LF)
- line_buffer[line_buffer_size-1]= '\0';
- return (retbuff == NULL);
-}
-
-bool Mysqld_output_parser_unix::cleanup()
-{
- if (m_stdout)
- pclose(m_stdout);
-
- return FALSE;
-}
-
-#else /* Windows */
-
-/**************************************************************************
- Platform-specific implementation: Windows.
-**************************************************************************/
-
-class Mysqld_output_parser_win : public Mysqld_output_parser
-{
-public:
- Mysqld_output_parser_win() :
- m_internal_buffer(NULL),
- m_internal_buffer_offset(0),
- m_internal_buffer_size(0)
- { }
-
-protected:
- virtual bool run_command(const char *command);
- virtual bool read_line(char *line_buffer,
- uint line_buffer_size);
- virtual bool cleanup();
-
-private:
- HANDLE m_h_child_stdout_wr;
- HANDLE m_h_child_stdout_rd;
- uint m_internal_buffer_offset;
- uint m_internal_buffer_size;
- char *m_internal_buffer;
-};
-
-bool Mysqld_output_parser_win::run_command(const char *command)
-{
- BOOL op_status;
-
- SECURITY_ATTRIBUTES sa_attr;
- sa_attr.nLength= sizeof(SECURITY_ATTRIBUTES);
- sa_attr.bInheritHandle= TRUE;
- sa_attr.lpSecurityDescriptor= NULL;
-
- op_status= CreatePipe(&m_h_child_stdout_rd,
- &m_h_child_stdout_wr,
- &sa_attr,
- 0 /* Use system-default buffer size. */);
-
- if (!op_status)
- return TRUE;
-
- SetHandleInformation(m_h_child_stdout_rd, HANDLE_FLAG_INHERIT, 0);
-
- STARTUPINFO si_start_info;
- ZeroMemory(&si_start_info, sizeof(STARTUPINFO));
- si_start_info.cb= sizeof(STARTUPINFO);
- si_start_info.hStdError= m_h_child_stdout_wr;
- si_start_info.hStdOutput= m_h_child_stdout_wr;
- si_start_info.dwFlags|= STARTF_USESTDHANDLES;
-
- PROCESS_INFORMATION pi_proc_info;
-
- op_status= CreateProcess(NULL, /* Application name. */
- (char*)command, /* Command line. */
- NULL, /* Process security attributes. */
- NULL, /* Primary thread security attr.*/
- TRUE, /* Handles are inherited. */
- 0, /* Creation flags. */
- NULL, /* Use parent's environment. */
- NULL, /* Use parent's curr. directory. */
- &si_start_info, /* STARTUPINFO pointer. */
- &pi_proc_info); /* Rec. PROCESS_INFORMATION. */
-
- if (!op_status)
- {
- CloseHandle(m_h_child_stdout_rd);
- CloseHandle(m_h_child_stdout_wr);
-
- return TRUE;
- }
-
- /* Close unnessary handles. */
-
- CloseHandle(pi_proc_info.hProcess);
- CloseHandle(pi_proc_info.hThread);
-
- return FALSE;
-}
-
-bool Mysqld_output_parser_win::read_line(char *line_buffer,
- uint line_buffer_size)
-{
- DWORD dw_read_count= m_internal_buffer_size;
- bzero(line_buffer,line_buffer_size);
- char *buff_ptr= line_buffer;
- char ch;
-
- while ((unsigned)(buff_ptr - line_buffer) < line_buffer_size)
- {
- do
- {
- ReadFile(m_h_child_stdout_rd, &ch,
- 1, &dw_read_count, NULL);
- } while ((ch == CR || ch == LF) && buff_ptr == line_buffer);
-
- if (dw_read_count == 0)
- return TRUE;
-
- if (ch == CR || ch == LF)
- break;
-
- *buff_ptr++ = ch;
- }
-
- return FALSE;
-}
-
-bool Mysqld_output_parser_win::cleanup()
-{
- /* Close all handles. */
-
- CloseHandle(m_h_child_stdout_wr);
- CloseHandle(m_h_child_stdout_rd);
-
- return FALSE;
-}
-#endif
-
-/*************************************************************************/
-
-} /* End of private module implementation. */
-
-/*************************************************************************/
-
-/**
- @brief Parse output of the given command
-
- @param command The command to execute.
- @param option_name_str Option name.
- @param option_name_length Length of the option name.
- @param[out] option_value_buf The buffer to store option value.
- @param option_value_buf_size Size of the option value buffer.
- @param option_type Type of the option:
- - GET_LINE if we want to get all the
- line after the option name;
- - GET_VALUE otherwise.
-
- Execute the process by running "command". Find the "option name" and
- return the next word if "option_type" is GET_VALUE. Return the rest of
- the parsed string otherwise.
-
- @note This function has a separate windows implementation.
-
- @return The error status.
- @retval FALSE Ok, the option name has been found.
- @retval TRUE Error occured or the option name is not found.
-*/
-
-bool parse_output_and_get_value(const char *command,
- const char *option_name_str,
- uint option_name_length,
- char *option_value_buf,
- size_t option_value_buf_size,
- enum_option_type option_type)
-{
-#ifndef __WIN__
- Mysqld_output_parser_unix parser;
-#else /* __WIN__ */
- Mysqld_output_parser_win parser;
-#endif
-
- return parser.parse(command,
- option_name_str,
- option_name_length,
- option_value_buf,
- option_value_buf_size,
- option_type);
-}
diff --git a/server-tools/instance-manager/parse_output.h b/server-tools/instance-manager/parse_output.h
deleted file mode 100644
index 41618f643a3..00000000000
--- a/server-tools/instance-manager/parse_output.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H
-/* Copyright (C) 2004 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <my_global.h>
-
-enum enum_option_type
-{
- GET_VALUE = 1,
- GET_LINE
-};
-
-bool parse_output_and_get_value(const char *command,
- const char *option_name_str,
- uint option_name_length,
- char *option_value_buf,
- size_t option_value_buf_size,
- enum_option_type option_type);
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H */
diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h
deleted file mode 100644
index 990e6140a9e..00000000000
--- a/server-tools/instance-manager/portability.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2005-2006 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H
-
-#if (defined(_SCO_DS) || defined(UNIXWARE_7)) && !defined(SHUT_RDWR)
-/*
- SHUT_* functions are defined only if
- "(defined(_XOPEN_SOURCE) && _XOPEN_SOURCE_EXTENDED - 0 >= 1)"
-*/
-#define SHUT_RDWR 2
-#endif
-
-#ifdef __WIN__
-
-#define vsnprintf _vsnprintf
-#define snprintf _snprintf
-
-#define SIGKILL 9
-
-/*TODO: fix this */
-#define PROTOCOL_VERSION 10
-
-#define DFLT_CONFIG_FILE_NAME "my.ini"
-#define DFLT_MYSQLD_PATH "mysqld"
-#define DFLT_PASSWD_FILE_EXT ".passwd"
-#define DFLT_PID_FILE_EXT ".pid"
-#define DFLT_SOCKET_FILE_EXT ".sock"
-
-typedef int pid_t;
-
-#undef popen
-#define popen(A,B) _popen(A,B)
-
-#define NEWLINE "\r\n"
-#define NEWLINE_LEN 2
-
-const char CR = '\r';
-const char LF = '\n';
-
-#else /* ! __WIN__ */
-
-#define NEWLINE "\n"
-#define NEWLINE_LEN 1
-
-const char LF = '\n';
-
-#endif /* __WIN__ */
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H */
-
-
diff --git a/server-tools/instance-manager/priv.cc b/server-tools/instance-manager/priv.cc
deleted file mode 100644
index 74263934924..00000000000
--- a/server-tools/instance-manager/priv.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "priv.h"
-
-#include <my_global.h>
-#include <mysql_com.h>
-#include <my_sys.h>
-
-#include "log.h"
-
-/*
- The following string must be less then 80 characters, as
- mysql_connection.cc relies on it
-*/
-const LEX_STRING mysqlmanager_version= { C_STRING_WITH_LEN("1.0-beta") };
-
-const unsigned char protocol_version= PROTOCOL_VERSION;
-
-unsigned long net_buffer_length= 16384;
-
-unsigned long max_allowed_packet= 16384;
-
-unsigned long net_read_timeout= NET_WAIT_TIMEOUT; // same as in mysqld
-
-unsigned long net_write_timeout= 60; // same as in mysqld
-
-unsigned long net_retry_count= 10; // same as in mysqld
-
-/* needed by net_serv.cc */
-unsigned int test_flags= 0;
-unsigned long bytes_sent = 0L, bytes_received = 0L;
-unsigned long mysqld_net_retry_count = 10L;
-unsigned long open_files_limit;
-
-
-
-bool create_pid_file(const char *pid_file_name, int pid)
-{
- FILE *pid_file;
-
- if (!(pid_file= my_fopen(pid_file_name, O_WRONLY | O_CREAT | O_BINARY,
- MYF(0))))
- {
- log_error("Can not create pid file '%s': %s (errno: %d)",
- (const char *) pid_file_name,
- (const char *) strerror(errno),
- (int) errno);
- return TRUE;
- }
-
- if (fprintf(pid_file, "%d\n", (int) pid) <= 0)
- {
- log_error("Can not write to pid file '%s': %s (errno: %d)",
- (const char *) pid_file_name,
- (const char *) strerror(errno),
- (int) errno);
- return TRUE;
- }
-
- my_fclose(pid_file, MYF(0));
-
- return FALSE;
-}
diff --git a/server-tools/instance-manager/priv.h b/server-tools/instance-manager/priv.h
deleted file mode 100644
index 1c2124c0e77..00000000000
--- a/server-tools/instance-manager/priv.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PRIV_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_PRIV_H
-
-#include <my_global.h>
-#include <m_string.h>
-#include <my_pthread.h>
-
-#include <sys/types.h>
-
-#ifndef __WIN__
-#include <unistd.h>
-#endif
-
-#include "portability.h"
-
-/* IM-wide platform-independent defines */
-#define SERVER_DEFAULT_PORT MYSQL_PORT
-#define DEFAULT_MONITORING_INTERVAL 20
-#define DEFAULT_PORT 2273
-/* three-week timeout should be enough */
-#define LONG_TIMEOUT ((ulong) 3600L*24L*21L)
-
-const int MEM_ROOT_BLOCK_SIZE= 512;
-
-/* The maximal length of option name and option value. */
-const int MAX_OPTION_LEN= 1024;
-
-/*
- The maximal length of whole option string:
- --<option name>=<option value>
-*/
-const int MAX_OPTION_STR_LEN= 2 + MAX_OPTION_LEN + 1 + MAX_OPTION_LEN + 1;
-
-const int MAX_VERSION_LENGTH= 160;
-
-const int MAX_INSTANCE_NAME_SIZE= FN_REFLEN;
-
-extern const LEX_STRING mysqlmanager_version;
-
-/* MySQL client-server protocol version: substituted from configure */
-extern const unsigned char protocol_version;
-
-/*
- These variables are used in MySQL subsystem to work with mysql clients
- To be moved to a config file/options one day.
-*/
-
-
-/* Buffer length for TCP/IP and socket communication */
-extern unsigned long net_buffer_length;
-
-
-/* Maximum allowed incoming/ougoung packet length */
-extern unsigned long max_allowed_packet;
-
-
-/*
- Number of seconds to wait for more data from a connection before aborting
- the read
-*/
-extern unsigned long net_read_timeout;
-
-
-/*
- Number of seconds to wait for a block to be written to a connection
- before aborting the write.
-*/
-extern unsigned long net_write_timeout;
-
-
-/*
- If a read on a communication port is interrupted, retry this many times
- before giving up.
-*/
-extern unsigned long net_retry_count;
-
-extern unsigned int test_flags;
-extern unsigned long bytes_sent, bytes_received;
-extern unsigned long mysqld_net_retry_count;
-extern unsigned long open_files_limit;
-
-bool create_pid_file(const char *pid_file_name, int pid);
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_PRIV_H
diff --git a/server-tools/instance-manager/protocol.cc b/server-tools/instance-manager/protocol.cc
deleted file mode 100644
index 8d71fcb8026..00000000000
--- a/server-tools/instance-manager/protocol.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "protocol.h"
-
-#include "messages.h"
-
-#include <mysql_com.h>
-#include <m_string.h>
-
-
-static uchar eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
-static const char ERROR_PACKET_CODE= (char) 255;
-
-
-int net_send_ok(struct st_net *net, unsigned long connection_id,
- const char *message)
-{
- /*
- The format of a packet
- 1 packet type code
- 1-9 affected rows count
- 1-9 connection id
- 2 thread return status
- 2 warning count
- 1-9 + message length message to send (isn't stored if no message)
- */
- Buffer buff;
- uchar *pos= buff.buffer;
-
- /* check that we have space to hold mandatory fields */
- buff.reserve(0, 23);
-
- enum { OK_PACKET_CODE= 0 };
- *pos++= OK_PACKET_CODE;
- pos= net_store_length(pos, (ulonglong) 0);
- pos= net_store_length(pos, (ulonglong) connection_id);
- int2store(pos, *net->return_status);
- pos+= 2;
- /* We don't support warnings, so store 0 for total warning count */
- int2store(pos, 0);
- pos+= 2;
-
- size_t position= pos - buff.buffer; /* we might need it for message */
-
- if (message != NULL)
- {
- buff.reserve(position, 9 + strlen(message));
- store_to_protocol_packet(&buff, message, &position);
- }
-
- return my_net_write(net, buff.buffer, position) || net_flush(net);
-}
-
-
-int net_send_error(struct st_net *net, uint sql_errno)
-{
- const char *err= message(sql_errno);
- char buff[1 + // packet type code
- 2 + // sql error number
- 1 + SQLSTATE_LENGTH + // sql state
- MYSQL_ERRMSG_SIZE]; // message
- char *pos= buff;
-
- *pos++= ERROR_PACKET_CODE;
- int2store(pos, sql_errno);
- pos+= 2;
- /* The first # is to make the protocol backward compatible */
- *pos++= '#';
- memcpy(pos, errno_to_sqlstate(sql_errno), SQLSTATE_LENGTH);
- pos+= SQLSTATE_LENGTH;
- pos= strmake(pos, err, MYSQL_ERRMSG_SIZE - 1) + 1;
- return (my_net_write(net, (uchar*) buff, (size_t) (pos - buff)) ||
- net_flush(net));
-}
-
-
-int net_send_error_323(struct st_net *net, uint sql_errno)
-{
- const char *err= message(sql_errno);
- char buff[1 + // packet type code
- 2 + // sql error number
- MYSQL_ERRMSG_SIZE]; // message
- char *pos= buff;
-
- *pos++= ERROR_PACKET_CODE;
- int2store(pos, sql_errno);
- pos+= 2;
- pos= strmake(pos, err, MYSQL_ERRMSG_SIZE - 1) + 1;
- return (my_net_write(net, (uchar*) buff, (size_t) (pos - buff)) ||
- net_flush(net));
-}
-
-char *net_store_length(char *pkg, uint length)
-{
- uchar *packet=(uchar*) pkg;
- if (length < 251)
- {
- *packet=(uchar) length;
- return (char*) packet+1;
- }
- *packet++=252;
- int2store(packet,(uint) length);
- return (char*) packet+2;
-}
-
-
-int store_to_protocol_packet(Buffer *buf, const char *string, size_t *position,
- size_t string_len)
-{
- uint currpos;
-
- /* reserve max amount of bytes needed to store length */
- if (buf->reserve(*position, 9))
- goto err;
- currpos= (net_store_length(buf->buffer + *position,
- (ulonglong) string_len) - buf->buffer);
- if (buf->append(currpos, string, string_len))
- goto err;
- *position= *position + string_len + (currpos - *position);
-
- return 0;
-err:
- return 1;
-}
-
-
-int store_to_protocol_packet(Buffer *buf, const char *string,
- size_t *position)
-{
- size_t string_len;
-
- string_len= strlen(string);
- return store_to_protocol_packet(buf, string, position, string_len);
-}
-
-
-int send_eof(struct st_net *net)
-{
- uchar buff[1 + /* eof packet code */
- 2 + /* warning count */
- 2]; /* server status */
-
- buff[0]=254;
- int2store(buff+1, 0);
- int2store(buff+3, 0);
- return my_net_write(net, buff, sizeof(buff));
-}
-
-
-int send_fields(struct st_net *net, LIST *fields)
-{
- LIST *tmp= fields;
- Buffer send_buff;
- uchar small_buff[4];
- size_t position= 0;
- LEX_STRING *field;
-
- /* send the number of fileds */
- net_store_length(small_buff, (uint) list_length(fields));
- if (my_net_write(net, small_buff, (uint) 1))
- goto err;
-
- while (tmp)
- {
- position= 0;
- field= (LEX_STRING *) tmp->data;
-
- store_to_protocol_packet(&send_buff,
- (char*) "", &position); /* catalog name */
- store_to_protocol_packet(&send_buff,
- (char*) "", &position); /* db name */
- store_to_protocol_packet(&send_buff,
- (char*) "", &position); /* table name */
- store_to_protocol_packet(&send_buff,
- (char*) "", &position); /* table name alias */
- store_to_protocol_packet(&send_buff,
- field->str, &position); /* column name */
- store_to_protocol_packet(&send_buff,
- field->str, &position); /* column name alias */
- send_buff.reserve(position, 12);
- if (send_buff.is_error())
- goto err;
- send_buff.buffer[position++]= 12;
- int2store(send_buff.buffer + position, 1); /* charsetnr */
- int4store(send_buff.buffer + position + 2,
- field->length); /* field length */
- send_buff.buffer[position+6]= (char) MYSQL_TYPE_STRING; /* type */
- int2store(send_buff.buffer + position + 7, 0); /* flags */
- send_buff.buffer[position + 9]= (char) 0; /* decimals */
- send_buff.buffer[position + 10]= 0;
- send_buff.buffer[position + 11]= 0;
- position+= 12;
- if (my_net_write(net, send_buff.buffer, (uint) position+1))
- goto err;
- tmp= list_rest(tmp);
- }
-
- if (my_net_write(net, eof_buff, 1))
- goto err;
- return 0;
-
-err:
- return 1;
-}
diff --git a/server-tools/instance-manager/protocol.h b/server-tools/instance-manager/protocol.h
deleted file mode 100644
index b06ae4dfdb2..00000000000
--- a/server-tools/instance-manager/protocol.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PROTOCOL_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_PROTOCOL_H
-
-#include "buffer.h"
-
-#include <my_list.h>
-
-/* default field length to be used in various field-realted functions */
-enum { DEFAULT_FIELD_LENGTH= 20 };
-
-struct st_net;
-
-int net_send_ok(struct st_net *net, unsigned long connection_id,
- const char *message);
-
-int net_send_error(struct st_net *net, unsigned sql_errno);
-
-int net_send_error_323(struct st_net *net, unsigned sql_errno);
-
-int send_fields(struct st_net *net, LIST *fields);
-
-char *net_store_length(char *pkg, uint length);
-
-int store_to_protocol_packet(Buffer *buf, const char *string,
- size_t *position);
-
-int store_to_protocol_packet(Buffer *buf, const char *string, size_t *position,
- size_t string_len);
-
-int send_eof(struct st_net *net);
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PROTOCOL_H */
diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc
deleted file mode 100644
index 489caa0aaa8..00000000000
--- a/server-tools/instance-manager/thread_registry.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "thread_registry.h"
-#include <thr_alarm.h>
-#include <signal.h>
-#include "log.h"
-
-#ifndef __WIN__
-/* Kick-off signal handler */
-
-enum { THREAD_KICK_OFF_SIGNAL= SIGUSR2 };
-
-extern "C" void handle_signal(int);
-
-void handle_signal(int __attribute__((unused)) sig_no)
-{
-}
-#endif
-
-/* Thread_info initializer methods */
-
-void Thread_info::init(bool send_signal_on_shutdown_arg)
-{
- thread_id= pthread_self();
- send_signal_on_shutdown= send_signal_on_shutdown_arg;
-}
-
-/*
- TODO: think about moving signal information (now it's shutdown_in_progress)
- to Thread_info. It will reduce contention and allow signal deliverence to
- a particular thread, not to the whole worker crew
-*/
-
-Thread_registry::Thread_registry() :
- shutdown_in_progress(FALSE)
- ,sigwait_thread_pid(pthread_self())
- ,error_status(FALSE)
-{
- pthread_mutex_init(&LOCK_thread_registry, 0);
- pthread_cond_init(&COND_thread_registry_is_empty, 0);
-
- /* head is used by-value to simplify nodes inserting */
- head.next= head.prev= &head;
-}
-
-
-Thread_registry::~Thread_registry()
-{
- /* Check that no one uses the repository. */
- pthread_mutex_lock(&LOCK_thread_registry);
-
- for (Thread_info *ti= head.next; ti != &head; ti= ti->next)
- {
- log_error("Thread_registry: unregistered thread: %lu.",
- (unsigned long) ti->thread_id);
- }
-
- /* All threads must unregister */
- DBUG_ASSERT(head.next == &head);
-
- pthread_mutex_unlock(&LOCK_thread_registry);
- pthread_cond_destroy(&COND_thread_registry_is_empty);
- pthread_mutex_destroy(&LOCK_thread_registry);
-}
-
-
-/*
- Set signal handler for kick-off thread, and insert a thread info to the
- repository. New node is appended to the end of the list; head.prev always
- points to the last node.
-*/
-
-void Thread_registry::register_thread(Thread_info *info,
- bool send_signal_on_shutdown)
-{
- info->init(send_signal_on_shutdown);
-
- DBUG_PRINT("info", ("Thread_registry: registering thread %lu...",
- (unsigned long) info->thread_id));
-
-#ifndef __WIN__
- struct sigaction sa;
- sa.sa_handler= handle_signal;
- sa.sa_flags= 0;
- sigemptyset(&sa.sa_mask);
- sigaction(THREAD_KICK_OFF_SIGNAL, &sa, 0);
-#endif
- info->current_cond= 0;
-
- pthread_mutex_lock(&LOCK_thread_registry);
- info->next= &head;
- info->prev= head.prev;
- head.prev->next= info;
- head.prev= info;
- pthread_mutex_unlock(&LOCK_thread_registry);
-}
-
-
-/*
- Unregister a thread from the repository and free Thread_info structure.
- Every registered thread must unregister. Unregistering should be the last
- thing a thread is doing, otherwise it could have no time to finalize.
-*/
-
-void Thread_registry::unregister_thread(Thread_info *info)
-{
- DBUG_PRINT("info", ("Thread_registry: unregistering thread %lu...",
- (unsigned long) info->thread_id));
-
- pthread_mutex_lock(&LOCK_thread_registry);
- info->prev->next= info->next;
- info->next->prev= info->prev;
-
- if (head.next == &head)
- {
- DBUG_PRINT("info", ("Thread_registry: thread registry is empty!"));
- pthread_cond_signal(&COND_thread_registry_is_empty);
- }
-
- pthread_mutex_unlock(&LOCK_thread_registry);
-}
-
-
-/*
- Check whether shutdown is in progress, and if yes, return immediately.
- Else set info->current_cond and call pthread_cond_wait. When
- pthread_cond_wait returns, unregister current cond and check the shutdown
- status again.
- RETURN VALUE
- return value from pthread_cond_wait
-*/
-
-int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
- pthread_mutex_t *mutex)
-{
- pthread_mutex_lock(&LOCK_thread_registry);
- if (shutdown_in_progress)
- {
- pthread_mutex_unlock(&LOCK_thread_registry);
- return 0;
- }
- info->current_cond= cond;
- pthread_mutex_unlock(&LOCK_thread_registry);
- /* sic: race condition here, cond can be signaled in deliver_shutdown */
- int rc= pthread_cond_wait(cond, mutex);
- pthread_mutex_lock(&LOCK_thread_registry);
- info->current_cond= 0;
- pthread_mutex_unlock(&LOCK_thread_registry);
- return rc;
-}
-
-
-int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- struct timespec *wait_time)
-{
- int rc;
- pthread_mutex_lock(&LOCK_thread_registry);
- if (shutdown_in_progress)
- {
- pthread_mutex_unlock(&LOCK_thread_registry);
- return 0;
- }
- info->current_cond= cond;
- pthread_mutex_unlock(&LOCK_thread_registry);
- /* sic: race condition here, cond can be signaled in deliver_shutdown */
- if ((rc= pthread_cond_timedwait(cond, mutex, wait_time)) == ETIME)
- rc= ETIMEDOUT; // For easier usage
- pthread_mutex_lock(&LOCK_thread_registry);
- info->current_cond= 0;
- pthread_mutex_unlock(&LOCK_thread_registry);
- return rc;
-}
-
-
-/*
- Deliver shutdown message to the workers crew.
- As it's impossible to avoid all race conditions, signal latecomers
- again.
-*/
-
-void Thread_registry::deliver_shutdown()
-{
- pthread_mutex_lock(&LOCK_thread_registry);
- shutdown_in_progress= TRUE;
-
-#ifndef __WIN__
- /* to stop reading from the network we need to flush alarm queue */
- end_thr_alarm(0);
- /*
- We have to deliver final alarms this way, as the main thread has already
- stopped alarm processing.
- */
- process_alarm(THR_SERVER_ALARM);
-#endif
-
- /*
- sic: race condition here, the thread may not yet fall into
- pthread_cond_wait.
- */
-
- interrupt_threads();
-
- wait_for_threads_to_unregister();
-
- /*
- If previous signals did not reach some threads, they must be sleeping
- in pthread_cond_wait or in a blocking syscall. Wake them up:
- every thread shall check signal variables after each syscall/cond_wait,
- so this time everybody should be informed (presumably each worker can
- get CPU during shutdown_time.)
- */
-
- interrupt_threads();
-
- /* Get the last chance to threads to stop. */
-
- wait_for_threads_to_unregister();
-
-#ifndef DBUG_OFF
- /*
- Print out threads, that didn't stopped. Thread_registry destructor will
- probably abort the program if there is still any alive thread.
- */
-
- if (head.next != &head)
- {
- DBUG_PRINT("info", ("Thread_registry: non-stopped threads:"));
-
- for (Thread_info *info= head.next; info != &head; info= info->next)
- DBUG_PRINT("info", (" - %lu", (unsigned long) info->thread_id));
- }
- else
- {
- DBUG_PRINT("info", ("Thread_registry: all threads stopped."));
- }
-#endif // DBUG_OFF
-
- pthread_mutex_unlock(&LOCK_thread_registry);
-}
-
-
-void Thread_registry::request_shutdown()
-{
- pthread_kill(sigwait_thread_pid, SIGTERM);
-}
-
-
-void Thread_registry::interrupt_threads()
-{
- for (Thread_info *info= head.next; info != &head; info= info->next)
- {
- if (!info->send_signal_on_shutdown)
- continue;
-
- pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL);
- if (info->current_cond)
- pthread_cond_signal(info->current_cond);
- }
-}
-
-
-void Thread_registry::wait_for_threads_to_unregister()
-{
- struct timespec shutdown_time;
-
- set_timespec(shutdown_time, 1);
-
- DBUG_PRINT("info", ("Thread_registry: joining threads..."));
-
- while (true)
- {
- if (head.next == &head)
- {
- DBUG_PRINT("info", ("Thread_registry: emptied."));
- return;
- }
-
- int error= pthread_cond_timedwait(&COND_thread_registry_is_empty,
- &LOCK_thread_registry,
- &shutdown_time);
-
- if (error == ETIMEDOUT || error == ETIME)
- {
- DBUG_PRINT("info", ("Thread_registry: threads shutdown timed out."));
- return;
- }
- }
-}
-
-
-/*********************************************************************
- class Thread
-*********************************************************************/
-
-#if defined(__ia64__) || defined(__ia64)
-/*
- We can live with 32K, but reserve 64K. Just to be safe.
- On ia64 we need to reserve double of the size.
-*/
-#define IM_THREAD_STACK_SIZE (128*1024L)
-#else
-#define IM_THREAD_STACK_SIZE (64*1024)
-#endif
-
-/*
- Change the stack size and start a thread. Return an error if either
- pthread_attr_setstacksize or pthread_create fails.
- Arguments are the same as for pthread_create().
-*/
-
-static
-int set_stacksize_and_create_thread(pthread_t *thread, pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg)
-{
- int rc= 0;
-
-#ifndef __WIN__
-#ifndef PTHREAD_STACK_MIN
-#define PTHREAD_STACK_MIN 32768
-#endif
- /*
- Set stack size to be safe on the platforms with too small
- default thread stack.
- */
- rc= pthread_attr_setstacksize(attr,
- (size_t) (PTHREAD_STACK_MIN +
- IM_THREAD_STACK_SIZE));
-#endif
- if (!rc)
- rc= pthread_create(thread, attr, start_routine, arg);
- return rc;
-}
-
-
-Thread::~Thread()
-{
-}
-
-
-void *Thread::thread_func(void *arg)
-{
- Thread *thread= (Thread *) arg;
- my_thread_init();
-
- thread->run();
-
- my_thread_end();
- return NULL;
-}
-
-
-bool Thread::start(enum_thread_type thread_type)
-{
- pthread_attr_t attr;
- int rc;
-
- pthread_attr_init(&attr);
-
- if (thread_type == DETACHED)
- {
- detached = TRUE;
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- }
- else
- {
- detached = FALSE;
- }
-
- rc= set_stacksize_and_create_thread(&id, &attr, Thread::thread_func, this);
- pthread_attr_destroy(&attr);
-
- return rc != 0;
-}
-
-
-bool Thread::join()
-{
- DBUG_ASSERT(!detached);
-
- return pthread_join(id, NULL) != 0;
-}
-
-
-int Thread_registry::get_error_status()
-{
- int ret_error_status;
-
- pthread_mutex_lock(&LOCK_thread_registry);
- ret_error_status= error_status;
- pthread_mutex_unlock(&LOCK_thread_registry);
-
- return ret_error_status;
-}
-
-
-void Thread_registry::set_error_status()
-{
- pthread_mutex_lock(&LOCK_thread_registry);
- error_status= TRUE;
- pthread_mutex_unlock(&LOCK_thread_registry);
-}
diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h
deleted file mode 100644
index d04c8442e44..00000000000
--- a/server-tools/instance-manager/thread_registry.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H
-
-/*
- A multi-threaded application shall nicely work with signals.
-
- This means it shall, first of all, shut down nicely on ``quit'' signals:
- stop all running threads, cleanup and exit.
-
- Note, that a thread can't be shut down nicely if it doesn't want to be.
- That's why to perform clean shutdown, all threads constituting a process
- must observe certain rules. Here we use the rules, described in Butenhof
- book 'Programming with POSIX threads', namely:
- - all user signals are handled in 'signal thread' in synchronous manner
- (by means of sigwait). To guarantee that the signal thread is the only who
- can receive user signals, all threads block them, and signal thread is
- the only who calls sigwait() with an apporpriate sigmask.
- To propogate a signal to the workers the signal thread sets
- a variable, corresponding to the signal. Additionally the signal thread
- sends each worker an internal signal (by means of pthread_kill) to kick it
- out from possible blocking syscall, and possibly pthread_cond_signal if
- some thread is blocked in pthread_cond_[timed]wait.
- - a worker handles only internal 'kick' signal (the handler does nothing).
- In case when a syscall returns 'EINTR' the worker checks all
- signal-related variables and behaves accordingly.
- Also these variables shall be checked from time to time in long
- CPU-bounded operations, and before/after pthread_cond_wait. (It's supposed
- that a worker thread either waits in a syscall/conditional variable, or
- computes something.)
- - to guarantee signal deliverence, there should be some kind of feedback,
- e. g. all workers shall account in the signal thread Thread Repository and
- unregister from it on exit.
-
- Configuration reload (on SIGHUP) and thread timeouts/alarms can be handled
- in manner, similar to ``quit'' signals.
-*/
-
-#include <my_global.h>
-#include <my_pthread.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-/**
- Thread_info - repository entry for each worker thread
- All entries comprise double-linked list like:
- 0 -- entry -- entry -- entry - 0
- Double-linked list is used to unregister threads easy.
-*/
-
-class Thread_info
-{
-public:
- Thread_info() {}
- friend class Thread_registry;
-private:
- void init(bool send_signal_on_shutdown);
-private:
- pthread_cond_t *current_cond;
- Thread_info *prev, *next;
- pthread_t thread_id;
- bool send_signal_on_shutdown;
-};
-
-
-/**
- A base class for a detached thread.
-*/
-
-class Thread
-{
-public:
- enum enum_thread_type
- {
- DETACHED,
- JOINABLE
- };
-public:
- Thread()
- { }
-
-public:
- inline bool is_detached() const;
-
- bool start(enum_thread_type thread_type = JOINABLE);
- bool join();
-
-protected:
- virtual void run()= 0;
- virtual ~Thread();
-
-private:
- pthread_t id;
- bool detached;
-
-private:
- static void *thread_func(void *arg);
-
-private:
- Thread(const Thread & /* rhs */); /* not implemented */
- Thread &operator=(const Thread & /* rhs */); /* not implemented */
-};
-
-inline bool Thread::is_detached() const
-{
- return detached;
-}
-
-
-/**
- Thread_registry - contains handles for each worker thread to deliver
- signal information to workers.
-*/
-
-class Thread_registry
-{
-public:
- Thread_registry();
- ~Thread_registry();
-
- void register_thread(Thread_info *info, bool send_signal_on_shutdown= TRUE);
- void unregister_thread(Thread_info *info);
- void deliver_shutdown();
- void request_shutdown();
- inline bool is_shutdown();
- int cond_wait(Thread_info *info, pthread_cond_t *cond,
- pthread_mutex_t *mutex);
- int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
- pthread_mutex_t *mutex, struct timespec *wait_time);
- int get_error_status();
- void set_error_status();
-
-private:
- void interrupt_threads();
- void wait_for_threads_to_unregister();
-
-private:
- Thread_info head;
- bool shutdown_in_progress;
- pthread_mutex_t LOCK_thread_registry;
- pthread_cond_t COND_thread_registry_is_empty;
- pthread_t sigwait_thread_pid;
- bool error_status;
-
-private:
- Thread_registry(const Thread_registry &);
- Thread_registry &operator =(const Thread_registry &);
-};
-
-
-inline bool Thread_registry::is_shutdown()
-{
- pthread_mutex_lock(&LOCK_thread_registry);
- bool res= shutdown_in_progress;
- pthread_mutex_unlock(&LOCK_thread_registry);
- return res;
-}
-
-
-#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_THREAD_REGISTRY_H */
diff --git a/server-tools/instance-manager/user_management_commands.cc b/server-tools/instance-manager/user_management_commands.cc
deleted file mode 100644
index 2eb0ae30aa5..00000000000
--- a/server-tools/instance-manager/user_management_commands.cc
+++ /dev/null
@@ -1,421 +0,0 @@
-/* Copyright (C) 2006 MySQL AB
-
- 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 St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "user_management_commands.h"
-
-#include "exit_codes.h"
-#include "options.h"
-#include "user_map.h"
-
-/*************************************************************************
- Module-specific (internal) functions.
-*************************************************************************/
-
-/*
- The function returns user name. The user name is retrieved from command-line
- options (if specified) or from console.
-
- NOTE
- This function must not be used in user-management command implementations.
- Use get_user_name() instead.
-
- SYNOPSIS
- get_user_name_impl()
-
- RETURN
- NULL on error
- valid pointer on success
-*/
-
-static char *get_user_name_impl()
-{
- static char user_name_buf[1024];
- char *ptr;
-
- if (Options::User_management::user_name)
- return Options::User_management::user_name;
-
- printf("Enter user name: ");
- fflush(stdout);
-
- if (!fgets(user_name_buf, sizeof (user_name_buf), stdin))
- return NULL;
-
- if ((ptr= strchr(user_name_buf, '\n')))
- *ptr= 0;
-
- if ((ptr= strchr(user_name_buf, '\r')))
- *ptr= 0;
-
- return user_name_buf;
-}
-
-
-/*
- The function is intended to provide user name for user-management
- operations. It also checks that length of the specified user name is correct
- (not empty, not exceeds USERNAME_LENGTH). Report to stderr if something is
- wrong.
-
- SYNOPSIS
- get_user_name()
- user_name [OUT] on success contains user name
-
- RETURN
- TRUE on error
- FALSE on success
-*/
-
-static bool get_user_name(LEX_STRING *user_name)
-{
- char *user_name_str= get_user_name_impl();
-
- if (!user_name_str)
- {
- fprintf(stderr, "Error: unable to read user name from stdin.\n");
- return TRUE;
- }
-
- user_name->str= user_name_str;
- user_name->length= strlen(user_name->str);
-
- if (user_name->length == 0)
- {
- fprintf(stderr, "Error: user name can not be empty.\n");
- return TRUE;
- }
-
- if (user_name->length > USERNAME_LENGTH)
- {
- fprintf(stderr, "Error: user name must not exceed %d characters.\n",
- (int) USERNAME_LENGTH);
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/*
- The function is intended to provide password for user-management operations.
- The password is retrieved from command-line options (if specified) or from
- console.
-
- SYNOPSIS
- get_password()
-
- RETURN
- NULL on error
- valid pointer on success
-*/
-
-static const char *get_password()
-{
- if (Options::User_management::password)
- return Options::User_management::password;
-
- const char *passwd1= get_tty_password("Enter password: ");
- const char *passwd2= get_tty_password("Re-type password: ");
-
- if (strcmp(passwd1, passwd2))
- {
- fprintf(stderr, "Error: passwords do not match.\n");
- return 0;
- }
-
- return passwd1;
-}
-
-
-/*
- Load password file into user map.
-
- SYNOPSIS
- load_password_file()
- user_map target user map
-
- RETURN
- See exit_codes.h for possible values.
-*/
-
-static int load_password_file(User_map *user_map)
-{
- int err_code;
- const char *err_msg;
-
- if (user_map->init())
- {
- fprintf(stderr, "Error: can not initialize user map.\n");
- return ERR_OUT_OF_MEMORY;
- }
-
- if ((err_code= user_map->load(Options::Main::password_file_name, &err_msg)))
- fprintf(stderr, "Error: %s.\n", (const char *) err_msg);
-
- return err_code;
-}
-
-
-/*
- Save user map into password file.
-
- SYNOPSIS
- save_password_file()
- user_map user map
-
- RETURN
- See exit_codes.h for possible values.
-*/
-
-static int save_password_file(User_map *user_map)
-{
- int err_code;
- const char *err_msg;
-
- if ((err_code= user_map->save(Options::Main::password_file_name, &err_msg)))
- fprintf(stderr, "Error: %s.\n", (const char *) err_msg);
-
- return err_code;
-}
-
-/*************************************************************************
- Print_password_line_cmd
-*************************************************************************/
-
-int Print_password_line_cmd::execute()
-{
- LEX_STRING user_name;
- const char *password;
-
- printf("Creating record for new user.\n");
-
- if (get_user_name(&user_name))
- return ERR_CAN_NOT_READ_USER_NAME;
-
- if (!(password= get_password()))
- return ERR_CAN_NOT_READ_PASSWORD;
-
- {
- User user(&user_name, password);
-
- printf("%s:%s\n",
- (const char *) user.user,
- (const char *) user.scrambled_password);
- }
-
- return ERR_OK;
-}
-
-
-/*************************************************************************
- Add_user_cmd
-*************************************************************************/
-
-int Add_user_cmd::execute()
-{
- LEX_STRING user_name;
- const char *password;
-
- User_map user_map;
- User *new_user;
-
- int err_code;
-
- if (get_user_name(&user_name))
- return ERR_CAN_NOT_READ_USER_NAME;
-
- /* Load the password file. */
-
- if ((err_code= load_password_file(&user_map)) != ERR_OK)
- return err_code;
-
- /* Check that the user does not exist. */
-
- if (user_map.find_user(&user_name))
- {
- fprintf(stderr, "Error: user '%s' already exists.\n",
- (const char *) user_name.str);
- return ERR_USER_ALREADY_EXISTS;
- }
-
- /* Add the user. */
-
- if (!(password= get_password()))
- return ERR_CAN_NOT_READ_PASSWORD;
-
- if (!(new_user= new User(&user_name, password)))
- return ERR_OUT_OF_MEMORY;
-
- if (user_map.add_user(new_user))
- {
- delete new_user;
- return ERR_OUT_OF_MEMORY;
- }
-
- /* Save the password file. */
-
- return save_password_file(&user_map);
-}
-
-
-/*************************************************************************
- Drop_user_cmd
-*************************************************************************/
-
-int Drop_user_cmd::execute()
-{
- LEX_STRING user_name;
-
- User_map user_map;
- User *user;
-
- int err_code;
-
- if (get_user_name(&user_name))
- return ERR_CAN_NOT_READ_USER_NAME;
-
- /* Load the password file. */
-
- if ((err_code= load_password_file(&user_map)) != ERR_OK)
- return err_code;
-
- /* Find the user. */
-
- user= user_map.find_user(&user_name);
-
- if (!user)
- {
- fprintf(stderr, "Error: user '%s' does not exist.\n",
- (const char *) user_name.str);
- return ERR_USER_NOT_FOUND;
- }
-
- /* Remove the user (ignore possible errors). */
-
- user_map.remove_user(user);
-
- /* Save the password file. */
-
- return save_password_file(&user_map);
-}
-
-
-/*************************************************************************
- Edit_user_cmd
-*************************************************************************/
-
-int Edit_user_cmd::execute()
-{
- LEX_STRING user_name;
- const char *password;
-
- User_map user_map;
- User *user;
-
- int err_code;
-
- if (get_user_name(&user_name))
- return ERR_CAN_NOT_READ_USER_NAME;
-
- /* Load the password file. */
-
- if ((err_code= load_password_file(&user_map)) != ERR_OK)
- return err_code;
-
- /* Find the user. */
-
- user= user_map.find_user(&user_name);
-
- if (!user)
- {
- fprintf(stderr, "Error: user '%s' does not exist.\n",
- (const char *) user_name.str);
- return ERR_USER_NOT_FOUND;
- }
-
- /* Modify user's password. */
-
- if (!(password= get_password()))
- return ERR_CAN_NOT_READ_PASSWORD;
-
- user->set_password(password);
-
- /* Save the password file. */
-
- return save_password_file(&user_map);
-}
-
-
-/*************************************************************************
- Clean_db_cmd
-*************************************************************************/
-
-int Clean_db_cmd::execute()
-{
- User_map user_map;
-
- if (user_map.init())
- {
- fprintf(stderr, "Error: can not initialize user map.\n");
- return ERR_OUT_OF_MEMORY;
- }
-
- return save_password_file(&user_map);
-}
-
-
-/*************************************************************************
- Check_db_cmd
-*************************************************************************/
-
-int Check_db_cmd::execute()
-{
- User_map user_map;
-
- return load_password_file(&user_map);
-}
-
-
-/*************************************************************************
- List_users_cmd
-*************************************************************************/
-
-int List_users_cmd::execute()
-{
- User_map user_map;
-
- int err_code;
-
- /* Load the password file. */
-
- if ((err_code= load_password_file(&user_map)))
- return err_code;
-
- /* Print out registered users. */
-
- {
- User_map::Iterator it(&user_map);
- User *user;
-
- while ((user= it.next()))
- fprintf(stderr, "%s\n", (const char *) user->user);
- }
-
- return ERR_OK;
-}
diff --git a/server-tools/instance-manager/user_management_commands.h b/server-tools/instance-manager/user_management_commands.h
deleted file mode 100644
index c925e6ae363..00000000000
--- a/server-tools/instance-manager/user_management_commands.h
+++ /dev/null
@@ -1,167 +0,0 @@
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MANAGEMENT_CMD_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MANAGEMENT_CMD_H
-
-/*
- Copyright (C) 2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- This header contains declarations of classes inteded to support
- user-management commands (such as add user, get list of users, etc).
-
- The general idea is to have one interface (pure abstract class) for such a
- command. Each concrete user-management command is implemented in concrete
- class, derived from the common interface.
-*/
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-/*************************************************************************
- User_management_cmd -- base class for User-management commands.
-*************************************************************************/
-
-class User_management_cmd
-{
-public:
- User_management_cmd()
- { }
-
- virtual ~User_management_cmd()
- { }
-
-public:
- /*
- Executes user-management command.
-
- SYNOPSIS
- execute()
-
- RETURN
- See exit_codes.h for possible values.
- */
-
- virtual int execute() = 0;
-};
-
-
-/*************************************************************************
- Print_password_line_cmd: support for --print-password-line command-line
- option.
-*************************************************************************/
-
-class Print_password_line_cmd: public User_management_cmd
-{
-public:
- Print_password_line_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- Add_user_cmd: support for --add-user command-line option.
-*************************************************************************/
-
-class Add_user_cmd: public User_management_cmd
-{
-public:
- Add_user_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- Drop_user_cmd: support for --drop-user command-line option.
-*************************************************************************/
-
-class Drop_user_cmd: public User_management_cmd
-{
-public:
- Drop_user_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- Edit_user_cmd: support for --edit-user command-line option.
-*************************************************************************/
-
-class Edit_user_cmd: public User_management_cmd
-{
-public:
- Edit_user_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- Clean_db_cmd: support for --clean-db command-line option.
-*************************************************************************/
-
-class Clean_db_cmd: public User_management_cmd
-{
-public:
- Clean_db_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- Check_db_cmd: support for --check-db command-line option.
-*************************************************************************/
-
-class Check_db_cmd: public User_management_cmd
-{
-public:
- Check_db_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-
-/*************************************************************************
- List_users_cmd: support for --list-users command-line option.
-*************************************************************************/
-
-class List_users_cmd: public User_management_cmd
-{
-public:
- List_users_cmd()
- { }
-
-public:
- virtual int execute();
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MANAGEMENT_CMD_H
diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc
deleted file mode 100644
index 49c35c16ca9..00000000000
--- a/server-tools/instance-manager/user_map.cc
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
-#pragma implementation
-#endif
-
-#include "user_map.h"
-#include "exit_codes.h"
-#include "log.h"
-#include "portability.h"
-
-User::User(const LEX_STRING *user_name_arg, const char *password)
-{
- user_length= (uint8) (strmake(user, user_name_arg->str,
- USERNAME_LENGTH + 1) - user);
- set_password(password);
-}
-
-int User::init(const char *line)
-{
- const char *name_begin, *name_end, *password;
- int password_length;
-
- if (line[0] == '\'' || line[0] == '"')
- {
- name_begin= line + 1;
- name_end= strchr(name_begin, line[0]);
- if (name_end == 0 || name_end[1] != ':')
- {
- log_error("Invalid format (unmatched quote) of user line (%s).",
- (const char *) line);
- return 1;
- }
- password= name_end + 2;
- }
- else
- {
- name_begin= line;
- name_end= strchr(name_begin, ':');
- if (name_end == 0)
- {
- log_error("Invalid format (no delimiter) of user line (%s).",
- (const char *) line);
- return 1;
- }
- password= name_end + 1;
- }
-
- user_length= (uint8) (name_end - name_begin);
- if (user_length > USERNAME_LENGTH)
- {
- log_error("User name is too long (%d). Max length: %d. "
- "User line: '%s'.",
- (int) user_length,
- (int) USERNAME_LENGTH,
- (const char *) line);
- return 1;
- }
-
- password_length= (int) strlen(password);
- if (password_length > SCRAMBLED_PASSWORD_CHAR_LENGTH)
- {
- log_error("Password is too long (%d). Max length: %d."
- "User line: '%s'.",
- (int) password_length,
- (int) SCRAMBLED_PASSWORD_CHAR_LENGTH,
- (const char *) line);
- return 1;
- }
-
- memcpy(user, name_begin, user_length);
- user[user_length]= 0;
-
- memcpy(scrambled_password, password, password_length);
- scrambled_password[password_length]= 0;
-
- get_salt_from_password(salt, password);
-
- log_info("Loaded user '%s'.", (const char *) user);
-
- return 0;
-}
-
-
-C_MODE_START
-
-static uchar* get_user_key(const uchar* u, size_t* len,
- my_bool __attribute__((unused)) t)
-{
- const User *user= (const User *) u;
- *len= user->user_length;
- return (uchar *) user->user;
-}
-
-static void delete_user(void *u)
-{
- User *user= (User *) u;
- delete user;
-}
-
-C_MODE_END
-
-
-void User_map::Iterator::reset()
-{
- cur_idx= 0;
-}
-
-
-User *User_map::Iterator::next()
-{
- if (cur_idx < user_map->hash.records)
- return (User *) hash_element(&user_map->hash, cur_idx++);
-
- return NULL;
-}
-
-
-int User_map::init()
-{
- enum { START_HASH_SIZE= 16 };
- if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
- get_user_key, delete_user, 0))
- return 1;
-
- initialized= TRUE;
-
- return 0;
-}
-
-
-User_map::User_map()
- :initialized(FALSE)
-{
-}
-
-
-User_map::~User_map()
-{
- if (initialized)
- hash_free(&hash);
-}
-
-
-/*
- Load password database.
-
- SYNOPSIS
- load()
- password_file_name [IN] password file path
- err_msg [OUT] error message
-
- DESCRIPTION
- Load all users from the password file. Must be called once right after
- construction. In case of failure, puts error message to the log file and
- returns specific error code.
-
- RETURN
- 0 on success
- !0 on error
-*/
-
-int User_map::load(const char *password_file_name, const char **err_msg)
-{
- static const int ERR_MSG_BUF_SIZE = 255;
- static char err_msg_buf[ERR_MSG_BUF_SIZE];
-
- FILE *file;
- char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH +
- 2 + /* for possible quotes */
- 1 + /* for ':' */
- 2 + /* for newline */
- 1]; /* for trailing zero */
- User *user;
-
- if (my_access(password_file_name, F_OK) != 0)
- {
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "password file (%s) does not exist",
- (const char *) password_file_name);
- *err_msg= err_msg_buf;
- }
-
- return ERR_PASSWORD_FILE_DOES_NOT_EXIST;
- }
-
- if ((file= my_fopen(password_file_name, O_RDONLY | O_BINARY, MYF(0))) == 0)
- {
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "can not open password file (%s): %s",
- (const char *) password_file_name,
- (const char *) strerror(errno));
- *err_msg= err_msg_buf;
- }
-
- return ERR_IO_ERROR;
- }
-
- log_info("Loading the password database...");
-
- while (fgets(line, sizeof(line), file))
- {
- char *user_line= line;
-
- /*
- We need to skip EOL-symbols also from the beginning of the line, because
- if the previous line was ended by \n\r sequence, we get \r in our line.
- */
-
- while (user_line[0] == '\r' || user_line[0] == '\n')
- ++user_line;
-
- /* Skip EOL-symbols in the end of the line. */
-
- {
- char *ptr;
-
- if ((ptr= strchr(user_line, '\n')))
- *ptr= 0;
-
- if ((ptr= strchr(user_line, '\r')))
- *ptr= 0;
- }
-
- /* skip comments and empty lines */
- if (!user_line[0] || user_line[0] == '#')
- continue;
-
- if ((user= new User) == 0)
- {
- my_fclose(file, MYF(0));
-
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "out of memory while parsing password file (%s)",
- (const char *) password_file_name);
- *err_msg= err_msg_buf;
- }
-
- return ERR_OUT_OF_MEMORY;
- }
-
- if (user->init(user_line))
- {
- delete user;
- my_fclose(file, MYF(0));
-
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "password file (%s) corrupted",
- (const char *) password_file_name);
- *err_msg= err_msg_buf;
- }
-
- return ERR_PASSWORD_FILE_CORRUPTED;
- }
-
- if (my_hash_insert(&hash, (uchar *) user))
- {
- delete user;
- my_fclose(file, MYF(0));
-
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "out of memory while parsing password file (%s)",
- (const char *) password_file_name);
- *err_msg= err_msg_buf;
- }
-
- return ERR_OUT_OF_MEMORY;
- }
- }
-
- log_info("The password database loaded successfully.");
-
- my_fclose(file, MYF(0));
-
- if (err_msg)
- *err_msg= NULL;
-
- return ERR_OK;
-}
-
-
-int User_map::save(const char *password_file_name, const char **err_msg)
-{
- static const int ERR_MSG_BUF_SIZE = 255;
- static char err_msg_buf[ERR_MSG_BUF_SIZE];
-
- FILE *file;
-
- if ((file= my_fopen(password_file_name, O_WRONLY | O_TRUNC | O_BINARY,
- MYF(0))) == 0)
- {
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "can not open password file (%s) for writing: %s",
- (const char *) password_file_name,
- (const char *) strerror(errno));
- *err_msg= err_msg_buf;
- }
-
- return ERR_IO_ERROR;
- }
-
- {
- User_map::Iterator it(this);
- User *user;
-
- while ((user= it.next()))
- {
- if (fprintf(file, "%s:%s\n", (const char *) user->user,
- (const char *) user->scrambled_password) < 0)
- {
- if (err_msg)
- {
- snprintf(err_msg_buf, ERR_MSG_BUF_SIZE,
- "can not write to password file (%s): %s",
- (const char *) password_file_name,
- (const char *) strerror(errno));
- *err_msg= err_msg_buf;
- }
-
- my_fclose(file, MYF(0));
-
- return ERR_IO_ERROR;
- }
- }
- }
-
- my_fclose(file, MYF(0));
-
- return ERR_OK;
-}
-
-
-/*
- Check if user exists and password is correct
- RETURN VALUE
- 0 - user found and password OK
- 1 - password mismatch
- 2 - user not found
-*/
-
-int User_map::authenticate(const LEX_STRING *user_name,
- const char *scrambled_password,
- const char *scramble) const
-{
- const User *user= find_user(user_name);
- return user ? check_scramble(scrambled_password, scramble, user->salt) : 2;
-}
-
-
-User *User_map::find_user(const LEX_STRING *user_name)
-{
- return (User*) hash_search(&hash, (uchar*) user_name->str, user_name->length);
-}
-
-const User *User_map::find_user(const LEX_STRING *user_name) const
-{
- return const_cast<User_map *> (this)->find_user(user_name);
-}
-
-
-bool User_map::add_user(User *user)
-{
- return my_hash_insert(&hash, (uchar*) user) == 0 ? FALSE : TRUE;
-}
-
-
-bool User_map::remove_user(User *user)
-{
- return hash_delete(&hash, (uchar*) user) == 0 ? FALSE : TRUE;
-}
diff --git a/server-tools/instance-manager/user_map.h b/server-tools/instance-manager/user_map.h
deleted file mode 100644
index 6168f2b04fa..00000000000
--- a/server-tools/instance-manager/user_map.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright (C) 2004-2006 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MAP_H
-#define INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MAP_H
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <mysql_com.h>
-#include <m_string.h>
-#include <hash.h>
-
-#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
-#pragma interface
-#endif
-
-struct User
-{
- User()
- {}
-
- User(const LEX_STRING *user_name_arg, const char *password);
-
- int init(const char *line);
-
- inline void set_password(const char *password)
- {
- make_scrambled_password(scrambled_password, password);
- }
-
- char user[USERNAME_LENGTH + 1];
- char scrambled_password[SCRAMBLED_PASSWORD_CHAR_LENGTH + 1];
- uint8 user_length;
- uint8 salt[SCRAMBLE_LENGTH];
-};
-
-/*
- User_map -- all users and passwords
-*/
-
-class User_map
-{
-public:
- /* User_map iterator */
-
- class Iterator
- {
- public:
- Iterator(User_map *user_map_arg) :
- user_map(user_map_arg), cur_idx(0)
- { }
-
- public:
- void reset();
-
- User *next();
-
- private:
- User_map *user_map;
- uint cur_idx;
- };
-
-public:
- User_map();
- ~User_map();
-
- int init();
- int load(const char *password_file_name, const char **err_msg);
- int save(const char *password_file_name, const char **err_msg);
- int authenticate(const LEX_STRING *user_name,
- const char *scrambled_password,
- const char *scramble) const;
-
- const User *find_user(const LEX_STRING *user_name) const;
- User *find_user(const LEX_STRING *user_name);
-
- bool add_user(User *user);
- bool remove_user(User *user);
-
-private:
- User_map(const User_map &);
- User_map &operator =(const User_map &);
-
-private:
- HASH hash;
- bool initialized;
-
- friend class Iterator;
-};
-
-#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_USER_MAP_H