summaryrefslogtreecommitdiff
path: root/server-tools
diff options
context:
space:
mode:
authorkostja@oak.local <>2003-08-16 21:44:24 +0400
committerkostja@oak.local <>2003-08-16 21:44:24 +0400
commit36ce7d5fd5d3f5ba85197f23ed430f83d7b4f9d7 (patch)
treeee10056d2c30e5854e5eca9f26645077b4b12379 /server-tools
parent6f6042462933c66f8af0503b32aa62e43f1aaf1f (diff)
downloadmariadb-git-36ce7d5fd5d3f5ba85197f23ed430f83d7b4f9d7.tar.gz
First implementation of instance-manager carcass:
logging, options, angel process.
Diffstat (limited to 'server-tools')
-rw-r--r--server-tools/Makefile.am1
-rw-r--r--server-tools/instance-manager/Makefile.am29
-rw-r--r--server-tools/instance-manager/README11
-rw-r--r--server-tools/instance-manager/log.cc167
-rw-r--r--server-tools/instance-manager/log.h84
-rw-r--r--server-tools/instance-manager/manager.cc70
-rw-r--r--server-tools/instance-manager/manager.h17
-rw-r--r--server-tools/instance-manager/mysqlmanager.cc249
-rw-r--r--server-tools/instance-manager/options.cc127
-rw-r--r--server-tools/instance-manager/options.h40
10 files changed, 795 insertions, 0 deletions
diff --git a/server-tools/Makefile.am b/server-tools/Makefile.am
new file mode 100644
index 00000000000..ed316b9ac38
--- /dev/null
+++ b/server-tools/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS= instance-manager
diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am
new file mode 100644
index 00000000000..f74a7d27304
--- /dev/null
+++ b/server-tools/instance-manager/Makefile.am
@@ -0,0 +1,29 @@
+INCLUDES= -I$(top_srcdir)/include
+
+# As all autoconf variables depend from ${prefix} and being resolved only when
+# make is run, we can't 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_LIBRARIES= liboptions.a
+liboptions_a_CPPFLAGS= $(CPPFLAGS) \
+ -DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
+ -DDEFAULT_LOG_FILE_NAME="$(localstatedir)/mysqlmanager.log" \
+ -DDEFAULT_SOCKET_FILE_NAME="$(localstatedir)/mysqlmanager.sock"
+
+liboptions_a_SOURCES= otpions.h options.cc
+
+bin_PROGRAMS = mysqlmanager
+
+#AM_CXXFLAGS= -Wformat=2 -W -Wall -Wformat-security
+mysqlmanager_SOURCES= mysqlmanager.cc manager.h manager.cc log.h log.cc
+mysqlmanager_LDADD= liboptions.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a \
+ $(top_builddir)/dbug/libdbug.a
+
+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
new file mode 100644
index 00000000000..ac799775003
--- /dev/null
+++ b/server-tools/instance-manager/README
@@ -0,0 +1,11 @@
+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/log.cc b/server-tools/instance-manager/log.cc
new file mode 100644
index 00000000000..7eb0f15b2a4
--- /dev/null
+++ b/server-tools/instance-manager/log.cc
@@ -0,0 +1,167 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 <stdarg.h>
+#include <m_string.h>
+#include <my_sys.h>
+
+/*
+ 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.
+ SYNOPSYS
+ log()
+*/
+
+static inline void log(FILE *file, 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[32];
+ sprintf(buff_date, "%02d%02d%02d %2d:%02d:%02d\t",
+ bd_time.tm_year % 100,
+ bd_time.tm_mon + 1,
+ bd_time.tm_mday,
+ bd_time.tm_hour,
+ bd_time.tm_min,
+ bd_time.tm_sec);
+ /* 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, 0);
+ while (true)
+ {
+ if (buff_msg == 0)
+ {
+ strmake(buff_stack, "log(): message is too big, my_malloc() failed",
+ sizeof(buff_stack));
+ 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, 0);
+ }
+ }
+ else if ((size_t) n > sizeof(buff_stack))
+ {
+ buff_msg= (char *) my_malloc(n + 1, 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() */
+}
+
+
+void log_error(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log(stderr, format, args);
+ va_end(args);
+}
+
+
+void log_info(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log(stdout, format, args);
+ va_end(args);
+}
+
+/* TODO: rewrite with buffering print */
+void print_info(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vfprintf(stdout, format, args);
+ va_end(args);
+}
+
+void print_error(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+/*
+ init_logs()
+ RETURN VALUE
+ 0 ok
+ !0 error
+*/
+
+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);
+}
+
+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
new file mode 100644
index 00000000000..e4236f3751c
--- /dev/null
+++ b/server-tools/instance-manager/log.h
@@ -0,0 +1,84 @@
+#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_LOG_H
+#define INCLUDES_MYSQL_INSTANCE_MANAGER_LOG_H
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+/*
+ 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 may be performed in two modes:
+ - console application mode (default), stdout/stderr is used for logging
+ init_logs() must be called to initialize logging environment
+ - daemon mode, without controlling terminal, call
+ init_logs_in_daemon_mode() to initialize
+
+ 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
+ Function names are subject to change.
+*/
+
+
+/* Precede error message with date and time and print it to the stdout */
+void log_info(const char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format(printf, 1, 2)))
+#endif
+ ;
+
+
+/* Precede error message with date and time and print it to the stderr */
+void log_error(const char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+ ;
+
+
+/*
+ Now this is simple catchouts for printf (no date/time is logged), to be
+ able to replace underlying streams in future.
+*/
+
+void print_info(const char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+ ;
+
+
+void print_error(const char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+ ;
+
+/* initialize logs */
+void log_init();
+
+
+/* initialize logs for daemon application */
+
+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
new file mode 100644
index 00000000000..041232da402
--- /dev/null
+++ b/server-tools/instance-manager/manager.cc
@@ -0,0 +1,70 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 "log.h"
+
+//#include "mysql_connection.h"
+
+void manager(const char *socket_file_name)
+{
+ while (true)
+ {
+ log_info("manager is alive");
+ sleep(2);
+ }
+#if 0
+ /*
+ Dummy manager implementation: listens on a UNIX socket and
+ starts echo server in a dedicated thread for each accepted connection.
+ Enough to test startup/shutdown/options/logging of the instance manager.
+ */
+
+ int fd= socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (!fd)
+ die("socket(): failed");
+
+ struct sockaddr_un address;
+ bzero(&address, sizeof(address));
+ address.sun_family= AF_UNIX;
+ strcpy(address.sun_path, socket_path);
+ int opt= 1;
+
+ if (unlink(socket_path) ||
+ bind(fd, (struct sockaddr *) &address, sizeof(address)) ||
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
+ die("unlink | bind | setsockopt failed");
+
+ if (listen(fd, 5))
+ die("listen() failed");
+
+ int client_fd;
+ while ((client_fd= accept(fd, 0, 0)) != -1);
+ {
+ printf("accepted\n");
+ const char *message= "\n10hel";
+ send(client_fd, message, strlen(message), 0);
+
+ int sleep_seconds= argc > 1 && atoi(argv[1]) ? atoi(argv[1]) : 1;
+ printf("sleeping %d seconds\n", sleep_seconds);
+ sleep(sleep_seconds);
+ close(client_fd);
+ }
+ printf("accept(): failed\n");
+ close(fd);
+#endif
+}
diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h
new file mode 100644
index 00000000000..0a6c0e03575
--- /dev/null
+++ b/server-tools/instance-manager/manager.h
@@ -0,0 +1,17 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+void manager(const char *socket_file_name);
diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc
new file mode 100644
index 00000000000..a08b0691eec
--- /dev/null
+++ b/server-tools/instance-manager/mysqlmanager.cc
@@ -0,0 +1,249 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include "manager.h"
+#include "options.h"
+#include "log.h"
+
+/*
+ Few notes about the Instance Manager architecture:
+ Instance Manager consisits of two processes: the angel process, and the
+ instance manager process. Responsibilities of the angel process is to
+ monitor the instance manager process, and restart it in case of
+ failure/shutdown. The angel process is started only if startup option
+ '--run-as-service' is provided.
+ The Instance Manager process consists of several
+ subsystems (thread sets):
+ - the signal handling thread: it's responsibilities are to handle
+ user signals and propogate them to the other threads. All other threads
+ are accounted in the signal handler thread Thread Repository.
+ - the listener: listens all sockets. There is a listening
+ socket for each (mysql, http, snmp, rendezvous (?)) subsystem.
+ - 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.
+ - http subsystem: it is also possible to talk with Instance Manager via
+ http. One thread per http connection is used. Threads are pooled.
+ - 'snmp' connections (FIXME: I know nothing about it yet)
+ - rendezvous threads
+*/
+
+static void init_environment(char *progname);
+static void daemonize(const char *log_file_name);
+static void angel(const Options &options);
+
+
+/*
+ main, entry point
+ - init environment
+ - handle options
+ - daemonize and run angel process (if necessary)
+ - run manager process
+*/
+
+int main(int argc, char *argv[])
+{
+ init_environment(argv[0]);
+ Options options;
+ options.load(argc, argv);
+ if (options.run_as_service)
+ {
+ daemonize(options.log_file_name);
+ angel(options);
+ }
+ else
+ manager(options.log_file_name);
+ return 0;
+}
+
+/******************* Auxilary functions implementation **********************/
+
+
+/*
+ Init environment, common for daemon and non-daemon
+*/
+
+static void init_environment(char *progname)
+{
+ MY_INIT(progname);
+ log_init();
+ umask(0117);
+}
+
+
+/*
+ Become a UNIX service
+ SYNOPSYS
+ daemonize()
+*/
+
+static void daemonize(const char *log_file_name)
+{
+ pid_t pid= fork();
+ switch (pid) {
+ case -1: // parent, fork error
+ die("daemonize(): fork failed, %s", strerror(errno));
+ case 0: // child, fork ok
+ int fd;
+ /*
+ Become a session leader: setsid should succeed because child is
+ guaranteed not to be a process group leader (it belongs to the
+ process group of the parent.)
+ The goal is not to have a controlling terminal.
+ */
+ if (setsid() == -1)
+ die("daemonize(): setsid() failed, %s", strerror(errno));
+ /*
+ As we now don't have a controlling terminal we will not receive
+ tty-related signals - no need to ignore them.
+ */
+
+ close(STDIN_FILENO);
+
+ fd= open(log_file_name, O_WRONLY | O_CREAT | O_APPEND | O_NOCTTY,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ if (fd < 0)
+ die("daemonize(): failed to open log file %s, %s", log_file_name,
+ strerror(errno));
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd != STDOUT_FILENO && fd != STDERR_FILENO)
+ close(fd);
+
+ /* TODO: chroot() and/or chdir() here */
+ break;
+ default:
+ /* successfully exit from parent */
+ exit(0);
+ }
+}
+
+
+enum { CHILD_OK= 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL };
+
+static volatile sig_atomic_t child_status= CHILD_OK;
+
+/*
+ Signal handler for SIGCHLD: reap child, analyze child exit status, and set
+ child_status appropriately.
+*/
+
+void reap_child(int __attribute__((unused)) signo)
+{
+ int child_exit_status;
+ /* As we have only one child, no need to cycle waitpid */
+ if (waitpid(0, &child_exit_status, WNOHANG) > 0)
+ {
+ if (WIFSIGNALED(child_exit_status))
+ child_status= CHILD_NEED_RESPAWN;
+ else
+ /*
+ As we reap_child is not called for SIGSTOP, we should be here only
+ if the child exited normally.
+ */
+ child_status= CHILD_EXIT_ANGEL;
+ }
+}
+
+/* Not static to reuse it in childs */
+
+volatile sig_atomic_t is_terminated= 0;
+
+/*
+ Signal handler for terminate signals - SIGTERM, SIGHUP, SIGINT.
+ Set termination status and return.
+ (q) do we need to handle SIGQUIT?
+*/
+
+void terminate(int signo)
+{
+ is_terminated= signo;
+}
+
+
+/*
+ Fork a child and monitor it.
+ User can explicitly kill the angel process with SIGTERM/SIGHUP/SIGINT.
+ Angel process will exit silently if mysqlmanager exits normally.
+*/
+
+static void angel(const Options &options)
+{
+ /* install signal handlers */
+ sigset_t zeromask; // to sigsuspend in parent
+ struct sigaction sa_chld, sa_term;
+ struct sigaction sa_chld_out, sa_term_out, sa_int_out, sa_hup_out;
+ if (sigemptyset(&zeromask) ||
+ sigemptyset(&sa_chld.sa_mask) ||
+ sigemptyset(&sa_term.sa_mask)) // how can it fail?
+ die("angel(): sigemptyset() failed, %s", strerror(errno));
+ sa_chld.sa_handler= reap_child;
+ sa_chld.sa_flags= SA_NOCLDSTOP;
+ sa_term.sa_handler= terminate;
+ sa_term.sa_flags= 0;
+ if (sigaction(SIGCHLD, &sa_chld, &sa_chld_out) == -1 ||
+ sigaction(SIGTERM, &sa_term, &sa_term_out) == -1 ||
+ sigaction(SIGINT, &sa_term, &sa_int_out) == -1 ||
+ sigaction(SIGHUP, &sa_term, &sa_hup_out) == -1)
+ die("angel(): sigaction() failed, %s", strerror(errno));
+
+ /* spawn a child */
+spawn:
+ pid_t pid= fork();
+ switch (pid) {
+ case -1:
+ die("angel(): fork failed, %s", strerror(errno));
+ case 0: // child, success
+ /*
+ restore default actions for signals to let the manager work with
+ signals as he wishes
+ */
+ if (sigaction(SIGCHLD, &sa_chld_out, 0) == -1 ||
+ sigaction(SIGTERM, &sa_term_out, 0) == -1 ||
+ sigaction(SIGINT, &sa_int_out, 0) == -1 ||
+ sigaction(SIGHUP, &sa_hup_out, 0) == -1)
+ die("angel(): child failed to restore old signal actions, %s",
+ strerror(errno));
+
+ manager(options.socket_file_name);
+ default: // parent, success
+ while (child_status == CHILD_OK && is_terminated == 0)
+ {
+ errno= 0;
+ sigsuspend(&zeromask);
+ if (errno != EINTR)
+ die("angel(): sigsuspend failed, %s", strerror(errno));
+ }
+ if (is_terminated)
+ log_info("angel got signal %d (%s), exiting",
+ is_terminated, sys_siglist[is_terminated]);
+ else if (child_status == CHILD_NEED_RESPAWN)
+ {
+ child_status= CHILD_OK;
+ log_error("angel(): mysqlmanager exited abnormally: respawning...");
+ sleep(1); /* don't respawn too fast */
+ goto spawn;
+ }
+ /* mysqlmanager successfully exited, let's silently evaporate */
+ }
+}
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
new file mode 100644
index 00000000000..c5bbee7d4a5
--- /dev/null
+++ b/server-tools/instance-manager/options.cc
@@ -0,0 +1,127 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 "options.h"
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <my_getopt.h>
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+
+#define QUOTE2(x) #x
+#define QUOTE(x) QUOTE2(x)
+
+char Options::run_as_service;
+const char *Options::log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
+const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
+const char *Options::socket_file_name= QUOTE(DEFAULT_SOCKET_FILE_NAME);
+
+/*
+ List of options, accepted by the instance manager.
+ List must be closed with empty option.
+*/
+
+enum options {
+ OPT_LOG= 256,
+ OPT_PID_FILE,
+ OPT_SOCKET,
+ OPT_RUN_AS_SERVICE
+};
+
+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 },
+
+ { "log", OPT_LOG, "Path to log file. Used only with --run-as-service.",
+ (gptr *) &Options::log_file_name, (gptr *) &Options::log_file_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+ { "pid-file", OPT_PID_FILE, "Pid file to use.",
+ (gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+ { "socket", OPT_SOCKET, "Socket file to use for connection.",
+ (gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+ { "run-as-service", OPT_RUN_AS_SERVICE,
+ "Daemonize and start angel process.", (gptr *) &Options::run_as_service,
+ 0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
+
+ { "version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
+
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
+};
+
+static void version()
+{
+ static const char mysqlmanager_version[] = "0.1-alpha";
+ printf("%s Ver %s for %s on %s\n", my_progname, mysqlmanager_version,
+ SYSTEM_TYPE, MACHINE_TYPE);
+}
+
+static void usage()
+{
+ version();
+ my_print_help(my_long_options);
+}
+
+C_MODE_START
+
+static my_bool
+get_one_option(int optid,
+ const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'V':
+ version();
+ exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+C_MODE_END
+
+
+/*
+ - call load_defaults to load configuration file section
+ - call handle_options to assign defaults and command-line arguments
+ to the class members
+ if either of these function fail, exit the program
+ May not return.
+*/
+
+void Options::load(int argc, char **argv)
+{
+ if (int rc= handle_options(&argc, &argv, my_long_options, get_one_option))
+ exit(rc);
+}
+
+void init_mysys_library(const char *progname)
+{
+ MY_INIT((char *) progname);
+}
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
new file mode 100644
index 00000000000..1a9857ed62a
--- /dev/null
+++ b/server-tools/instance-manager/options.h
@@ -0,0 +1,40 @@
+#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
+#define INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 */
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+/*
+ Options - all possible options for the instance manager grouped in one
+ struct.
+*/
+
+struct Options
+{
+ static char run_as_service; /* handle_options doesn't support bool */
+ static const char *log_file_name;
+ static const char *pid_file_name;
+ static const char *socket_file_name;
+
+ static void load(int argc, char **argv);
+};
+
+void init_mysys_library(const char *progname);
+
+#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H