📄 main.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <ndb_global.h>#include <my_pthread.h>#include <ndb_version.h>#include "Configuration.hpp"#include <ConfigRetriever.hpp>#include <TransporterRegistry.hpp>#include "vm/SimBlockList.hpp"#include "ThreadConfig.hpp"#include <SignalLoggerManager.hpp>#include <NdbOut.hpp>#include <NdbMain.h>#include <NdbDaemon.h>#include <NdbSleep.h>#include <NdbConfig.h>#include <WatchDog.hpp>#include <LogLevel.hpp>#include <EventLogger.hpp>#include <NdbAutoPtr.hpp>#include <Properties.hpp>#include <mgmapi_debug.h>#if defined NDB_SOLARIS // ok#include <sys/processor.h> // For system informatio#endifextern EventLogger g_eventLogger;extern NdbMutex * theShutdownMutex;void catchsigs(bool ignore); // for process signal handling#define MAX_FAILED_STARTUPS 3// Flag set by child through SIGUSR1 to signal a failed startupstatic bool failed_startup_flag = false;// Counter for consecutive failed startupsstatic Uint32 failed_startups = 0;extern "C" void handler_shutdown(int signum); // for process signal handlingextern "C" void handler_error(int signum); // for process signal handlingextern "C" void handler_sigusr1(int signum); // child signalling failed restart// Shows system informationvoid systemInfo(const Configuration & conf, const LogLevel & ll); // These are used already before fork if fetch_configuration() fails// (e.g. Unable to alloc node id). Set them to something reasonable.static FILE *child_info_file_r= stdin;static FILE *child_info_file_w= stdout;static void writeChildInfo(const char *token, int val){ fprintf(child_info_file_w, "%s=%d\n", token, val); fflush(child_info_file_w);}void childReportSignal(int signum){ writeChildInfo("signal", signum);}void childReportError(int error){ writeChildInfo("error", error);}void childExit(int code, Uint32 currentStartPhase){ writeChildInfo("sphase", currentStartPhase); writeChildInfo("exit", code); fprintf(child_info_file_w, "\n"); fclose(child_info_file_r); fclose(child_info_file_w); exit(code);}void childAbort(int code, Uint32 currentStartPhase){ writeChildInfo("sphase", currentStartPhase); writeChildInfo("exit", code); fprintf(child_info_file_w, "\n"); fclose(child_info_file_r); fclose(child_info_file_w); signal(6, SIG_DFL); abort();}static int insert(const char * pair, Properties & p){ BaseString tmp(pair); tmp.trim(" \t\n\r"); Vector<BaseString> split; tmp.split(split, ":=", 2); if(split.size() != 2) return -1; p.put(split[0].trim().c_str(), split[1].trim().c_str()); return 0;}static int readChildInfo(Properties &info){ fclose(child_info_file_w); char buf[128]; while (fgets(buf,sizeof(buf),child_info_file_r)) insert(buf,info); fclose(child_info_file_r); return 0;}static bool get_int_property(Properties &info, const char *token, Uint32 *int_val){ const char *str_val= 0; if (!info.get(token, &str_val)) return false; char *endptr; long int tmp= strtol(str_val, &endptr, 10); if (str_val == endptr) return false; *int_val = tmp; return true;}int reportShutdown(class Configuration *config, int error_exit, int restart){ Uint32 error= 0, signum= 0, sphase= 256; Properties info; readChildInfo(info); get_int_property(info, "signal", &signum); get_int_property(info, "error", &error); get_int_property(info, "sphase", &sphase); Uint32 length, theData[25]; EventReport *rep = (EventReport *)theData; rep->setNodeId(globalData.ownId); if (restart) theData[1] = 1 | (globalData.theRestartFlag == initial_state ? 2 : 0) | (config->getInitialStart() ? 4 : 0); else theData[1] = 0; if (error_exit == 0) { rep->setEventType(NDB_LE_NDBStopCompleted); theData[2] = signum; length = 3; } else { rep->setEventType(NDB_LE_NDBStopForced); theData[2] = signum; theData[3] = error; theData[4] = sphase; theData[5] = 0; // extra length = 6; } { // Log event const EventReport * const eventReport = (EventReport *)&theData[0]; g_eventLogger.log(eventReport->getEventType(), theData, eventReport->getNodeId(), 0); } for (unsigned n = 0; n < config->m_mgmds.size(); n++) { NdbMgmHandle h = ndb_mgm_create_handle(); if (h == 0 || ndb_mgm_set_connectstring(h, config->m_mgmds[n].c_str()) || ndb_mgm_connect(h, 1, //no_retries 0, //retry_delay_in_seconds 0 //verbose )) goto handle_error; { if (ndb_mgm_report_event(h, theData, length)) goto handle_error; } goto do_next;handle_error: if (h) { BaseString tmp(ndb_mgm_get_latest_error_msg(h)); tmp.append(" : "); tmp.append(ndb_mgm_get_latest_error_desc(h)); g_eventLogger.warning("Unable to report shutdown reason to %s: %s", config->m_mgmds[n].c_str(), tmp.c_str()); } else { g_eventLogger.error("Unable to report shutdown reason to %s", config->m_mgmds[n].c_str()); }do_next: if (h) { ndb_mgm_disconnect(h); ndb_mgm_destroy_handle(&h); } } return 0;}int main(int argc, char** argv){ NDB_INIT(argv[0]); // Print to stdout/console g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("ndbd"); g_eventLogger.enable(Logger::LL_ON, Logger::LL_INFO); g_eventLogger.enable(Logger::LL_ON, Logger::LL_CRITICAL); g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); g_eventLogger.enable(Logger::LL_ON, Logger::LL_WARNING); g_eventLogger.m_logLevel.setLogLevel(LogLevel::llStartUp, 15); globalEmulatorData.create(); // Parse command line options Configuration* theConfig = globalEmulatorData.theConfiguration; if(!theConfig->init(argc, argv)){ return NRT_Default; } { // Do configuration#ifndef NDB_WIN32 signal(SIGPIPE, SIG_IGN);#endif theConfig->fetch_configuration(); } my_setwd(NdbConfig_get_path(0), MYF(0)); if (theConfig->getDaemonMode()) { // Become a daemon char *lockfile= NdbConfig_PidFileName(globalData.ownId); char *logfile= NdbConfig_StdoutFileName(globalData.ownId); NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile); if (NdbDaemon_Make(lockfile, logfile, 0) == -1) { ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl; return 1; } }#ifndef NDB_WIN32 signal(SIGUSR1, handler_sigusr1); pid_t child = -1; while (! theConfig->getForegroundMode()) // the cond is const { // setup reporting between child and parent int filedes[2]; if (pipe(filedes)) { g_eventLogger.error("pipe() failed with errno=%d (%s)", errno, strerror(errno)); return 1; } else { if (!(child_info_file_w= fdopen(filedes[1],"w"))) { g_eventLogger.error("fdopen() failed with errno=%d (%s)", errno, strerror(errno)); } if (!(child_info_file_r= fdopen(filedes[0],"r"))) { g_eventLogger.error("fdopen() failed with errno=%d (%s)", errno, strerror(errno)); } } if ((child = fork()) <= 0) break; // child or error /** * Parent */ catchsigs(true); /** * We no longer need the mgm connection in this process * (as we are the angel, not ndb) * * We don't want to purge any allocated resources (nodeid), so * we set that option to false */ theConfig->closeConfiguration(false); int status = 0, error_exit = 0, signum = 0; while(waitpid(child, &status, 0) != child); if(WIFEXITED(status)){ switch(WEXITSTATUS(status)){ case NRT_Default: g_eventLogger.info("Angel shutting down"); reportShutdown(theConfig, 0, 0); exit(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -