diff options
author | unknown <gweir@work.mysql.com> | 2003-02-01 00:42:26 +0100 |
---|---|---|
committer | unknown <gweir@work.mysql.com> | 2003-02-01 00:42:26 +0100 |
commit | 88301da1cd4feb1d7cbcad1984795f937ac8152e (patch) | |
tree | f7c383e264e8172bc011c8dc34a02e47c418eeb3 /netware/mysqld_safe.c | |
parent | 2479bdeae9e48165017d07f737dc30c911d305e1 (diff) | |
download | mariadb-git-88301da1cd4feb1d7cbcad1984795f937ac8152e.tar.gz |
Many files:
new file
Makefile.am:
Changes from Novell diff
netware/Makefile.am:
Changes from Novell diff
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'netware/mysqld_safe.c')
-rw-r--r-- | netware/mysqld_safe.c | 662 |
1 files changed, 662 insertions, 0 deletions
diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c new file mode 100644 index 00000000000..cf0d6989d8d --- /dev/null +++ b/netware/mysqld_safe.c @@ -0,0 +1,662 @@ +/*
+ Copyright (c) 2003 Novell, Inc. All Rights Reserved.
+
+ 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 <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <monitor.h>
+#include <strings.h>
+#include <getopt.h>
+#include <screen.h>
+#include <dirent.h>
+
+#include "my_config.h"
+#include "my_manage.h"
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+char autoclose;
+char basedir[PATH_MAX];
+char datadir[PATH_MAX];
+char pid_file[PATH_MAX];
+char address[PATH_MAX];
+char port[PATH_MAX];
+char err_log[PATH_MAX];
+char safe_log[PATH_MAX];
+char mysqld[PATH_MAX];
+char hostname[PATH_MAX];
+char default_option[PATH_MAX];
+
+FILE *log_fd = NULL;
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void vlog(char *, va_list);
+void log(char *, ...);
+void start_defaults(int, char*[]);
+void finish_defaults();
+void read_defaults(arg_list);
+void parse_args(int, char*[]);
+void get_options(int, char*[]);
+void check_data_vol();
+void check_setup();
+void check_tables();
+void mysql_start(int, char*[]);
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ vlog()
+
+ Log the message.
+
+******************************************************************************/
+void vlog(char *format, va_list ap)
+{
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ if (log_fd)
+ {
+ vfprintf(log_fd, format, ap);
+ fflush(log_fd);
+ }
+}
+
+/******************************************************************************
+
+ log()
+
+ Log the message.
+
+******************************************************************************/
+void log(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vlog(format, ap);
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ start_defaults()
+
+ Start setting the defaults.
+
+******************************************************************************/
+void start_defaults(int argc, char *argv[])
+{
+ struct stat buf;
+ int i;
+
+ // default options
+ static char *default_options[] =
+ {
+ "--no-defaults",
+ "--defaults-file=",
+ "--defaults-extra-file=",
+ NULL
+ };
+
+ // autoclose
+ autoclose = FALSE;
+
+ // basedir
+ get_basedir(argv[0], basedir);
+
+ // hostname
+ if (gethostname(hostname,PATH_MAX) < 0)
+ {
+ // default
+ strcpy(hostname,"mysql");
+ }
+
+ // address
+ snprintf(address, PATH_MAX, "0.0.0.0");
+
+ // port
+ snprintf(port, PATH_MAX, "3306");
+
+ // default option
+ default_option[0] = NULL;
+ for (i=0; (argc > 1) && default_options[i]; i++)
+ {
+ if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
+ {
+ strncpy(default_option, argv[1], PATH_MAX);
+ break;
+ }
+ }
+
+ // set after basedir is established
+ datadir[0] = NULL;
+ pid_file[0] = NULL;
+ err_log[0] = NULL;
+ safe_log[0] = NULL;
+ mysqld[0] = NULL;
+}
+
+/******************************************************************************
+
+ finish_defaults()
+
+ Finish settig the defaults.
+
+******************************************************************************/
+void finish_defaults()
+{
+ struct stat buf;
+ int i;
+
+ // datadir
+ if (!datadir[0]) snprintf(datadir, PATH_MAX, "%s/data", basedir);
+
+ // pid-file
+ if (!pid_file[0]) snprintf(pid_file, PATH_MAX, "%s/%s.pid", datadir, hostname);
+
+ // err-log
+ if (!err_log[0]) snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
+
+ // safe-log
+ if (!safe_log[0]) snprintf(safe_log, PATH_MAX, "%s/%s.log", datadir, hostname);
+
+ // mysqld
+ if (!mysqld[0]) snprintf(mysqld, PATH_MAX, "%s/bin/mysqld-max", basedir);
+
+ if (stat(mysqld, &buf))
+ {
+ snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
+ }
+}
+
+/******************************************************************************
+
+ read_defaults()
+
+ Read the defaults.
+
+******************************************************************************/
+void read_defaults(arg_list pal)
+{
+ arg_list al;
+ char defaults_file[PATH_MAX];
+ char mydefaults[PATH_MAX];
+ char line[PATH_MAX];
+ FILE *fp;
+
+ // defaults output file
+ snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
+ remove(defaults_file);
+
+ // mysqladmin file
+ snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
+
+ // args
+ init_args(al);
+ add_arg(al, mydefaults);
+ if (default_option[0]) add_arg(al, default_option);
+ add_arg(al, "mysqld");
+ add_arg(al, "server");
+ add_arg(al, "mysqld_safe");
+ add_arg(al, "safe_mysqld");
+
+ spawn(mydefaults, al, TRUE, NULL, defaults_file, NULL);
+
+ free_args(al);
+
+ // gather defaults
+ if((fp = fopen(defaults_file, "r")) != NULL)
+ {
+ while(fgets(line, PATH_MAX, fp))
+ {
+ char *p;
+
+ // remove end-of-line character
+ if ((p = strrchr(line, '\n')) != NULL) *p = '\0';
+
+ // add the option as an argument
+ add_arg(pal, line);
+ }
+
+ fclose(fp);
+ }
+
+ // remove file
+ remove(defaults_file);
+}
+
+/******************************************************************************
+
+ parse_args()
+
+ Get the options.
+
+******************************************************************************/
+void parse_args(int argc, char *argv[])
+{
+ int index = 0;
+ int c;
+
+ // parse options
+ enum opts
+ {
+ OPT_BASEDIR = 0xFF,
+ OPT_DATADIR,
+ OPT_PID_FILE,
+ OPT_BIND_ADDRESS,
+ OPT_PORT,
+ OPT_ERR_LOG,
+ OPT_SAFE_LOG,
+ OPT_MYSQLD
+ };
+
+ static struct option options[] =
+ {
+ {"autoclose", no_argument, &autoclose, TRUE},
+ {"basedir", required_argument, 0, OPT_BASEDIR},
+ {"datadir", required_argument, 0, OPT_DATADIR},
+ {"pid-file", required_argument, 0, OPT_PID_FILE},
+ {"bind-address", required_argument, 0, OPT_BIND_ADDRESS},
+ {"port", required_argument, 0, OPT_PORT},
+ {"err-log", required_argument, 0, OPT_ERR_LOG},
+ {"safe-log", required_argument, 0, OPT_SAFE_LOG},
+ {"mysqld", required_argument, 0, OPT_MYSQLD},
+ {0, 0, 0, 0}
+ };
+
+ // we have to reset getopt_long because we use it multiple times
+ optind = 1;
+
+ // turn off error reporting
+ opterr = 0;
+
+ while ((c = getopt_long(argc, argv, "b:h:P:", options, &index)) >= 0)
+ {
+ switch (c)
+ {
+ case OPT_BASEDIR:
+ case 'b':
+ strcpy(basedir, optarg);
+ break;
+
+ case OPT_DATADIR:
+ case 'h':
+ strcpy(datadir, optarg);
+ break;
+
+ case OPT_PID_FILE:
+ strcpy(pid_file, optarg);
+ break;
+
+ case OPT_BIND_ADDRESS:
+ strcpy(address, optarg);
+ break;
+
+ case OPT_PORT:
+ case 'P':
+ strcpy(port, optarg);
+ break;
+
+ case OPT_ERR_LOG:
+ strcpy(err_log, optarg);
+ break;
+
+ case OPT_SAFE_LOG:
+ strcpy(safe_log, optarg);
+ break;
+
+ case OPT_MYSQLD:
+ strcpy(mysqld, optarg);
+ break;
+
+ default:
+ // ignore
+ break;
+ }
+ }
+}
+
+/******************************************************************************
+
+ get_options()
+
+ Get the options.
+
+******************************************************************************/
+void get_options(int argc, char *argv[])
+{
+ arg_list al;
+
+ // start defaults
+ start_defaults(argc, argv);
+
+ // default file arguments
+ init_args(al);
+ add_arg(al, "dummy");
+ read_defaults(al);
+ parse_args(al->argc, al->argv);
+ free_args(al);
+
+ // command-line arguments
+ parse_args(argc, argv);
+
+ // finish defaults
+ finish_defaults();
+}
+
+/******************************************************************************
+
+ check_data_vol()
+
+ Check the database volume.
+
+******************************************************************************/
+void check_data_vol()
+{
+ // warn if the data is on a Traditional volume
+ struct volume_info vol;
+ char buff[PATH_MAX];
+ char *p;
+
+ // clear struct
+ memset(&vol, 0, sizeof(vol));
+
+ // find volume name
+ strcpy(buff, datadir);
+ if (p = strchr(buff, ':'))
+ {
+ // terminate after volume name
+ *p = 0;
+ }
+ else
+ {
+ // assume SYS volume
+ strcpy(buff, "SYS");
+ }
+
+ // retrieve information
+ netware_vol_info_from_name(&vol, buff);
+
+ if ((vol.flags & VOL_NSS_PRESENT) == 0)
+ {
+ log("Error: The data directory is not on an NSS volume!\n\n");
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_setup()
+
+ Check the current setup.
+
+******************************************************************************/
+void check_setup()
+{
+ struct stat info;
+ char temp[PATH_MAX];
+
+ // remove any current pid_file
+ if (!stat(pid_file, &info) && (remove(pid_file) < 0))
+ {
+ log("ERROR: Unable to remove current pid file!\n\n");
+ exit(-1);
+ }
+
+ // check the data volume
+ check_data_vol();
+
+ // check for a database
+ snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
+ if (stat(temp, &info))
+ {
+ log("ERROR: No database found in the data directory!\n\n");
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_tables()
+
+ Check the database tables.
+
+******************************************************************************/
+void check_tables()
+{
+ arg_list al;
+ char mycheck[PATH_MAX];
+ char table[PATH_MAX];
+ char db[PATH_MAX];
+ DIR *datadir_entry, *db_entry, *table_entry;
+
+ // status
+ log("checking tables...\n");
+
+ // list databases
+ if ((datadir_entry = opendir(datadir)) == NULL)
+ {
+ return;
+ }
+
+ while((db_entry = readdir(datadir_entry)) != NULL)
+ {
+ if (db_entry->d_name[0] == '.')
+ {
+ // Skip
+ }
+ else if (S_ISDIR(db_entry->d_type))
+ {
+ // create long db name
+ snprintf(db, PATH_MAX, "%s/%s", datadir, db_entry->d_name);
+
+ // list tables
+ if ((db_entry = opendir(db)) == NULL)
+ {
+ continue;
+ }
+
+ while((table_entry = readdir(db_entry)) != NULL)
+ {
+ // create long table name
+ snprintf(table, PATH_MAX, "%s/%s", db, strlwr(table_entry->d_name));
+
+ if (strindex(table, ".myi"))
+ {
+ // ** myisamchk
+
+ // mysqladmin file
+ snprintf(mycheck, PATH_MAX, "%s/bin/myisamchk", basedir);
+
+ // args
+ init_args(al);
+ add_arg(al, mycheck);
+ add_arg(al, "--silent");
+ add_arg(al, "--force");
+ add_arg(al, "--fast");
+ add_arg(al, "--medium-check");
+ add_arg(al, "-O");
+ add_arg(al, "key_buffer=64M");
+ add_arg(al, "-O");
+ add_arg(al, "sort_buffer=64M");
+ add_arg(al, table);
+
+ spawn(mycheck, al, TRUE, NULL, NULL, NULL);
+
+ free_args(al);
+ }
+ else if (strindex(table, ".ism"))
+ {
+ // ** isamchk
+
+ // mysqladmin file
+ snprintf(mycheck, PATH_MAX, "%s/bin/isamchk", basedir);
+
+ // args
+ init_args(al);
+ add_arg(al, mycheck);
+ add_arg(al, "--silent");
+ add_arg(al, "--force");
+ add_arg(al, "-O");
+ add_arg(al, "sort_buffer=64M");
+ add_arg(al, table);
+
+ spawn(mycheck, al, TRUE, NULL, NULL, NULL);
+
+ free_args(al);
+ }
+ }
+ }
+ }
+}
+
+/******************************************************************************
+
+ mysql_start()
+
+ Start the mysql server.
+
+******************************************************************************/
+void mysql_start(int argc, char *argv[])
+{
+ arg_list al;
+ int i, j, err;
+ struct stat info;
+ time_t cal;
+ struct tm lt;
+ char stamp[PATH_MAX];
+ char skip;
+
+ // private options
+ static char *private_options[] =
+ {
+ "--autoclose",
+ "--err-log=",
+ "--mysqld=",
+ NULL
+ };
+
+ // args
+ init_args(al);
+ add_arg(al, "%s", mysqld);
+
+ // parent args
+ for(i = 1; i < argc; i++)
+ {
+ skip = FALSE;
+
+ // skip private arguments
+ for (j=0; private_options[j]; j++)
+ {
+ if(!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
+ {
+ skip = TRUE;
+ break;
+ }
+ }
+
+ if (!skip) add_arg(al, "%s", argv[i]);
+ }
+
+ // spawn
+ do
+ {
+ // check the database tables
+ check_tables();
+
+ // status
+ time(&cal);
+ localtime_r(&cal, <);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", <);
+ log("mysql started : %s\n", stamp);
+
+ // spawn mysqld
+ spawn(mysqld, al, TRUE, NULL, NULL, err_log);
+ }
+ while (!stat(pid_file, &info));
+
+ // status
+ time(&cal);
+ localtime_r(&cal, <);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", <);
+ log("mysql stopped : %s\n\n", stamp);
+
+ // free args
+ free_args(al);
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
+ char temp[PATH_MAX];
+
+ // get the options
+ get_options(argc, argv);
+
+ // keep the screen up
+ if (!autoclose) setscreenmode(SCR_NO_MODE);
+
+ // create log file
+ log_fd = fopen(safe_log, "w+");
+
+ // header
+ log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+ // status
+ log("address : %s\n", address);
+ log("port : %s\n", port);
+ log("daemon : %s\n", mysqld);
+ log("base directory : %s\n", basedir);
+ log("data directory : %s\n", datadir);
+ log("pid file : %s\n", pid_file);
+ log("error file : %s\n", err_log);
+ log("log file : %s\n", safe_log);
+ log("\n");
+
+ // check setup
+ check_setup();
+
+ // start the MySQL server
+ mysql_start(argc, argv);
+
+ // close log file
+ if (log_fd) fclose(log_fd);
+
+ return 0;
+}
|