Пример #1
0
my_bool
my_io_wait_async(struct mysql_async_context *b, enum enum_vio_io_event event,
                 int timeout)
{
  switch (event)
  {
  case VIO_IO_EVENT_READ:
    b->events_to_wait_for = MYSQL_WAIT_READ;
    break;
  case VIO_IO_EVENT_WRITE:
    b->events_to_wait_for = MYSQL_WAIT_WRITE;
    break;
  case VIO_IO_EVENT_CONNECT:
    b->events_to_wait_for = MYSQL_WAIT_WRITE | IF_WIN(0, MYSQL_WAIT_EXCEPT);
    break;
  }

  if (timeout >= 0)
  {
    b->events_to_wait_for |= MYSQL_WAIT_TIMEOUT;
    b->timeout_value= timeout;
  }
  if (b->suspend_resume_hook)
    (*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
  my_context_yield(&b->async_context);
  if (b->suspend_resume_hook)
    (*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
  return (b->events_occurred & MYSQL_WAIT_TIMEOUT) ? 0 : 1;
}
Пример #2
0
ssize_t
my_send_async(struct mysql_async_context *b, int fd,
              const unsigned char *buf, size_t size, int timeout)
{
  ssize_t res;

  for (;;)
  {
    res= send(fd, buf, size, IF_WIN(0, MSG_DONTWAIT));
    if (res >= 0 || IS_BLOCKING_ERROR())
      return res;
    b->events_to_wait_for= MYSQL_WAIT_WRITE;
    if (timeout >= 0)
    {
      b->events_to_wait_for|= MYSQL_WAIT_TIMEOUT;
      b->timeout_value= timeout;
    }
    if (b->suspend_resume_hook)
      (*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
    my_context_yield(&b->async_context);
    if (b->suspend_resume_hook)
      (*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
    if (b->events_occurred & MYSQL_WAIT_TIMEOUT)
      return -1;
  }
}
Пример #3
0
static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...)
{
  int ret;
  const char* arg;
  va_list args;
  DYNAMIC_STRING ds_cmdline;

  DBUG_ENTER("run_tool");
  DBUG_PRINT("enter", ("tool_path: %s", tool_path));

  if (init_dynamic_string(&ds_cmdline, IF_WIN("\"", ""), FN_REFLEN, FN_REFLEN))
    die("Out of memory");

  dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS);
  dynstr_append(&ds_cmdline, " ");

  va_start(args, ds_res);

  while ((arg= va_arg(args, char *)))
  {
    /* Options should be os quoted */
    if (strncmp(arg, "--", 2) == 0)
      dynstr_append_os_quoted(&ds_cmdline, arg, NullS);
    else
      dynstr_append(&ds_cmdline, arg);
    dynstr_append(&ds_cmdline, " ");
  }

  va_end(args);

#ifdef __WIN__
  dynstr_append(&ds_cmdline, "\"");
#endif

  DBUG_PRINT("info", ("Running: %s", ds_cmdline.str));
  ret= run_command(ds_cmdline.str, ds_res);
  DBUG_PRINT("exit", ("ret: %d", ret));
  dynstr_free(&ds_cmdline);
  DBUG_RETURN(ret);
}
int
basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
  int ret;

  if (size == 0)
  {
    char buf[1];
    return basestring_vsnprintf(buf, 1, format, ap);
  }
  ret = IF_WIN(_vsnprintf,vsnprintf)(str, size, format, ap);
  if (ret >= 0 && ret < (int)size)
    return ret;
#ifdef _WIN32
  if (ret < 0 && errno == EINVAL)
    return ret;
  // otherwise, more than size chars are needed
  return _vscprintf(format, ap);
#else
  return ret;
#endif
}
Пример #5
0
static
bool
create_directory(const char * path)
{
  BaseString native(path);
  to_native(native);
  BaseString tmp(path);
  Vector<BaseString> list;

  if (tmp.split(list, "/") == 0)
  {
    g_logger.error("Failed to create directory: %s", tmp.c_str());
    return false;
  }
  
  BaseString cwd = IF_WIN("","/");
  for (unsigned i = 0; i < list.size(); i++)
  {
    cwd.append(list[i].c_str());
    cwd.append("/");
    NdbDir::create(cwd.c_str(),
                   NdbDir::u_rwx() | NdbDir::g_r() | NdbDir::g_x(),
                   true);
  }

  struct stat sbuf;
  if (lstat(native.c_str(), &sbuf) != 0 ||
      !S_ISDIR(sbuf.st_mode))
  {
    g_logger.error("Failed to create directory: %s (%s)", 
		   native.c_str(),
		   cwd.c_str());
    return false;
  }
  
  return true;
}
Пример #6
0
int
CPCD::Process::start() {
  /* We need to fork() twice, so that the second child (grandchild?) can
   * become a daemon. The original child then writes the pid file,
   * so that the monitor knows the pid of the new process, and then
   * exit()s. That way, the monitor process can pickup the pid, and
   * the running process is a daemon.
   *
   * This is a bit tricky but has the following advantages:
   *  - the cpcd can die, and "reconnect" to the monitored clients
   *    without restarting them.
   *  - the cpcd does not have to wait() for the childs. init(1) will
   *    take care of that.
   */
  logger.info("Starting %d: %s", m_id, m_name.c_str());
  m_status = STARTING;
    
  int pid = -1;
  switch(m_processType){
  case TEMPORARY:{
#ifndef _WIN32
    /**
     * Simple fork
     * don't ignore child
     */
    switch(pid = fork()) {
    case 0: /* Child */
      setsid();
      writePid(getpgrp());
      if(runas(m_runas.c_str()) == 0){
        signal(SIGCHLD, SIG_DFL);
	do_exec();
      }
      _exit(1);
      break;
    case -1: /* Error */
      logger.error("Cannot fork: %s\n", strerror(errno));
      m_status = STOPPED;
      return -1;
      break;
    default: /* Parent */
      logger.debug("Started temporary %d : pid=%d", m_id, pid);
      break;
    }
#else //_WIN32
    do_exec();
#endif
    break;
  }
#ifndef _WIN32
  case PERMANENT:{
    /**
     * PERMANENT
     */
    switch(fork()) {
    case 0: /* Child */
      signal(SIGCHLD, SIG_IGN);
      switch(pid = fork()) {
      case 0: /* Child */
	setsid();
	writePid(getpgrp());
	if(runas(m_runas.c_str()) != 0){
	  _exit(1);
	}
        signal(SIGCHLD, SIG_DFL);
	do_exec();
	_exit(1);
	/* NOTREACHED */
	break;
      case -1: /* Error */
	logger.error("Cannot fork: %s\n", strerror(errno));
	writePid(-1);
	_exit(1);
	break;
      default: /* Parent */
	logger.debug("Started permanent %d : pid=%d", m_id, pid);
	_exit(0);
	break;
      }
      break;
    case -1: /* Error */
      logger.error("Cannot fork: %s\n", strerror(errno));
      m_status = STOPPED;
      return -1;
      break;
    default: /* Parent */
      break;
    }
    break;
  }
#endif
  default:
    logger.critical("Unknown process type");
    return -1;
  }

  while(readPid() < 0){
    sched_yield();
  }
  
  errno = 0;
  pid_t pgid = IF_WIN(-1, getpgid(pid));
  
  if(pgid != -1 && pgid != m_pid){
    logger.error("pgid and m_pid don't match: %d %d (%d)", pgid, m_pid, pid);
  }

  if(isRunning()){
    m_status = RUNNING;
    return 0;
  }
  m_status = STOPPED;

  return -1;
}
Пример #7
0
void
CPCD::Process::do_exec() {
  unsigned i;

#ifdef _WIN32
  Vector<BaseString> saved;
  char *cwd = 0;
  save_environment(m_env.c_str(), saved);
#endif

  setup_environment(m_env.c_str());

  char **argv = BaseString::argify(m_path.c_str(), m_args.c_str());

  if(strlen(m_cwd.c_str()) > 0) {
#ifdef _WIN32
    cwd = getcwd(0, 0);
    if(!cwd)
    {
      logger.critical("Couldn't getcwd before spawn");
    }
#endif
    int err = chdir(m_cwd.c_str());
    if(err == -1) {
      BaseString err;
      logger.error("%s: %s\n", m_cwd.c_str(), strerror(errno));
      _exit(1);
    }
  }
#ifndef _WIN32
  Vector<BaseString> ulimit;
  m_ulimit.split(ulimit);
  for(i = 0; i<ulimit.size(); i++){
    if(ulimit[i].trim().length() > 0 && set_ulimit(ulimit[i]) != 0){
      _exit(1);
    }
  }
#endif

  const char *nul = IF_WIN("nul:", "/dev/null");
  int fdnull = open(nul, O_RDWR, 0);
  if(fdnull == -1) {
    logger.error("Cannot open `%s': %s\n", nul, strerror(errno));
    _exit(1);
  }
  
  BaseString * redirects[] = { &m_stdin, &m_stdout, &m_stderr };
  int fds[3];
#ifdef _WIN32
  int std_dups[3];
#endif
  for (i = 0; i < 3; i++) {
#ifdef _WIN32
    std_dups[i] = dup(i);
#endif
    if (redirects[i]->empty()) {
#ifndef DEBUG
      dup2(fdnull, i);
#endif
      continue;
    }
    
    if((* redirects[i]) == "2>&1" && i == 2){
      dup2(fds[1], 2);
      continue;
    }
    
    /**
     * Make file
     */
    int flags = 0;
    int mode = S_IRUSR | S_IWUSR ;
    if(i == 0){
      flags |= O_RDONLY;
    } else {
      flags |= O_WRONLY | O_CREAT | O_APPEND;
    }
    int f = fds[i]= open(redirects[i]->c_str(), flags, mode);
    if(f == -1){
      logger.error("Cannot redirect %u to/from '%s' : %s\n", i,
		   redirects[i]->c_str(), strerror(errno));
      _exit(1);
    }
    dup2(f, i);
#ifdef _WIN32
    close(f);
#endif
  }

#ifndef _WIN32
  /* Close all filedescriptors */
  for(i = STDERR_FILENO+1; (int)i < getdtablesize(); i++)
    close(i);

  execv(m_path.c_str(), argv);
  /* XXX If we reach this point, an error has occurred, but it's kind of hard
   * to report it, because we've closed all files... So we should probably
   * create a new logger here */
  logger.error("Exec failed: %s\n", strerror(errno));
  /* NOTREACHED */
#else

  // Get full path to cygwins shell
  FILE *fpipe = _popen("sh -c 'cygpath -w `which sh`'", "rt");
  char buf[MAX_PATH];

  require(fgets(buf, MAX_PATH - 1, fpipe));
  fclose(fpipe);

  BaseString sh;
  sh.assign(buf);
  sh.trim("\n");
  sh.append(".exe");

  BaseString shcmd;
  shcmd.assfmt("%s -c '%s %s'", sh.c_str(), m_path.c_str(), m_args.c_str());

  PROCESS_INFORMATION pi = {0};
  STARTUPINFO si = {sizeof(STARTUPINFO), 0};

  si.dwFlags   |=  STARTF_USESTDHANDLES;
  si.hStdInput  = (HANDLE)_get_osfhandle(0);
  si.hStdOutput = (HANDLE)_get_osfhandle(1);
  si.hStdError  = (HANDLE)_get_osfhandle(2);

  if(!CreateProcessA(sh.c_str(),
                     (LPSTR)shcmd.c_str(),
                     NULL,
                     NULL,
                     TRUE,
                     CREATE_SUSPENDED, // Resumed after assigned to Job
                     NULL,
                     NULL,
                     &si,
                     &pi))
  {
    char* message;
    DWORD err = GetLastError();

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL,
                  err,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (LPTSTR)&message,
                  0, NULL );

    logger.error("CreateProcess failed, error: %d, message: '%s'",
                 err, message);
    LocalFree(message);

  }

  HANDLE proc = pi.hProcess;
  require(proc);

  // Job control
  require(m_job = CreateJobObject(0, 0));
  require(AssignProcessToJobObject(m_job, proc));

  // Resum process after it has been added to Job
  ResumeThread(pi.hThread);
  CloseHandle(pi.hThread);


  // go back up to original cwd
  if(chdir(cwd))
  {
    logger.critical("Couldn't go back to saved cwd after spawn()");
    logger.critical("errno: %d, strerror: %s", errno, strerror(errno));
  }
  free(cwd);

  // get back to original std i/o
  for(i = 0; i < 3; i++) {
    dup2(std_dups[i], i);
    close(std_dups[i]);
  }

  for (i = 0; i < saved.size(); i++) {
    putenv(saved[i].c_str());
  }

  logger.debug("'%s' has been started", shcmd.c_str());

  DWORD exitcode;
  BOOL result = GetExitCodeProcess(proc, &exitcode);
  //maybe a short running process
  if (result && exitcode != 259) {
    m_status = STOPPED;
    logger.warning("Process terminated early");
  }

  int pid = GetProcessId(proc);
  if (!pid)
    logger.critical("GetProcessId failed, error: %d!", GetLastError());

  logger.debug("new pid %d", pid);

  CloseHandle(proc);
  m_status = RUNNING;
  writePid(pid);
#endif

  close(fdnull);
}
Пример #8
0
void
ndbd_run(bool foreground, int report_fd,
         const char* connect_str, int force_nodeid, const char* bind_address,
         bool no_start, bool initial, bool initialstart,
         unsigned allocated_nodeid)
{
#ifdef _WIN32
  {
    char shutdown_event_name[32];
    _snprintf(shutdown_event_name, sizeof(shutdown_event_name),
              "ndbd_shutdown_%d", GetCurrentProcessId());

    g_shutdown_event = CreateEvent(NULL, TRUE, FALSE, shutdown_event_name);
    if (g_shutdown_event == NULL)
    {
      g_eventLogger->error("Failed to create shutdown event, error: %d",
                           GetLastError());
     ndbd_exit(1);
    }

    HANDLE thread = CreateThread(NULL, 0, &shutdown_thread, NULL, 0, NULL);
    if (thread == NULL)
    {
      g_eventLogger->error("couldn't start shutdown thread, error: %d",
                           GetLastError());
      ndbd_exit(1);
    }
  }
#endif

  if (foreground)
    g_eventLogger->info("Ndb started in foreground");

  if (report_fd)
  {
    g_eventLogger->debug("Opening report stream on fd: %d", report_fd);
    // Open a stream for sending extra status to angel
    if (!(angel_info_w = fdopen(report_fd, "w")))
    {
      g_eventLogger->error("Failed to open stream for reporting "
                           "to angel, error: %d (%s)", errno, strerror(errno));
      ndbd_exit(-1);
    }
  }
  else
  {
    // No reporting requested, open /dev/null
    const char* dev_null = IF_WIN("nul", "/dev/null");
    if (!(angel_info_w = fopen(dev_null, "w")))
    {
      g_eventLogger->error("Failed to open stream for reporting to "
                           "'%s', error: %d (%s)", dev_null, errno,
                           strerror(errno));
      ndbd_exit(-1);
    }
  }

  globalEmulatorData.create();

  Configuration* theConfig = globalEmulatorData.theConfiguration;
  if(!theConfig->init(no_start, initial, initialstart))
  {
    g_eventLogger->error("Failed to init Configuration");
    ndbd_exit(-1);
  }

  theConfig->fetch_configuration(connect_str, force_nodeid, bind_address,
                                 allocated_nodeid);

  if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
  {
    g_eventLogger->warning("Cannot change directory to '%s', error: %d",
                           NdbConfig_get_path(NULL), errno);
    // Ignore error
  }

  theConfig->setupConfiguration();

  if (get_multithreaded_config(globalEmulatorData))
    ndbd_exit(-1);

  systemInfo(* theConfig, * theConfig->m_logLevel);

  NdbThread* pWatchdog = globalEmulatorData.theWatchDog->doStart();

  {
    /*
     * Memory allocation can take a long time for large memory.
     *
     * So we want the watchdog to monitor the process of initial allocation.
     */
    Uint32 watchCounter;
    watchCounter = 9;           //  Means "doing allocation"
    globalEmulatorData.theWatchDog->registerWatchedThread(&watchCounter, 0);
    if (init_global_memory_manager(globalEmulatorData, &watchCounter))
      ndbd_exit(1);
    globalEmulatorData.theWatchDog->unregisterWatchedThread(0);
  }

  globalEmulatorData.theThreadConfig->init();

#ifdef VM_TRACE
  // Create a signal logger before block constructors
  char *buf= NdbConfig_SignalLogFileName(globalData.ownId);
  NdbAutoPtr<char> tmp_aptr(buf);
  FILE * signalLog = fopen(buf, "a");
  globalSignalLoggers.setOwnNodeId(globalData.ownId);
  globalSignalLoggers.setOutputStream(signalLog);
#if 1 // to log startup
  { const char* p = NdbEnv_GetEnv("NDB_SIGNAL_LOG", (char*)0, 0);
    if (p != 0) {
      char buf[200];
      BaseString::snprintf(buf, sizeof(buf), "BLOCK=%s", p);
      for (char* q = buf; *q != 0; q++) *q = toupper(toascii(*q));
      globalSignalLoggers.log(SignalLoggerManager::LogInOut, buf);
      globalData.testOn = 1;
      assert(signalLog != 0);
      fprintf(signalLog, "START\n");
      fflush(signalLog);
    }
  }
#endif
#endif

  // Load blocks (both main and workers)
  globalEmulatorData.theSimBlockList->load(globalEmulatorData);

  // Set thread concurrency for Solaris' light weight processes
  int status;
  status = NdbThread_SetConcurrencyLevel(30);
  assert(status == 0);

  catchsigs(foreground);

  /**
   * Do startup
   */
  switch(globalData.theRestartFlag){
  case initial_state:
    globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
    break;
  case perform_start:
    globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
    globalEmulatorData.theThreadConfig->doStart(NodeState::SL_STARTING);
    break;
  default:
    assert("Illegal state globalData.theRestartFlag" == 0);
  }

  globalTransporterRegistry.startSending();
  globalTransporterRegistry.startReceiving();
  if (!globalTransporterRegistry.start_service(*globalEmulatorData.m_socket_server)){
    ndbout_c("globalTransporterRegistry.start_service() failed");
    ndbd_exit(-1);
  }

  // Re-use the mgm handle as a transporter
  if(!globalTransporterRegistry.connect_client(
		 theConfig->get_config_retriever()->get_mgmHandlePtr()))
      ERROR_SET(fatal, NDBD_EXIT_CONNECTION_SETUP_FAILED,
                "Failed to convert mgm connection to a transporter",
                __FILE__);

  NdbThread* pTrp = globalTransporterRegistry.start_clients();
  if (pTrp == 0)
  {
    ndbout_c("globalTransporterRegistry.start_clients() failed");
    ndbd_exit(-1);
  }

  NdbThread* pSockServ = globalEmulatorData.m_socket_server->startServer();

  globalEmulatorData.theConfiguration->addThread(pTrp, SocketClientThread);
  globalEmulatorData.theConfiguration->addThread(pWatchdog, WatchDogThread);
  globalEmulatorData.theConfiguration->addThread(pSockServ, SocketServerThread);

  //  theConfig->closeConfiguration();
  {
    NdbThread *pThis = NdbThread_CreateObject(0);
    Uint32 inx = globalEmulatorData.theConfiguration->addThread(pThis,
                                                                MainThread);
    globalEmulatorData.theThreadConfig->ipControlLoop(pThis, inx);
    globalEmulatorData.theConfiguration->removeThreadId(inx);
  }
  NdbShutdown(0, NST_Normal);

  ndbd_exit(0);
}
Пример #9
0
mode_t NdbDir::o_r(void) {
    return IF_WIN(0, S_IROTH);
};
Пример #10
0
mode_t NdbDir::g_x(void) {
    return IF_WIN(0, S_IXGRP);
};
Пример #11
0
mode_t NdbDir::g_w(void) {
    return IF_WIN(0, S_IWGRP);
};
Пример #12
0
mode_t NdbDir::g_r(void) {
    return IF_WIN(0, S_IRGRP);
};
Пример #13
0
mode_t NdbDir::u_x(void) {
    return IF_WIN(0, S_IXUSR);
};
Пример #14
0
mode_t NdbDir::u_w(void) {
    return IF_WIN(0, S_IWUSR);
};
Пример #15
0
mode_t NdbDir::u_r(void) {
    return IF_WIN(0, S_IRUSR);
};
Пример #16
0
int main(int argc, char **argv)
{
  char self_name[FN_REFLEN];

  MY_INIT(argv[0]);

#if __WIN__
  if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
  {
    strncpy(self_name, argv[0], FN_REFLEN);
  }

  if (init_dynamic_string(&ds_args, "", 512, 256) ||
      init_dynamic_string(&conn_args, "", 512, 256))
    die("Out of memory");

  if (load_defaults("my", load_default_groups, &argc, &argv))
    die(NULL);
  defaults_argv= argv; /* Must be freed by 'free_defaults' */

  if (handle_options(&argc, &argv, my_long_options, get_one_option))
    die(NULL);
  if (debug_info_flag)
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
  if (debug_check_flag)
    my_end_arg= MY_CHECK_ERROR;

  if (tty_password)
  {
    opt_password= get_tty_password(NullS);
    /* add password to defaults file */
    dynstr_append_os_quoted(&ds_args, "--password="******" ");
  }
  /* add user to defaults file */
  dynstr_append_os_quoted(&ds_args, "--user="******" ");

  /* Find mysql */
  find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);

  if (!opt_systables_only)
  {
    /* Find mysqlcheck */
    find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
  }
  else
  {
    if (!opt_silent)
      printf("The --upgrade-system-tables option was used, databases won't be touched.\n");
  }

  /*
    Read the mysql_upgrade_info file to check if mysql_upgrade
    already has been run for this installation of MySQL
  */
  if (!opt_force && upgrade_already_done())
  {
    printf("This installation of MySQL is already upgraded to %s, "
           "use --force if you still need to run mysql_upgrade\n",
           MYSQL_SERVER_VERSION);
    die(NULL);
  }

  if (opt_version_check && check_version_match())
    die("Upgrade failed");

  /*
    Run "mysqlcheck" and "mysql_fix_privilege_tables.sql"
  */
  if ((!opt_systables_only &&
       (run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) ||
      run_sql_fix_privilege_tables())
  {
    /*
      The upgrade failed to complete in some way or another,
      significant error message should have been printed to the screen
    */
    die("Upgrade failed" );
  }
  verbose("OK");

  /* Create a file indicating upgrade has been performed */
  create_mysql_upgrade_info_file();

  free_used_memory();
  my_end(my_end_arg);
  exit(0);
}
Пример #17
0
int main(int argc, char **argv)
{
  char self_name[FN_REFLEN];

  MY_INIT(argv[0]);

#if __WIN__
  if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
  {
    strncpy(self_name, argv[0], FN_REFLEN);
  }

  if (init_dynamic_string(&ds_args, "", 512, 256) ||
      init_dynamic_string(&conn_args, "", 512, 256))
    die("Out of memory");

  if (load_defaults("my", load_default_groups, &argc, &argv))
    die(NULL);
  defaults_argv= argv; /* Must be freed by 'free_defaults' */

  if (handle_options(&argc, &argv, my_long_options, get_one_option))
    die(NULL);
  if (debug_info_flag)
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
  if (debug_check_flag)
    my_end_arg= MY_CHECK_ERROR;

  if (tty_password)
  {
    opt_password= get_tty_password(NullS);
    /* add password to defaults file */
    dynstr_append_os_quoted(&ds_args, "--password="******" ");
  }
  /* add user to defaults file */
  dynstr_append_os_quoted(&ds_args, "--user="******" ");

  /* Find mysql */
  find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);

  /* Find mysqlcheck */
  find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);

  if (opt_systables_only && !opt_silent)
    printf("The --upgrade-system-tables option was used, user tables won't be touched.\n");


  /*
    Read the mysql_upgrade_info file to check if mysql_upgrade
    already has been run for this installation of MySQL
  */
  if (!opt_force && upgrade_already_done())
  {
    printf("This installation of MySQL is already upgraded to %s, "
           "use --force if you still need to run mysql_upgrade\n",
           MYSQL_SERVER_VERSION);
    goto end;
  }

  if (opt_version_check && check_version_match())
    die("Upgrade failed");

  upgrade_from_mysql= is_mysql();

  /*
    Run "mysqlcheck" and "mysql_fix_privilege_tables.sql"
  */
  if (run_mysqlcheck_upgrade(TRUE) ||
      run_mysqlcheck_views() ||
      run_sql_fix_privilege_tables() ||
      run_mysqlcheck_fixnames() ||
      run_mysqlcheck_upgrade(FALSE))
    die("Upgrade failed" );

  verbose("Phase %d/%d: Running 'FLUSH PRIVILEGES'", ++phase, phases_total);
  if (run_query("FLUSH PRIVILEGES", NULL, TRUE))
    die("Upgrade failed" );

  verbose("OK");

  /* Create a file indicating upgrade has been performed */
  create_mysql_upgrade_info_file();

  DBUG_ASSERT(phase == phases_total);

end:
  free_used_memory();
  my_end(my_end_arg);
  exit(0);
}
Пример #18
0
mode_t NdbDir::o_w(void) {
    return IF_WIN(0, S_IWOTH);
};
Пример #19
0
/**
  Look for the filename of given tool, with the presumption that it is in the
  same directory as mysql_upgrade and that the same executable-searching 
  mechanism will be used when we run our sub-shells with popen() later.
*/
static void find_tool(char *tool_executable_name, const char *tool_name, 
                      const char *self_name)
{
  char *last_fn_libchar;
  DYNAMIC_STRING ds_tmp;
  DBUG_ENTER("find_tool");
  DBUG_PRINT("enter", ("progname: %s", my_progname));

  if (init_dynamic_string(&ds_tmp, "", 32, 32))
    die("Out of memory");

  last_fn_libchar= strrchr(self_name, FN_LIBCHAR);

  if (last_fn_libchar == NULL)
  {
    /*
      mysql_upgrade was found by the shell searching the path.  A sibling
      next to us should be found the same way.
    */
    strncpy(tool_executable_name, tool_name, FN_REFLEN);
  }
  else
  {
    int len;

    /*
      mysql_upgrade was run absolutely or relatively.  We can find a sibling
      by replacing our name after the LIBCHAR with the new tool name.
    */

    /*
      When running in a not yet installed build and using libtool,
      the program(mysql_upgrade) will be in .libs/ and executed
      through a libtool wrapper in order to use the dynamic libraries
      from this build. The same must be done for the tools(mysql and
      mysqlcheck). Thus if path ends in .libs/, step up one directory
      and execute the tools from there
    */
    if (((last_fn_libchar - 6) >= self_name) &&
        (strncmp(last_fn_libchar - 5, ".libs", 5) == 0) &&
        (*(last_fn_libchar - 6) == FN_LIBCHAR))
    {
      DBUG_PRINT("info", ("Chopping off \".libs\" from end of path"));
      last_fn_libchar -= 6;
    }

    len= last_fn_libchar - self_name;

    my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s",
                len, self_name, FN_LIBCHAR, tool_name);
  }

  if (opt_verbose)
    verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);

  /*
    Make sure it can be executed
  */
  if (run_tool(tool_executable_name,
               &ds_tmp, /* Get output from command, discard*/
               "--no-defaults",
               "--help",
               "2>&1",
               IF_WIN("> NUL", "> /dev/null"),
               NULL))
    die("Can't execute '%s'", tool_executable_name);

  dynstr_free(&ds_tmp);

  DBUG_VOID_RETURN;
}
Пример #20
0
mode_t NdbDir::o_x(void) {
    return IF_WIN(0, S_IXOTH);
};
Пример #21
0
bool
NdbDir::remove_recursive(const char* dir, bool only_contents)
{
    char path[PATH_MAX];
    if (basestring_snprintf(path, sizeof(path),
                            "%s%s", dir, DIR_SEPARATOR) < 0) {
        fprintf(stderr, "Too long path to remove: '%s'\n", dir);
        return false;
    }
    int start_len = strlen(path);

    const char* name;
    NdbDir::Iterator iter;
loop:
    {
        if (iter.open(path) != 0)
        {
            fprintf(stderr, "Failed to open iterator for '%s'\n",
                    path);
            return false;
        }

        while ((name = iter.next_entry()) != NULL)
        {
            if ((strcmp(".", name) == 0) || (strcmp("..", name) == 0))
                continue;

            int end_len, len = strlen(path);
            if ((end_len = basestring_snprintf(path + len, sizeof(path) - len,
                                               "%s", name)) < 0)
            {
                fprintf(stderr, "Too long path detected: '%s'+'%s'\n",
                        path, name);
                return false;
            }

            if (unlink(path) == 0 || NdbDir::remove(path) == true)
            {
                path[len] = 0;
                continue;
            }

            iter.close();

            // Append ending slash to the string
            int pos = len + end_len;
            if (basestring_snprintf(path + pos, sizeof(path) - pos,
                                    "%s", DIR_SEPARATOR) < 0)
            {
                fprintf(stderr, "Too long path detected: '%s'+'%s'\n",
                        path, DIR_SEPARATOR);
                return false;
            }

            goto loop;
        }
        iter.close();

        int len = strlen(path);
        path[len - 1] = 0; // remove ending slash

        char * prev_slash = strrchr(path, IF_WIN('\\', '/'));
        if (len > start_len && prev_slash)
        {
            // Not done yet, step up one dir level
            assert(prev_slash > path && prev_slash < path + sizeof(path));
            prev_slash[1] = 0;
            goto loop;
        }
    }

    if (only_contents == false && NdbDir::remove(dir) == false)
    {
        fprintf(stderr,
                "Failed to remove directory '%s', error: %d\n",
                dir, errno);
        return false;
    }

    return true;
}
Пример #22
0
static int mgmd_main(int argc, char** argv)
{
    NDB_INIT(argv[0]);

    printf("MySQL Cluster Management Server %s\n", NDB_VERSION_STRING);

    ndb_opt_set_usage_funcs(short_usage_sub, usage);

    load_defaults("my",load_default_groups,&argc,&argv);
    defaults_argv= argv; /* Must be freed by 'free_defaults' */

    int ho_error;
#ifndef DBUG_OFF
    opt_debug= IF_WIN("d:t:i:F:o,c:\\ndb_mgmd.trace",
                      "d:t:i:F:o,/tmp/ndb_mgmd.trace");
#endif

    if ((ho_error=handle_options(&argc, &argv, my_long_options,
                                 ndb_std_get_one_option)))
        mgmd_exit(ho_error);

    if (opts.interactive ||
            opts.non_interactive ||
            opts.print_full_config) {
        opts.daemon= 0;
    }

    if (opts.mycnf && opts.config_filename)
    {
        fprintf(stderr, "ERROR: Both --mycnf and -f is not supported\n");
        mgmd_exit(1);
    }

    if (opt_nowait_nodes)
    {
        int res = parse_mask(opt_nowait_nodes, opts.nowait_nodes);
        if(res == -2 || (res > 0 && opts.nowait_nodes.get(0)))
        {
            fprintf(stderr, "ERROR: Invalid nodeid specified in nowait-nodes: '%s'\n",
                    opt_nowait_nodes);
            mgmd_exit(1);
        }
        else if (res < 0)
        {
            fprintf(stderr, "ERROR: Unable to parse nowait-nodes argument: '%s'\n",
                    opt_nowait_nodes);
            mgmd_exit(1);
        }
    }

    /* Setup use of event logger */
    g_eventLogger->setCategory(opt_logname);

    /* Output to console initially */
    g_eventLogger->createConsoleHandler();

#ifdef _WIN32
    /* Output to Windows event log */
    g_eventLogger->createEventLogHandler("MySQL Cluster Management Server");
#endif

    if (opts.verbose)
        g_eventLogger->enable(Logger::LL_ALL); // --verbose turns on everything

    /**
       Install signal handler for SIGPIPE
       Done in TransporterFacade as well.. what about Configretriever?
     */
#if !defined NDB_WIN32
    signal(SIGPIPE, SIG_IGN);
#endif

    while (!g_StopServer)
    {
        mgm= new MgmtSrvr(opts);
        if (mgm == NULL) {
            g_eventLogger->critical("Out of memory, couldn't create MgmtSrvr");
            mgmd_exit(1);
        }

        /* Init mgm, load or fetch config */
        if (!mgm->init()) {
            delete mgm;
            mgmd_exit(1);
        }

        if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
        {
            g_eventLogger->warning("Cannot change directory to '%s', error: %d",
                                   NdbConfig_get_path(NULL), errno);
            // Ignore error
        }

        if (opts.daemon)
        {
            NodeId localNodeId= mgm->getOwnNodeId();
            if (localNodeId == 0) {
                g_eventLogger->error("Couldn't get own node id");
                delete mgm;
                mgmd_exit(1);
            }

            char *lockfile= NdbConfig_PidFileName(localNodeId);
            char *logfile=  NdbConfig_StdoutFileName(localNodeId);
            if (ndb_daemonize(lockfile, logfile))
            {
                g_eventLogger->error("Couldn't start as daemon, error: '%s'",
                                     ndb_daemon_error);
                mgmd_exit(1);
            }
        }

        /* Start mgm services */
        if (!mgm->start()) {
            delete mgm;
            mgmd_exit(1);
        }

        if (opts.interactive) {
            int port= mgm->getPort();
            BaseString con_str;
            if(opts.bind_address)
                con_str.appfmt("host=%s:%d", opts.bind_address, port);
            else
                con_str.appfmt("localhost:%d", port);
            Ndb_mgmclient com(con_str.c_str(), 1);
            while(!g_StopServer) {
                if (!read_and_execute(&com, "ndb_mgm> ", 1))
                    g_StopServer = true;
            }
        }
        else
        {
            g_eventLogger->info("MySQL Cluster Management Server %s started",
                                NDB_VERSION_STRING);

            while (!g_StopServer)
                NdbSleep_MilliSleep(500);
        }

        g_eventLogger->info("Shutting down server...");
        delete mgm;
        g_eventLogger->info("Shutdown complete");

        if(g_RestartServer) {
            g_eventLogger->info("Restarting server...");
            g_RestartServer= g_StopServer= false;
        }
    }

    mgmd_exit(0);
    return 0;
}