From 88301da1cd4feb1d7cbcad1984795f937ac8152e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 1 Feb 2003 00:42:26 +0100 Subject: 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 --- netware/mysqld_safe.c | 662 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 netware/mysqld_safe.c (limited to 'netware/mysqld_safe.c') 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- cgit v1.2.1