void Buffer::Allocate(unsigned size_, bool keepold) { char* newbuffer; if (size_ <= size) return; size_ = NextPowerOfTwo(size_); if (buffer == array || preallocated) newbuffer = (char*) malloc(size_); else newbuffer = (char*) realloc(buffer, size_); if (newbuffer == NULL) { throw std::bad_alloc(); // in case of exceptions are disabled STOP_FAIL(1, "Out of memory error"); } if (keepold && length > 0) { if (buffer == array || preallocated) memcpy(newbuffer, buffer, length); } buffer = newbuffer; size = size_; preallocated = false; }
bool ReplicatedConfig::Init() { Endpoint endpoint; nodeID = Config::GetIntValue("paxos.nodeID", 0); numNodes = Config::GetListNum("paxos.endpoints"); if (numNodes == 0) { endpoint.Set("0.0.0.0:10000"); endpoints[0] = endpoint; nodeID = 0; } else { if (nodeID < 0 || nodeID >= numNodes) STOP_FAIL("Configuration error, " "check your paxos.nodeID and paxos.endpoints entry" ,0); for (unsigned i = 0; i < numNodes; i++) { endpoint.Set(Config::GetListValue("paxos.endpoints", i, NULL), true); endpoints[i] = endpoint; } } if (strcmp("replicated", Config::GetValue("mode", "")) == 0) InitRestartCounter(); return true; }
int main(int argc, char** argv) { Application* app; bool isController; if (argc < 2) STOP_FAIL(1, "Config file argument not given, exiting"); if (!configFile.Init(argv[1])) STOP_FAIL(1, "Invalid config file (%s)", argv[1]); InitLog(); ParseArgs(argc, argv); StartClock(); ConfigureSystemSettings(); IOProcessor::Init(configFile.GetIntValue("io.maxfd", 32768)); InitContextTransport(); BloomFilter::StaticInit(); isController = IsController(); LogPrintVersion(isController); if (isController) app = new ConfigServerApp; else app = new ShardServerApp; app->Init(); IOProcessor::BlockSignals(IOPROCESSOR_BLOCK_ALL); EventLoop::Init(); EventLoop::Run(); Log_Message("Shutting down..."); EventLoop::Shutdown(); app->Shutdown(); delete app; IOProcessor::Shutdown(); StopClock(); configFile.Shutdown(); Log_Shutdown(); return 0; }
static void CDatabaseError(const DbEnv* /*dbenv*/, const char* /*errpfx*/, const char* msg) { if (strcmp(msg, LOG_BUFFER_ALLOC_ERROR) == 0) STOP_FAIL("Not enough memory to allocate log buffer!\nChange database.logBufferSize in the config file!", 1); LG_TRACE("%s", msg); }
void ClusterTransport::Init(Endpoint& endpoint_) { endpoint = endpoint_; if (!server.Init(endpoint.GetPort())) STOP_FAIL(1, "Cannot bind on cluster port: %s", endpoint.ToString()); server.SetTransport(this); awaitingNodeID = true; nodeID = UNDEFINED_NODEID; clusterID = 0; }
BOOL WINAPI ConsoleCtrlHandler(DWORD /*ctrlType*/) { if (terminated) { STOP_FAIL("aborting due to user request", 0); return FALSE; } terminated = true; IOProcessor::Complete(NULL); return TRUE; }
bool IsController() { const char* role; role = configFile.GetValue("role", ""); if (role == NULL) STOP_FAIL(1, "Missing \"role\" in config file!"); if (strcmp(role, "controller") == 0) return true; else return false; }
Endpoint& ClusterTransport::GetEndpoint(uint64_t nodeID) { ClusterConnection* it; FOREACH (it, conns) { if (it->GetNodeID() == nodeID) return it->endpoint; } ASSERT_FAIL(); // never gets here, this is only here for suppressing VC++ warning STOP_FAIL(1, "Program error in ClusterTransport::GetEndpoint"); }
void ParseArgs(int argc, char** argv) { for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 't': Log_SetTrace(true); break; case 'h': STOP_FAIL(0, "Usage: %s [-t] config-file\n\n", argv[0]); break; } } } }
void MessageConnection::OnRead() { bool yield, closed; unsigned pos, msglength, nread, msgbegin, msgend, required; uint64_t start; Stopwatch sw; ReadBuffer msg; if (!readActive) { if (resumeRead.IsActive()) STOP_FAIL(1, "Program bug: resumeRead.IsActive() should be false."); EventLoop::Add(&resumeRead); return; } sw.Start(); Log_Trace("Read buffer: %B", tcpread.buffer); tcpread.requested = IO_READ_ANY; pos = 0; start = NowClock(); yield = false; while(true) { msglength = BufferToUInt64(tcpread.buffer->GetBuffer() + pos, tcpread.buffer->GetLength() - pos, &nread); if (msglength > tcpread.buffer->GetSize() - NumDigits(msglength) - 1) { Log_Trace(); required = msglength + NumDigits(msglength) + 1; if (required > MESSAGING_MAX_SIZE) { Log_Trace(); OnClose(); return; } tcpread.buffer->Allocate(required); break; } if (nread == 0 || (unsigned) tcpread.buffer->GetLength() - pos <= nread) break; if (tcpread.buffer->GetCharAt(pos + nread) != ':') { Log_Trace("Message protocol error"); OnClose(); return; } msgbegin = pos + nread + 1; msgend = pos + nread + 1 + msglength; if ((unsigned) tcpread.buffer->GetLength() < msgend) { // read more //tcpread.requested = msgend - pos; break; } msg.SetBuffer(tcpread.buffer->GetBuffer() + msgbegin); msg.SetLength(msglength); closed = OnMessage(msg); if (closed) return; pos = msgend; // if the user called Close() in OnMessageRead() if (state != CONNECTED) return; if (tcpread.buffer->GetLength() == msgend) break; if (NowClock() - start >= YIELD_TIME || !readActive) { // let other code run every YIELD_TIME msec yield = true; if (resumeRead.IsActive()) STOP_FAIL(1, "Program bug: resumeRead.IsActive() should be false."); EventLoop::Add(&resumeRead); break; } } if (pos > 0) { memmove(tcpread.buffer->GetBuffer(), tcpread.buffer->GetBuffer() + pos, tcpread.buffer->GetLength() - pos); tcpread.buffer->Shorten(pos); } if (state == CONNECTED && !tcpread.active && !yield) IOProcessor::Add(&tcpread); sw.Stop(); Log_Trace("time spent in OnRead(): %U", sw.Elapsed()); }
int main(int argc, char* argv[]) { enum { single, replicated, missing } mode; int logTargets; const char* user; char buf[4096]; bool deleteDB; bool firstRun; firstRun = true; mode = missing; if (argc == 1) { fprintf(stderr, "You did not specify a config file!\n"); fprintf(stderr, "Starting in single mode with defaults...\n"); fprintf(stderr, "Using database.dir = '%s'\n", DATABASE_CONFIG_DIR); mode = single; } else if (argc == 2) { if (!Config::Init(argv[1])) STOP_FAIL("Cannot open config file", 1); } else { fprintf(stderr, "usage: %s <config-file>\n", argv[0]); STOP_FAIL("invalid arguments", 1); } if (strcmp("single", Config::GetValue("mode", "")) == 0) mode = single; else if (strcmp("replicated", Config::GetValue("mode", "")) == 0) mode = replicated; else if (mode == missing) { fprintf(stderr, "specify mode = single or mode = replicated\n"); STOP_FAIL("invalid configuration file", 1); } logTargets = 0; if (Config::GetListNum("log.targets") == 0) logTargets = LOG_TARGET_STDOUT; for (int i = 0; i < Config::GetListNum("log.targets"); i++) { if (strcmp(Config::GetListValue("log.targets", i, ""), "file") == 0) { logTargets |= LOG_TARGET_FILE; Log_SetOutputFile(Config::GetValue("log.file", NULL), Config::GetBoolValue("log.truncate", false)); } if (strcmp(Config::GetListValue("log.targets", i, NULL), "stdout") == 0) logTargets |= LOG_TARGET_STDOUT; if (strcmp(Config::GetListValue("log.targets", i, NULL), "stderr") == 0) logTargets |= LOG_TARGET_STDERR; } Log_SetTarget(logTargets); Log_SetTrace(Config::GetBoolValue("log.trace", false)); Log_SetTimestamping(Config::GetBoolValue("log.timestamping", false)); Log_Message(VERSION_FMT_STRING " started"); run: { if (!IOProcessor::Init(Config::GetIntValue("io.maxfd", 1024))) STOP_FAIL("Cannot initalize IOProcessor!", 1); // after io is initialized, drop root rights user = Config::GetValue("daemon.user", NULL); if (!ChangeUser(user)) STOP_FAIL(rprintf("Cannot setuid to %s", user), 1); DatabaseConfig dbConfig; dbConfig.dir = Config::GetValue("database.dir", DATABASE_CONFIG_DIR); dbConfig.pageSize = Config::GetIntValue("database.pageSize", DATABASE_CONFIG_PAGE_SIZE); dbConfig.cacheSize = Config::GetIntValue("database.cacheSize", DATABASE_CONFIG_CACHE_SIZE); dbConfig.logBufferSize = Config::GetIntValue("database.logBufferSize", DATABASE_CONFIG_LOG_BUFFER_SIZE); dbConfig.checkpointTimeout = Config::GetIntValue("database.checkpointTimeout", DATABASE_CONFIG_CHECKPOINT_TIMEOUT); dbConfig.verbose = Config::GetBoolValue("database.verbose", DATABASE_CONFIG_VERBOSE); dbConfig.directDB = Config::GetBoolValue("database.directDB", DATABASE_CONFIG_DIRECT_DB); dbConfig.txnNoSync = Config::GetBoolValue("database.txnNoSync", DATABASE_CONFIG_TXN_NOSYNC); dbConfig.txnWriteNoSync = Config::GetBoolValue("database.txnWriteNoSync", DATABASE_CONFIG_TXN_WRITE_NOSYNC); if (Config::GetBoolValue("database.warmCache", true) && firstRun) WarmCache((char*)dbConfig.dir, dbConfig.cacheSize); if (firstRun) Log_Message("Opening database..."); if (!database.Init(dbConfig)) STOP_FAIL("Cannot initialize database!", 1); if (firstRun) Log_Message("Database opened"); dbWriter.Init(1); dbReader.Init(Config::GetIntValue("database.numReaders", 20)); if (!RCONF->Init()) STOP_FAIL("Cannot initialize paxos!", 1); KeyspaceDB* kdb; if (mode == replicated) { RLOG->Init(Config::GetBoolValue("paxos.useSoftClock", true)); kdb = new ReplicatedKeyspaceDB; } else { kdb = new SingleKeyspaceDB; } kdb->Init(); HttpServer protoHttp; HttpKeyspaceHandler httpKeyspaceHandler(kdb); int httpPort = Config::GetIntValue("http.port", 8080); if (httpPort) { protoHttp.Init(httpPort); protoHttp.RegisterHandler(&httpKeyspaceHandler); } KeyspaceServer protoKeyspace; protoKeyspace.Init(kdb, Config::GetIntValue("keyspace.port", 7080)); EventLoop::Init(); EventLoop::Run(); EventLoop::Shutdown(); if (mode == replicated) deleteDB = ((ReplicatedKeyspaceDB*)kdb)->DeleteDB(); else deleteDB = false; protoKeyspace.Shutdown(); protoHttp.Shutdown(); kdb->Shutdown(); delete kdb; dbReader.Shutdown(); dbWriter.Shutdown(); RLOG->Shutdown(); database.Shutdown(); IOProcessor::Shutdown(); if (mode == replicated && deleteDB) { // snprintf(buf, SIZE(buf), "%s/__*", dbConfig.dir); // DeleteWC(buf); snprintf(buf, SIZE(buf), "%s/log*", dbConfig.dir); DeleteWC(buf); snprintf(buf, SIZE(buf), "%s/keyspace", dbConfig.dir); DeleteWC(buf); #ifdef _WIN32 MSleep(3000); // otherwise Windows won't let use reuse the same ports #endif firstRun = false; goto run; } } Log_Message("Keyspace shutting down."); Config::Shutdown(); Log_Shutdown(); }