mysqld_safe.c 16 KB
Newer Older
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
1
/*
monty@mysql.com's avatar
monty@mysql.com committed
2
  Copyright (c) 2003 Novell, Inc. All Rights Reserved.
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
3

monty@mysql.com's avatar
monty@mysql.com committed
4 5 6 7 8 9 10 11 12
  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.
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
13

monty@mysql.com's avatar
monty@mysql.com committed
14 15
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
16
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
monty@mysql.com's avatar
monty@mysql.com committed
17
*/
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

#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
monty@mysql.com's avatar
monty@mysql.com committed
35

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
36 37 38
******************************************************************************/
char autoclose;
char basedir[PATH_MAX];
greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
39
char checktables;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
40 41 42 43 44 45 46 47 48 49
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];

monty@mysql.com's avatar
monty@mysql.com committed
50
FILE *log_fd= NULL;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
51 52 53 54

/******************************************************************************

	prototypes
monty@mysql.com's avatar
monty@mysql.com committed
55

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
56 57
******************************************************************************/

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
58
void usage(void);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
59 60
void vlog(char *, va_list);
void log(char *, ...);
monty@mysql.com's avatar
monty@mysql.com committed
61
void start_defaults(int, char *[]);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
62
void finish_defaults();
63
void read_defaults(arg_list_t *);
monty@mysql.com's avatar
monty@mysql.com committed
64 65
void parse_args(int, char *[]);
void get_options(int, char *[]);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
66 67 68
void check_data_vol();
void check_setup();
void check_tables();
monty@mysql.com's avatar
monty@mysql.com committed
69
void mysql_start(int, char *[]);
70
void parse_setvar(char *arg);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
71 72 73 74

/******************************************************************************

	functions
monty@mysql.com's avatar
monty@mysql.com committed
75

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
76 77 78 79
******************************************************************************/

/******************************************************************************

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
80
  usage()
monty@mysql.com's avatar
monty@mysql.com committed
81

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
82 83 84 85 86 87 88
  Show usage.

******************************************************************************/
void usage(void)
{
  // keep the screen up
  setscreenmode(SCR_NO_MODE);
monty@mysql.com's avatar
monty@mysql.com committed
89

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  puts("\
\n\
usage: mysqld_safe [options]\n\
\n\
Program to start the MySQL daemon and restart it if it dies unexpectedly.\n\
All options, besides those listed below, are passed on to the MySQL daemon.\n\
\n\
options:\n\
\n\
--autoclose                 Automatically close the mysqld_safe screen.\n\
\n\
--check-tables              Check the tables before starting the MySQL daemon.\n\
\n\
--err-log=<file>            Send the MySQL daemon error output to <file>.\n\
\n\
--help                      Show this help information.\n\
\n\
--mysqld=<file>             Use the <file> MySQL daemon.\n\
\n\
  ");
monty@mysql.com's avatar
monty@mysql.com committed
110

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
111 112 113 114 115
  exit(-1);
}

/******************************************************************************

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
116
  vlog()
monty@mysql.com's avatar
monty@mysql.com committed
117

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
118 119 120 121 122 123 124
  Log the message.

******************************************************************************/
void vlog(char *format, va_list ap)
{
  vfprintf(stdout, format, ap);
  fflush(stdout);
monty@mysql.com's avatar
monty@mysql.com committed
125

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
126 127 128 129 130 131 132 133 134 135
  if (log_fd)
  {
    vfprintf(log_fd, format, ap);
    fflush(log_fd);
  }
}

/******************************************************************************

  log()
monty@mysql.com's avatar
monty@mysql.com committed
136

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
137 138 139 140 141 142
  Log the message.

******************************************************************************/
void log(char *format, ...)
{
  va_list ap;
monty@mysql.com's avatar
monty@mysql.com committed
143

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
144 145 146
  va_start(ap, format);

  vlog(format, ap);
monty@mysql.com's avatar
monty@mysql.com committed
147

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
148 149 150 151 152 153
  va_end(ap);
}

/******************************************************************************

	start_defaults()
monty@mysql.com's avatar
monty@mysql.com committed
154

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
155 156 157 158 159 160 161
	Start setting the defaults.

******************************************************************************/
void start_defaults(int argc, char *argv[])
{
  struct stat buf;
  int i;
monty@mysql.com's avatar
monty@mysql.com committed
162

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
163
  // default options
monty@mysql.com's avatar
monty@mysql.com committed
164
  static char *default_options[]=
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
165
  {
monty@mysql.com's avatar
monty@mysql.com committed
166 167 168 169
    "--no-defaults",
    "--defaults-file=",
    "--defaults-extra-file=",
    NULL
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
170
  };
monty@mysql.com's avatar
monty@mysql.com committed
171

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
172
  // autoclose
monty@mysql.com's avatar
monty@mysql.com committed
173 174
  autoclose= FALSE;

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
175 176
  // basedir
  get_basedir(argv[0], basedir);
monty@mysql.com's avatar
monty@mysql.com committed
177

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
178
  // check-tables
monty@mysql.com's avatar
monty@mysql.com committed
179 180
  checktables= FALSE;

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
181
  // hostname
monty@mysql.com's avatar
monty@mysql.com committed
182
  if (gethostname(hostname, PATH_MAX) < 0)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
183 184
  {
    // default
monty@mysql.com's avatar
monty@mysql.com committed
185
    strcpy(hostname, "mysql");
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
186 187 188 189 190 191
  }

  // address
  snprintf(address, PATH_MAX, "0.0.0.0");

  // port
192
  snprintf(port, PATH_MAX, "%d", MYSQL_PORT);
monty@mysql.com's avatar
monty@mysql.com committed
193

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
194
  // default option
monty@mysql.com's avatar
monty@mysql.com committed
195 196 197 198 199 200 201 202 203 204
  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;
    }
  }

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
205
  // set after basedir is established
monty@mysql.com's avatar
monty@mysql.com committed
206 207 208 209 210
  datadir[0]= NULL;
  pid_file[0]= NULL;
  err_log[0]= NULL;
  safe_log[0]= NULL;
  mysqld[0]= NULL;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
211 212 213 214 215
}

/******************************************************************************

	finish_defaults()
monty@mysql.com's avatar
monty@mysql.com committed
216

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
217 218 219 220 221 222 223
	Finish settig the defaults.

******************************************************************************/
void finish_defaults()
{
  struct stat buf;
  int i;
monty@mysql.com's avatar
monty@mysql.com committed
224

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
225
  // datadir
monty@mysql.com's avatar
monty@mysql.com committed
226 227 228
  if (!datadir[0])
    snprintf(datadir, PATH_MAX, "%s/data", basedir);

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
229
  // pid-file
monty@mysql.com's avatar
monty@mysql.com committed
230 231 232
  if (!pid_file[0])
    snprintf(pid_file, PATH_MAX, "%s/%s.pid", datadir, hostname);

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
233
  // err-log
monty@mysql.com's avatar
monty@mysql.com committed
234 235
  if (!err_log[0])
    snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
236 237

  // safe-log
monty@mysql.com's avatar
monty@mysql.com committed
238 239
  if (!safe_log[0])
    snprintf(safe_log, PATH_MAX, "%s/%s.safe", datadir, hostname);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
240 241

  // mysqld
monty@mysql.com's avatar
monty@mysql.com committed
242 243 244
  if (!mysqld[0])
    snprintf(mysqld, PATH_MAX, "%s/bin/mysqld-max", basedir);

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
245 246 247 248 249 250 251 252 253
  if (stat(mysqld, &buf))
  {
    snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
  }
}

/******************************************************************************

	read_defaults()
monty@mysql.com's avatar
monty@mysql.com committed
254

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
255 256 257
	Read the defaults.

******************************************************************************/
258
void read_defaults(arg_list_t *pal)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
259
{
260
  arg_list_t al;
261
  char defaults_file[PATH_MAX];
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
262 263 264
  char mydefaults[PATH_MAX];
  char line[PATH_MAX];
  FILE *fp;
265

monty@mysql.com's avatar
monty@mysql.com committed
266 267 268 269 270
  // defaults output file
  snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
  remove(defaults_file);

  // mysqladmin file
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
271
  snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
monty@mysql.com's avatar
monty@mysql.com committed
272

273
  // args
274 275
  init_args(&al);
  add_arg(&al, mydefaults);
monty@mysql.com's avatar
monty@mysql.com committed
276 277
  if (default_option[0])
    add_arg(&al, default_option);
278 279 280 281
  add_arg(&al, "mysqld");
  add_arg(&al, "server");
  add_arg(&al, "mysqld_safe");
  add_arg(&al, "safe_mysqld");
282

monty@mysql.com's avatar
monty@mysql.com committed
283
  spawn(mydefaults, &al, TRUE, NULL, defaults_file, NULL);
284

285
  free_args(&al);
286

monty@mysql.com's avatar
monty@mysql.com committed
287 288 289 290 291
  // gather defaults
  if ((fp= fopen(defaults_file, "r")) != NULL)
  {
    while (fgets(line, PATH_MAX, fp))
    {
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
292
      char *p;
monty@mysql.com's avatar
monty@mysql.com committed
293

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
294
      // remove end-of-line character
monty@mysql.com's avatar
monty@mysql.com committed
295 296 297
      if ((p= strrchr(line, '\n')) != NULL)
	*p= '\0';

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
298
      // add the option as an argument
monty@mysql.com's avatar
monty@mysql.com committed
299 300 301 302 303 304 305 306
      add_arg(pal, line);
    }

    fclose(fp);
  }

  // remove file
  remove(defaults_file);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
307 308 309 310 311
}

/******************************************************************************

	parse_args()
monty@mysql.com's avatar
monty@mysql.com committed
312

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
313 314 315 316 317
	Get the options.

******************************************************************************/
void parse_args(int argc, char *argv[])
{
monty@mysql.com's avatar
monty@mysql.com committed
318
  int index= 0;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
319
  int c;
monty@mysql.com's avatar
monty@mysql.com committed
320

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
321 322 323
  // parse options
  enum opts
  {
monty@mysql.com's avatar
monty@mysql.com committed
324
    OPT_BASEDIR= 0xFF,
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
325 326 327 328 329 330
    OPT_DATADIR,
    OPT_PID_FILE,
    OPT_BIND_ADDRESS,
    OPT_PORT,
    OPT_ERR_LOG,
    OPT_SAFE_LOG,
greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
331
    OPT_MYSQLD,
332 333
    OPT_HELP,
    OPT_SETVAR
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
334
  };
monty@mysql.com's avatar
monty@mysql.com committed
335 336

  static struct option options[]=
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
337
  {
monty@mysql.com's avatar
monty@mysql.com committed
338 339 340 341 342 343 344 345 346 347 348 349 350
    {"autoclose", no_argument, &autoclose, TRUE},
    {"basedir", required_argument, 0, OPT_BASEDIR},
    {"check-tables", no_argument, &checktables, TRUE},
    {"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},
    {"help", no_argument, 0, OPT_HELP},
    {"set-variable", required_argument, 0, OPT_SETVAR},
    {0, 0, 0, 0}
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
351
  };
monty@mysql.com's avatar
monty@mysql.com committed
352

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
353
  // we have to reset getopt_long because we use it multiple times
monty@mysql.com's avatar
monty@mysql.com committed
354 355
  optind= 1;

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
356
  // turn off error reporting
monty@mysql.com's avatar
monty@mysql.com committed
357 358 359
  opterr= 0;

  while ((c= getopt_long(argc, argv, "b:h:P:", options, &index)) >= 0)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
360
  {
monty@mysql.com's avatar
monty@mysql.com committed
361
    switch (c) {
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
362 363 364 365
    case OPT_BASEDIR:
    case 'b':
      strcpy(basedir, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
366

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
367 368 369 370
    case OPT_DATADIR:
    case 'h':
      strcpy(datadir, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
371

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
372 373 374
    case OPT_PID_FILE:
      strcpy(pid_file, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
375

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
376 377 378
    case OPT_BIND_ADDRESS:
      strcpy(address, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
379

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
380 381 382 383
    case OPT_PORT:
    case 'P':
      strcpy(port, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
384

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
385 386 387
    case OPT_ERR_LOG:
      strcpy(err_log, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
388

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
389 390 391
    case OPT_SAFE_LOG:
      strcpy(safe_log, optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
392

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
393 394 395
    case OPT_MYSQLD:
      strcpy(mysqld, optarg);
      break;
396 397 398 399

    case OPT_SETVAR:
      parse_setvar(optarg);
      break;
monty@mysql.com's avatar
monty@mysql.com committed
400

greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
401 402 403
    case OPT_HELP:
      usage();
      break;
monty@mysql.com's avatar
monty@mysql.com committed
404

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
405 406 407 408 409 410 411
    default:
      // ignore
      break;
    }
  }
}

412 413 414 415 416 417 418
/*
  parse_setvar(char *arg)
  Pasrsing for port just to display the port num on the mysqld_safe screen
*/
void parse_setvar(char *arg)
{
  char *pos;
monty@mysql.com's avatar
monty@mysql.com committed
419

420 421
  if ((pos= strindex(arg, "port")))
  {
monty@mysql.com's avatar
monty@mysql.com committed
422
    for (; *pos && *pos != '='; pos++);
423 424 425 426
    if (*pos)
      strcpy(port, pos + 1);
  }
}
monty@mysql.com's avatar
monty@mysql.com committed
427

428 429 430 431
/******************************************************************************



gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
432 433 434
/******************************************************************************

	get_options()
monty@mysql.com's avatar
monty@mysql.com committed
435

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
436 437 438 439 440
	Get the options.

******************************************************************************/
void get_options(int argc, char *argv[])
{
441
  arg_list_t al;
monty@mysql.com's avatar
monty@mysql.com committed
442

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
443 444 445 446
  // start defaults
  start_defaults(argc, argv);

  // default file arguments
447 448 449 450 451
  init_args(&al);
  add_arg(&al, "ignore");
  read_defaults(&al);
  parse_args(al.argc, al.argv);
  free_args(&al);
monty@mysql.com's avatar
monty@mysql.com committed
452

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
453 454
  // command-line arguments
  parse_args(argc, argv);
monty@mysql.com's avatar
monty@mysql.com committed
455

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
456 457 458 459 460 461 462
  // finish defaults
  finish_defaults();
}

/******************************************************************************

	check_data_vol()
monty@mysql.com's avatar
monty@mysql.com committed
463

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
464 465 466 467 468 469 470 471 472
	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;
monty@mysql.com's avatar
monty@mysql.com committed
473

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
474 475
  // clear struct
  memset(&vol, 0, sizeof(vol));
monty@mysql.com's avatar
monty@mysql.com committed
476

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
477 478
  // find volume name
  strcpy(buff, datadir);
monty@mysql.com's avatar
monty@mysql.com committed
479
  if (p= strchr(buff, ':'))
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
480 481
  {
    // terminate after volume name
monty@mysql.com's avatar
monty@mysql.com committed
482
    *p= 0;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
483 484 485 486 487 488
  }
  else
  {
    // assume SYS volume
    strcpy(buff, "SYS");
  }
monty@mysql.com's avatar
monty@mysql.com committed
489

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
490 491
  // retrieve information
  netware_vol_info_from_name(&vol, buff);
492

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
493 494
  if ((vol.flags & VOL_NSS_PRESENT) == 0)
  {
495
    log("Error: Either the data directory does not exist or is not on an NSS volume!\n\n");
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
496 497 498 499 500 501 502
    exit(-1);
  }
}

/******************************************************************************

	check_setup()
monty@mysql.com's avatar
monty@mysql.com committed
503

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
504 505 506 507 508
	Check the current setup.

******************************************************************************/
void check_setup()
{
monty@mysql.com's avatar
monty@mysql.com committed
509
  struct stat info;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
510
  char temp[PATH_MAX];
monty@mysql.com's avatar
monty@mysql.com committed
511

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
512
  // remove any current pid_file
monty@mysql.com's avatar
monty@mysql.com committed
513 514
  if (!stat(pid_file, &info) && (remove(pid_file) < 0))
  {
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
515 516
    log("ERROR: Unable to remove current pid file!\n\n");
    exit(-1);
monty@mysql.com's avatar
monty@mysql.com committed
517 518 519
  }

  // check the data volume
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
520
  check_data_vol();
monty@mysql.com's avatar
monty@mysql.com committed
521

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
522 523 524 525 526 527 528 529 530 531 532 533
  // 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()
monty@mysql.com's avatar
monty@mysql.com committed
534

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
535 536 537 538 539
	Check the database tables.

******************************************************************************/
void check_tables()
{
540
  arg_list_t al;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
541
  char mycheck[PATH_MAX];
monty@mysql.com's avatar
monty@mysql.com committed
542 543 544 545 546
  char table[PATH_MAX];
  char db[PATH_MAX];
  DIR *datadir_entry, *db_entry, *table_entry;

  // status
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
547
  log("checking tables...\n");
monty@mysql.com's avatar
monty@mysql.com committed
548

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
549
  // list databases
monty@mysql.com's avatar
monty@mysql.com committed
550 551 552 553
  if ((datadir_entry= opendir(datadir)) == NULL)
  {
    return;
  }
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
554

monty@mysql.com's avatar
monty@mysql.com committed
555 556
  while ((db_entry= readdir(datadir_entry)) != NULL)
  {
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
557 558 559 560 561 562 563 564
    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);
monty@mysql.com's avatar
monty@mysql.com committed
565

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
566
      // list tables
monty@mysql.com's avatar
monty@mysql.com committed
567
      if ((db_entry= opendir(db)) == NULL)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
568
      {
monty@mysql.com's avatar
monty@mysql.com committed
569
	continue;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
570
      }
monty@mysql.com's avatar
monty@mysql.com committed
571 572

      while ((table_entry= readdir(db_entry)) != NULL)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
573
      {
monty@mysql.com's avatar
monty@mysql.com committed
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
	// 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);
	}
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
621 622
      }
    }
monty@mysql.com's avatar
monty@mysql.com committed
623
  }
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
624 625 626 627 628
}

/******************************************************************************

	mysql_start()
monty@mysql.com's avatar
monty@mysql.com committed
629

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
630 631 632 633 634
	Start the mysql server.

******************************************************************************/
void mysql_start(int argc, char *argv[])
{
635 636 637 638 639 640 641
  arg_list_t al;
  int i, j, err;
  struct stat info;
  time_t cal;
  struct tm lt;
  char stamp[PATH_MAX];
  char skip;
monty@mysql.com's avatar
monty@mysql.com committed
642

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
643
  // private options
monty@mysql.com's avatar
monty@mysql.com committed
644
  static char *private_options[]=
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
645
  {
646
    "--autoclose",
greg@mysql.com[greg]'s avatar
greg@mysql.com[greg] committed
647 648
    "--check-tables",
    "--help",
649 650 651
    "--err-log=",
    "--mysqld=",
    NULL
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
652
  };
monty@mysql.com's avatar
monty@mysql.com committed
653

654 655 656
  // args
  init_args(&al);
  add_arg(&al, "%s", mysqld);
monty@mysql.com's avatar
monty@mysql.com committed
657

658
  // parent args
monty@mysql.com's avatar
monty@mysql.com committed
659
  for (i= 1; i < argc; i++)
660
  {
monty@mysql.com's avatar
monty@mysql.com committed
661 662
    skip= FALSE;

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
663
    // skip private arguments
monty@mysql.com's avatar
monty@mysql.com committed
664
    for (j= 0; private_options[j]; j++)
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
665
    {
monty@mysql.com's avatar
monty@mysql.com committed
666
      if (!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
667
      {
monty@mysql.com's avatar
monty@mysql.com committed
668 669
	skip= TRUE;
	break;
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
670 671
      }
    }
monty@mysql.com's avatar
monty@mysql.com committed
672

673 674 675 676 677
    if (!skip)
    {
      add_arg(&al, "%s", argv[i]);
    }
  }
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
678
  // spawn
679 680 681
  do
  {
    // check the database tables
monty@mysql.com's avatar
monty@mysql.com committed
682 683 684
    if (checktables)
      check_tables();

685
    // status
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
686 687 688 689
    time(&cal);
    localtime_r(&cal, &lt);
    strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
    log("mysql started    : %s\n", stamp);
monty@mysql.com's avatar
monty@mysql.com committed
690

691 692 693 694
    // spawn mysqld
    spawn(mysqld, &al, TRUE, NULL, NULL, err_log);
  }
  while (!stat(pid_file, &info));
monty@mysql.com's avatar
monty@mysql.com committed
695

696
  // status
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
697 698 699 700
  time(&cal);
  localtime_r(&cal, &lt);
  strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
  log("mysql stopped    : %s\n\n", stamp);
monty@mysql.com's avatar
monty@mysql.com committed
701

702 703
  // free args
  free_args(&al);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
704 705 706 707 708
}

/******************************************************************************

	main()
monty@mysql.com's avatar
monty@mysql.com committed
709

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
710 711 712
******************************************************************************/
int main(int argc, char **argv)
{
monty@mysql.com's avatar
monty@mysql.com committed
713 714
  char temp[PATH_MAX];

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
715
  // get the options
monty@mysql.com's avatar
monty@mysql.com committed
716
  get_options(argc, argv);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
717 718

  // keep the screen up
monty@mysql.com's avatar
monty@mysql.com committed
719 720 721
  if (!autoclose)
    setscreenmode(SCR_NO_MODE);

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
722
  // create log file
monty@mysql.com's avatar
monty@mysql.com committed
723 724
  log_fd= fopen(safe_log, "w+");

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
725 726
  // header
  log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
monty@mysql.com's avatar
monty@mysql.com committed
727 728 729 730

  // status
  log("address          : %s\n", address);
  log("port             : %s\n", port);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
731
  log("daemon           : %s\n", mysqld);
monty@mysql.com's avatar
monty@mysql.com committed
732 733 734 735 736
  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);
gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
737
  log("\n");
monty@mysql.com's avatar
monty@mysql.com committed
738

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
739 740
  // check setup
  check_setup();
monty@mysql.com's avatar
monty@mysql.com committed
741

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
742
  // start the MySQL server
monty@mysql.com's avatar
monty@mysql.com committed
743 744 745 746 747 748
  mysql_start(argc, argv);

  // close log file
  if (log_fd)
    fclose(log_fd);

gweir@work.mysql.com's avatar
gweir@work.mysql.com committed
749 750
  return 0;
}