virtual void main() { running = true; loop { INode *senderNode; CMessageBuffer msg; if (!queryWorldCommunicator().recv(msg, NULL, MPTAG_THORREGISTRATION, &senderNode)) return; rank_t sender = queryClusterGroup().rank(senderNode); SocketEndpoint ep = senderNode->endpoint(); ep.port -= THOR_MP_INC; StringBuffer url; ep.getUrlStr(url); if (RANK_NULL == sender) { PROGLOG("Node %s trying to deregister is not part of this cluster", url.str()); continue; } RegistryCode code; msg.read((int &)code); if (!rc_deregister == code) throwUnexpected(); registry.deregisterNode(sender); } running = false; }
virtual void main() { running = true; loop { INode *senderNode; CMessageBuffer msg; if (!queryWorldCommunicator().recv(msg, NULL, MPTAG_THORREGISTRATION, &senderNode)) return; rank_t sender = queryNodeGroup().rank(senderNode); SocketEndpoint ep = senderNode->endpoint(); StringBuffer url; ep.getUrlStr(url); if (RANK_NULL == sender) { PROGLOG("Node %s trying to deregister is not part of this cluster", url.str()); continue; } RegistryCode code; msg.read((int &)code); if (rc_deregister != code) throwUnexpected(); Owned<IException> e = deserializeException(msg); if (e.get()) EXCLOG(e, "Slave unregistered with exception"); registry.deregisterNode(sender-1); } running = false; }
bool CDfuPlusHelper::runLocalDaFileSvr(SocketEndpoint &listenep,bool requireauthenticate, unsigned timeout) { Owned<CDafsThread> thr = new CDafsThread(listenep,requireauthenticate); if (!thr->ok()) return false; thr->start(); StringBuffer eps; if (listenep.isNull()) progress("Started local Dali file server on port %d\n", listenep.port?listenep.port:DAFILESRV_PORT); else progress("Started local Dali file server on %s\n", listenep.getUrlStr(eps).str()); if (timeout==0) { setDafsTrace(NULL,0); // disable client tracing dafsthread.setown(thr.getClear()); } else { loop { Sleep(500); if (thr->idleTime()>timeout) { thr->stop(); break; } } } return true; }
bool UnregisterSelf(IException *e) { if (!hasMPServerStarted()) return false; StringBuffer slfStr; slfEp.getUrlStr(slfStr); LOG(MCdebugProgress, thorJob, "Unregistering slave : %s", slfStr.str()); try { CMessageBuffer msg; msg.append((int)rc_deregister); serializeException(e, msg); // NB: allows exception to be NULL if (!queryWorldCommunicator().send(msg, masterNode, MPTAG_THORREGISTRATION, 60*1000)) { LOG(MCerror, thorJob, "Failed to unregister slave : %s", slfStr.str()); return false; } LOG(MCdebugProgress, thorJob, "Unregistered slave : %s", slfStr.str()); return true; } catch (IException *e) { if (!jobListenerStopped) FLLOG(MCexception(e), thorJob, e,"slave unregistration error"); e->Release(); } return false; }
ISmartSocket *CSmartSocketFactory::connect_timeout( unsigned timeoutms) { SmartSocketEndpoint *ss = nextSmartEndpoint(); if (!ss) throw createSmartSocketException(0, "smartsocket failed to get nextEndpoint"); ISocket *sock = NULL; SocketEndpoint ep; try { { synchronized block(lock); ss->checkHost(dnsInterval); ep = ss->ep; } if (timeoutms) sock = ISocket::connect_timeout(ep, timeoutms); else sock = ISocket::connect(ep); return new CSmartSocket(sock, ep, this); } catch (IException *e) { StringBuffer s("CSmartSocketFactory::connect "); ep.getUrlStr(s); EXCLOG(e,s.str()); ss->status=false; if (sock) sock->Release(); throw; } }
virtual ~CMergeReadStream() { if (stream) { char url[100]; endpoint.getUrlStr(url,sizeof(url)); PrintLog("SORT Merge READ: EOS via destructor for %s",url); stream->stop(); } eos(); }
static void replyError(unsigned errorCode, const char *errorMsg) { SocketEndpoint myEp = queryMyNode()->endpoint(); StringBuffer str("Node '"); myEp.getUrlStr(str); str.append("' exception: ").append(errorMsg); Owned<IException> e = MakeStringException(errorCode, "%s", str.str()); CMessageBuffer msg; serializeException(e, msg); queryWorldCommunicator().send(msg, 0, MPTAG_THORREGISTRATION); }
void update(HeartBeatPacketHeader &packet) { alive = true; if (markdead) { markdead = false; StringBuffer epstr; ep.getUrlStr(epstr); LOG(MCdebugProgress, unknownJob, "Watchdog : Marking Machine as Up! [%s]", epstr.str()); } }
virtual void stop() { if (stream) { #ifdef _FULL_TRACE char url[100]; endpoint.getUrlStr(url,sizeof(url)); PrintLog("SORT Merge READ: stop for %s",url); #endif stream->stop(); eos(); } }
bool updateDaliEnv(IPropertyTree *env, bool forceGroupUpdate, const char *daliIp) { Owned<IPropertyTreeIterator> dalis = env->getElements("Software/DaliServerProcess/Instance"); if (!dalis||!dalis->first()) { fprintf(stderr,"Could not find DaliServerProcess\n"); return false; } SocketEndpoint daliep; loop { const char *ps = dalis->get().queryProp("@port"); unsigned port = ps?atoi(ps):0; if (!port) port = DALI_SERVER_PORT; daliep.set(dalis->get().queryProp("@netAddress"),port); if (daliIp && *daliIp) { SocketEndpoint testep; testep.set(daliIp,DALI_SERVER_PORT); if (testep.equals(daliep)) break; daliep.set(NULL,0); } if (!dalis->next()) break; if (!daliep.isNull()) { fprintf(stderr,"Ambiguous DaliServerProcess instance\n"); return false; } } if (daliep.isNull()) { fprintf(stderr,"Could not find DaliServerProcess instance\n"); return false; } SocketEndpointArray epa; epa.append(daliep); Owned<IGroup> group = createIGroup(epa); bool ret = true; initClientProcess(group, DCR_Util); StringBuffer response; if (querySDS().updateEnvironment(env, forceGroupUpdate, response)) { StringBuffer tmp; PROGLOG("Environment and node groups updated in dali at %s",daliep.getUrlStr(tmp).str()); } else ret = false; if (response.length()) WARNLOG("%s", response.str()); closedownClientProcess(); return ret; }
CDafsThread(SocketEndpoint &_listenep,bool requireauthenticate) : listenep(_listenep) { if (listenep.port==0) listenep.port = DAFILESRV_PORT; StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate); server.setown(createRemoteFileServer()); }
CMergeReadStream(IRowInterfaces *rowif, unsigned streamno,SocketEndpoint &targetep, rowcount_t startrec, rowcount_t numrecs) { endpoint = targetep; #ifdef _TRACE char url[100]; targetep.getUrlStr(url,sizeof(url)); PrintLog("SORT Merge READ: Stream(%u) %s, pos=%" RCPF "d len=%" RCPF "u",streamno,url,startrec,numrecs); #endif SocketEndpoint mergeep = targetep; mergeep.port+=SOCKETSERVERINC; stream = ConnectMergeRead(streamno,rowif,mergeep,startrec,numrecs); #ifdef _TRACE PrintLog("SORT Merge READ: Stream(%u) connected to %s",streamno,url); #endif }
const void *nextRow() { if (stream) { OwnedConstThorRow row = stream->nextRow(); if (row) return row.getClear(); #ifdef _FULL_TRACE char url[100]; endpoint.getUrlStr(url,sizeof(url)); PrintLog("SORT Merge READ: EOS for %s",url); #endif eos(); } return NULL; }
void run() { // Get params from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DaFileSrv\Parameters int requireauthenticate=0; HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\DaFileSrv\\Parameters", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { DWORD dwType = 0; DWORD dwSize = sizeof(requireauthenticate); RegQueryValueEx(hkey, "RequireAuthentication", NULL, &dwType, (BYTE*)&requireauthenticate, &dwSize); RegCloseKey(hkey); } StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate!=0); PROGLOG("Opening " DAFS_SERVICE_DISPLAY_NAME " on %s%s", useSSL?"SECURE ":"",eps.str()); const char * verstring = remoteServerVersionString(); PROGLOG("Version: %s", verstring); PROGLOG("Authentication:%s required",requireauthenticate?"":" not"); PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Running"); server.setown(createRemoteFileServer(maxThreads, maxThreadsDelayMs, maxAsyncCopy)); server->setThrottle(ThrottleStd, parallelRequestLimit, throttleDelayMs, throttleCPULimit); server->setThrottle(ThrottleSlow, parallelSlowRequestLimit, throttleSlowDelayMs, throttleSlowCPULimit); try { server->run(listenep, useSSL); } catch (IException *e) { EXCLOG(e,DAFS_SERVICE_NAME); e->Release(); } PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Stopped"); stopped = true; }
void UnregisterSelf() { StringBuffer slfStr; slfEp.getUrlStr(slfStr); LOG(MCdebugProgress, thorJob, "Unregistering slave : %s", slfStr.toCharArray()); try { CMessageBuffer msg; msg.append((int)rc_deregister); if (!queryWorldCommunicator().send(msg, masterNode, MPTAG_THORREGISTRATION, 60*1000)) { LOG(MCerror, thorJob, "Failed to unregister slave : %s", slfStr.toCharArray()); return; } LOG(MCdebugProgress, thorJob, "Unregistered slave : %s", slfStr.toCharArray()); } catch (IException *e) { FLLOG(MCexception(e), thorJob, e,"slave unregistration error"); e->Release(); } }
StringBuffer & CSmartSocketFactory::getUrlStr(StringBuffer &url, bool useHostName) { SmartSocketEndpoint * sep = nextSmartEndpoint(); if (sep) { SocketEndpoint ep; if(useHostName && sep->name.length()) { url.append(sep->name.str()); ep = sep->ep; if (ep.port) url.append(':').append((unsigned)ep.port); } else { sep->checkHost(dnsInterval); SocketEndpoint ep = sep->ep; ep.getUrlStr(url); } } return url; }
int main(int argc,char **argv) { InitModuleObjects(); EnableSEHtoExceptionMapping(); #ifndef __64BIT__ Thread::setDefaultStackSize(0x10000); // 64K stack (also set in windows DSP) #endif StringBuffer logDir; #ifdef _WIN32 logDir.append("c:\\"); #else if (checkDirExists("/c$")) logDir.append("/c$/"); #endif Owned<IFile> sentinelFile = createSentinelTarget(); removeSentinelFile(sentinelFile); SocketEndpoint listenep; unsigned sendbufsize = 0; unsigned recvbufsize = 0; int i = 1; bool isdaemon = (memicmp(argv[0]+strlen(argv[0])-4,".exe",4)==0); // bit of a kludge for windows - if .exe not specified then not daemon bool locallisten = false; const char *logdir=NULL; bool requireauthenticate = false; while (argc>i) { if (stricmp(argv[i],"-D")==0) { i++; isdaemon = true; } else if (stricmp(argv[i],"-R")==0) { // for remote run i++; #ifdef _WIN32 isdaemon = false; #else isdaemon = true; #endif } else if (stricmp(argv[i],"-A")==0) { i++; requireauthenticate = true; } else if ((argv[i][0]=='-')&&(toupper(argv[i][1])=='T')&&(!argv[i][2]||isdigit(argv[i][2]))) { if (argv[i][2]) setDafsTrace(NULL,(byte)atoi(argv[i]+2)); i++; isdaemon = false; } else if ((argc>i+1)&&(stricmp(argv[i],"-L")==0)) { i++; logDir.clear().append(argv[i++]); addPathSepChar(logDir); } else if (stricmp(argv[i],"-LOCAL")==0) { i++; locallisten = true; } else break; } #ifdef _WIN32 if ((argc>i)&&(stricmp(argv[i],"-install")==0)) { if (installService(DAFS_SERVICE_NAME,DAFS_SERVICE_DISPLAY_NAME,NULL)) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Installed"); return 0; } return 1; } if ((argc>i)&&(stricmp(argv[i],"-remove")==0)) { if (uninstallService(DAFS_SERVICE_NAME,DAFS_SERVICE_DISPLAY_NAME)) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Uninstalled"); return 0; } return 1; } #endif if (argc == i) listenep.port = DAFILESRV_PORT; else { if (strchr(argv[i],'.')||!isdigit(argv[i][0])) listenep.set(argv[i],DAFILESRV_PORT); else listenep.port = atoi(argv[i]); if (listenep.port==0) { usage(); exit(-1); } sendbufsize = (argc>i+1)?(atoi(argv[i+1])*1024):0; recvbufsize = (argc>i+2)?(atoi(argv[i+2])*1024):0; } if (isdaemon) { #ifdef _WIN32 class cserv: public CService { bool stopped; bool started; SocketEndpoint listenep; bool requireauthenticate; class cpollthread: public Thread { cserv *parent; public: cpollthread( cserv *_parent ) : Thread("CService::cpollthread"), parent(_parent) { } int run() { while (parent->poll()) Sleep(1000); return 1; } } pollthread; Owned<IRemoteFileServer> server; public: cserv(SocketEndpoint _listenep) : listenep(_listenep),pollthread(this) { stopped = false; started = false; } virtual ~cserv() { stopped = true; if (started) pollthread.join(); } bool init() { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Initialized"); started = true; pollthread.start(); return true; } bool poll() { if (stopped||!running()) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Stopping"); if (server) { server->stop(); server.clear(); } return false; } return true; } void run() { // Get params from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DaFileSrv\Parameters int requireauthenticate=0; HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\DaFileSrv\\Parameters", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { DWORD dwType = 0; DWORD dwSize = sizeof(requireauthenticate); RegQueryValueEx(hkey, "RequireAuthentication", NULL, &dwType, (BYTE*)&requireauthenticate, &dwSize); RegCloseKey(hkey); } StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate!=0); PROGLOG("Opening "DAFS_SERVICE_DISPLAY_NAME" on %s", eps.str()); const char * verstring = remoteServerVersionString(); PROGLOG("Version: %s", verstring); PROGLOG("Authentication:%s required",requireauthenticate?"":" not"); PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Running"); server.setown(createRemoteFileServer()); try { server->run(listenep); } catch (IException *e) { EXCLOG(e,DAFS_SERVICE_NAME); e->Release(); } PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Stopped"); stopped = true; } } service(listenep); service.start(); return 0; #else int ret = initDaemon(); if (ret) return ret; #endif } { Owned<IComponentLogFileCreator> lf = createComponentLogFileCreator(logDir.str(), "DAFILESRV"); lf->setCreateAliasFile(false); lf->setMaxDetail(TopDetail); lf->beginLogging(); } const char * verstring = remoteServerVersionString(); StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate); PROGLOG("Opening Dali File Server on %s", eps.str()); PROGLOG("Version: %s", verstring); PROGLOG("Authentication:%s required",requireauthenticate?"":" not"); startPerformanceMonitor(10*60*1000, PerfMonStandard); server.setown(createRemoteFileServer()); writeSentinelFile(sentinelFile); try { server->run(listenep); } catch (IException *e) { EXCLOG(e,"DAFILESRV"); e->Release(); } if (server) server->stop(); server.clear(); PROGLOG("Stopped Dali File Server"); return 0; }
static bool RegisterSelf(SocketEndpoint &masterEp) { StringBuffer slfStr; StringBuffer masterStr; LOG(MCdebugProgress, thorJob, "registering %s - master %s",slfEp.getUrlStr(slfStr).str(),masterEp.getUrlStr(masterStr).str()); try { SocketEndpoint ep = masterEp; ep.port = getFixedPort(getMasterPortBase(), TPORT_mp); Owned<INode> masterNode = createINode(ep); CMessageBuffer msg; if (!queryWorldCommunicator().recv(msg, masterNode, MPTAG_THORREGISTRATION)) return false; PROGLOG("Initialization received"); unsigned vmajor, vminor; msg.read(vmajor); msg.read(vminor); if (vmajor != THOR_VERSION_MAJOR || vminor != THOR_VERSION_MINOR) { replyError(TE_FailedToRegisterSlave, "Thor master/slave version mismatch"); return false; } Owned<IGroup> rawGroup = deserializeIGroup(msg); globals->Release(); globals = createPTree(msg); mergeCmdParams(globals); // cmd line unsigned slavesPerNode = globals->getPropInt("@slavesPerNode", 1); unsigned channelsPerSlave = globals->getPropInt("@channelsPerSlave", 1); unsigned localThorPortInc = globals->getPropInt("@localThorPortInc", DEFAULT_SLAVEPORTINC); unsigned slaveBasePort = globals->getPropInt("@slaveport", DEFAULT_THORSLAVEPORT); setClusterGroup(masterNode, rawGroup, slavesPerNode, channelsPerSlave, slaveBasePort, localThorPortInc); unsigned numStrands, blockSize; if (globals->hasProp("Debug/@forceNumStrands")) numStrands = globals->getPropInt("Debug/@forceNumStrands"); else { numStrands = defaultForceNumStrands; globals->setPropInt("Debug/@forceNumStrands", defaultForceNumStrands); } if (globals->hasProp("Debug/@strandBlockSize")) blockSize = globals->getPropInt("Debug/@strandBlockSize"); else { blockSize = defaultStrandBlockSize; globals->setPropInt("Debug/@strandBlockSize", defaultStrandBlockSize); } PROGLOG("Strand defaults: numStrands=%u, blockSize=%u", numStrands, blockSize); const char *_masterBuildTag = globals->queryProp("@masterBuildTag"); const char *masterBuildTag = _masterBuildTag?_masterBuildTag:"no build tag"; PROGLOG("Master build: %s", masterBuildTag); if (!_masterBuildTag || 0 != strcmp(BUILD_TAG, _masterBuildTag)) { StringBuffer errStr("Thor master/slave build mismatch, master = "); errStr.append(masterBuildTag).append(", slave = ").append(BUILD_TAG); ERRLOG("%s", errStr.str()); #ifndef _DEBUG replyError(TE_FailedToRegisterSlave, errStr.str()); return false; #endif } msg.read((unsigned &)masterSlaveMpTag); msg.clear(); msg.setReplyTag(MPTAG_THORREGISTRATION); if (!queryNodeComm().reply(msg)) return false; PROGLOG("Registration confirmation sent"); if (!queryNodeComm().recv(msg, 0, MPTAG_THORREGISTRATION)) // when all registered return false; ::masterNode = LINK(masterNode); PROGLOG("verifying mp connection to rest of cluster"); if (!queryNodeComm().verifyAll()) ERRLOG("Failed to connect to all nodes"); else PROGLOG("verified mp connection to rest of cluster"); LOG(MCdebugProgress, thorJob, "registered %s",slfStr.str()); } catch (IException *e) { FLLOG(MCexception(e), thorJob, e,"slave registration error"); e->Release(); return false; } return true; }
int main( int argc, char *argv[] ) { #if defined(WIN32) && defined(_DEBUG) int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tmpFlag ); #endif InitModuleObjects(); addAbortHandler(ControlHandler); EnableSEHtoExceptionMapping(); dummyProc(); #ifndef __64BIT__ // Restrict stack sizes on 32-bit systems Thread::setDefaultStackSize(0x10000); // NB under windows requires linker setting (/stack:) #endif #ifdef _WIN32 Owned<CReleaseMutex> globalNamedMutex; #endif if (globals) globals->Release(); { Owned<IFile> iFile = createIFile("thor.xml"); globals = iFile->exists() ? createPTree(*iFile, ipt_caseInsensitive) : createPTree("Thor", ipt_caseInsensitive); } unsigned multiThorMemoryThreshold = 0; Owned<IException> unregisterException; try { if (argc==1) { usage(); return 1; } cmdArgs = argv+1; mergeCmdParams(globals); cmdArgs = argv+1; const char *master = globals->queryProp("@MASTER"); if (!master) usage(); const char *slave = globals->queryProp("@SLAVE"); if (slave) { slfEp.set(slave); localHostToNIC(slfEp); } else slfEp.setLocalHost(0); mySlaveNum = globals->getPropInt("@SLAVENUM"); setMachinePortBase(slfEp.port); slfEp.port = getMachinePortBase(); startSlaveLog(); setSlaveAffinity(globals->getPropInt("@SLAVEPROCESSNUM")); startMPServer(getFixedPort(TPORT_mp)); #ifdef USE_MP_LOG startLogMsgParentReceiver(); LOG(MCdebugProgress, thorJob, "MPServer started on port %d", getFixedPort(TPORT_mp)); #endif SocketEndpoint masterEp(master); localHostToNIC(masterEp); setMasterPortBase(masterEp.port); markNodeCentral(masterEp); if (RegisterSelf(masterEp)) { if (globals->getPropBool("Debug/@slaveDaliClient")) enableThorSlaveAsDaliClient(); IDaFileSrvHook *daFileSrvHook = queryDaFileSrvHook(); if (daFileSrvHook) // probably always installed daFileSrvHook->addFilters(globals->queryPropTree("NAS"), &slfEp); StringBuffer thorPath; globals->getProp("@thorPath", thorPath); recursiveCreateDirectory(thorPath.str()); int err = _chdir(thorPath.str()); if (err) { IException *e = makeErrnoExceptionV(-1, "Failed to change dir to '%s'", thorPath.str()); FLLOG(MCexception(e), thorJob, e); throw e; } // Initialization from globals setIORetryCount(globals->getPropInt("Debug/@ioRetries")); // default == 0 == off StringBuffer str; if (globals->getProp("@externalProgDir", str.clear())) _mkdir(str.str()); else globals->setProp("@externalProgDir", thorPath); const char * overrideBaseDirectory = globals->queryProp("@thorDataDirectory"); const char * overrideReplicateDirectory = globals->queryProp("@thorReplicateDirectory"); StringBuffer datadir; StringBuffer repdir; if (getConfigurationDirectory(globals->queryPropTree("Directories"),"data","thor",globals->queryProp("@name"),datadir)) overrideBaseDirectory = datadir.str(); if (getConfigurationDirectory(globals->queryPropTree("Directories"),"mirror","thor",globals->queryProp("@name"),repdir)) overrideReplicateDirectory = repdir.str(); if (overrideBaseDirectory&&*overrideBaseDirectory) setBaseDirectory(overrideBaseDirectory, false); if (overrideReplicateDirectory&&*overrideBaseDirectory) setBaseDirectory(overrideReplicateDirectory, true); StringBuffer tempDirStr; if (getConfigurationDirectory(globals->queryPropTree("Directories"),"temp","thor",globals->queryProp("@name"), tempDirStr)) globals->setProp("@thorTempDirectory", tempDirStr.str()); else tempDirStr.append(globals->queryProp("@thorTempDirectory")); addPathSepChar(tempDirStr).append(getMachinePortBase()); logDiskSpace(); // Log before temp space is cleared SetTempDir(tempDirStr.str(), "thtmp", true); useMemoryMappedRead(globals->getPropBool("@useMemoryMappedRead")); LOG(MCdebugProgress, thorJob, "ThorSlave Version LCR - %d.%d started",THOR_VERSION_MAJOR,THOR_VERSION_MINOR); StringBuffer url; LOG(MCdebugProgress, thorJob, "Slave %s - temporary dir set to : %s", slfEp.getUrlStr(url).str(), queryTempDir()); #ifdef _WIN32 ULARGE_INTEGER userfree; ULARGE_INTEGER total; ULARGE_INTEGER free; if (GetDiskFreeSpaceEx("c:\\",&userfree,&total,&free)&&total.QuadPart) { unsigned pc = (unsigned)(free.QuadPart*100/total.QuadPart); LOG(MCdebugProgress, thorJob, "Total disk space = %" I64F "d k", total.QuadPart/1000); LOG(MCdebugProgress, thorJob, "Free disk space = %" I64F "d k", free.QuadPart/1000); LOG(MCdebugProgress, thorJob, "%d%% disk free\n",pc); } #endif if (getConfigurationDirectory(globals->queryPropTree("Directories"),"query","thor",globals->queryProp("@name"),str.clear())) globals->setProp("@query_so_dir", str.str()); else globals->getProp("@query_so_dir", str.clear()); if (str.length()) { if (globals->getPropBool("Debug/@dllsToSlaves", true)) { StringBuffer uniqSoPath; if (PATHSEPCHAR == str.charAt(str.length()-1)) uniqSoPath.append(str.length()-1, str.str()); else uniqSoPath.append(str); uniqSoPath.append("_").append(getMachinePortBase()); str.swapWith(uniqSoPath); globals->setProp("@query_so_dir", str.str()); } PROGLOG("Using querySo directory: %s", str.str()); recursiveCreateDirectory(str.str()); } multiThorMemoryThreshold = globals->getPropInt("@multiThorMemoryThreshold")*0x100000; if (multiThorMemoryThreshold) { StringBuffer lgname; if (!globals->getProp("@multiThorResourceGroup",lgname)) globals->getProp("@nodeGroup",lgname); if (lgname.length()) { Owned<ILargeMemLimitNotify> notify = createMultiThorResourceMutex(lgname.str()); setMultiThorMemoryNotify(multiThorMemoryThreshold,notify); PROGLOG("Multi-Thor resource limit for %s set to %" I64F "d",lgname.str(),(__int64)multiThorMemoryThreshold); } else multiThorMemoryThreshold = 0; } slaveMain(jobListenerStopped); } LOG(MCdebugProgress, thorJob, "ThorSlave terminated OK"); } catch (IException *e) { if (!jobListenerStopped) FLLOG(MCexception(e), thorJob, e,"ThorSlave"); unregisterException.setown(e); } ClearTempDirs(); if (multiThorMemoryThreshold) setMultiThorMemoryNotify(0,NULL); roxiemem::releaseRoxieHeap(); if (unregisterException.get()) UnregisterSelf(unregisterException); if (globals->getPropBool("Debug/@slaveDaliClient")) disableThorSlaveAsDaliClient(); #ifdef USE_MP_LOG stopLogMsgReceivers(); #endif stopMPServer(); ::Release(globals); releaseAtoms(); // don't know why we can't use a module_exit to destruct these... ExitModuleObjects(); // not necessary, atexit will call, but good for leak checking return 0; }
static bool RegisterSelf(SocketEndpoint &masterEp) { StringBuffer slfStr; StringBuffer masterStr; LOG(MCdebugProgress, thorJob, "registering %s - master %s",slfEp.getUrlStr(slfStr).toCharArray(),masterEp.getUrlStr(masterStr).toCharArray()); try { SocketEndpoint ep = masterEp; ep.port = getFixedPort(getMasterPortBase(), TPORT_mp); Owned<INode> masterNode = createINode(ep); CMessageBuffer msg; if (!queryWorldCommunicator().recv(msg, masterNode, MPTAG_THORREGISTRATION)) return false; PROGLOG("Initialization received"); unsigned vmajor, vminor; msg.read(vmajor); msg.read(vminor); if (vmajor != THOR_VERSION_MAJOR || vminor != THOR_VERSION_MINOR) { replyError("Thor master/slave version mismatch"); return false; } Owned<IGroup> group = deserializeIGroup(msg); setClusterGroup(group); SocketEndpoint myEp = queryMyNode()->endpoint(); rank_t groupPos = group->rank(queryMyNode()); if (RANK_NULL == groupPos) { replyError("Node not part of thorgroup"); return false; } if (globals->hasProp("@SLAVENUM") && (mySlaveNum != (unsigned)groupPos)) { VStringBuffer errStr("Slave group rank[%d] does not match provided cmd line slaveNum[%d]", mySlaveNum, (unsigned)groupPos); replyError(errStr.str()); return false; } globals->Release(); globals = createPTree(msg); mergeCmdParams(globals); // cmd line const char *_masterBuildTag = globals->queryProp("@masterBuildTag"); const char *masterBuildTag = _masterBuildTag?_masterBuildTag:"no build tag"; PROGLOG("Master build: %s", masterBuildTag); #ifndef _DEBUG if (!_masterBuildTag || 0 != strcmp(BUILD_TAG, _masterBuildTag)) { StringBuffer errStr("Thor master/slave build mismatch, master = "); replyError(errStr.append(masterBuildTag).append(", slave = ").append(BUILD_TAG).str()); return false; } #endif msg.read((unsigned &)masterSlaveMpTag); msg.clear(); msg.setReplyTag(MPTAG_THORREGISTRATION); if (!queryClusterComm().reply(msg)) return false; PROGLOG("Registration confirmation sent"); if (!queryClusterComm().recv(msg, 0, MPTAG_THORREGISTRATION)) // when all registered return false; PROGLOG("verifying mp connection to rest of cluster"); if (!queryClusterComm().verifyAll()) ERRLOG("Failed to connect to all nodes"); else PROGLOG("verified mp connection to rest of cluster"); ::masterNode = LINK(masterNode); LOG(MCdebugProgress, thorJob, "registered %s",slfStr.toCharArray()); } catch (IException *e) { FLLOG(MCexception(e), thorJob, e,"slave registration error"); e->Release(); return false; } return true; }
int main( int argc, char *argv[] ) { #if defined(WIN32) && defined(_DEBUG) int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tmpFlag ); #endif InitModuleObjects(); addAbortHandler(ControlHandler); EnableSEHtoExceptionMapping(); dummyProc(); #ifndef __64BIT__ Thread::setDefaultStackSize(0x10000); // NB under windows requires linker setting (/stack:) #endif #ifdef _WIN32 Owned<CReleaseMutex> globalNamedMutex; #endif if (globals) globals->Release(); { Owned<IFile> iFile = createIFile("thor.xml"); globals = iFile->exists() ? createPTree(*iFile, ipt_caseInsensitive) : createPTree("Thor", ipt_caseInsensitive); } unsigned multiThorMemoryThreshold = 0; try { if (argc==1) { usage(); return 1; } cmdArgs = argv+1; mergeCmdParams(globals); cmdArgs = argv+1; const char *master = globals->queryProp("@MASTER"); if (!master) usage(); const char *slave = globals->queryProp("@SLAVE"); if (slave) { slfEp.set(slave); localHostToNIC(slfEp); } else slfEp.setLocalHost(0); if (globals->hasProp("@SLAVENUM")) mySlaveNum = atoi(globals->queryProp("@SLAVENUM")); else mySlaveNum = slfEp.port; // shouldn't happen, provided by script setMachinePortBase(slfEp.port); slfEp.port = getMachinePortBase(); startSlaveLog(); startMPServer(getFixedPort(TPORT_mp)); #ifdef USE_MP_LOG startLogMsgParentReceiver(); LOG(MCdebugProgress, thorJob, "MPServer started on port %d", getFixedPort(TPORT_mp)); #endif SocketEndpoint masterEp(master); localHostToNIC(masterEp); setMasterPortBase(masterEp.port); markNodeCentral(masterEp); if (RegisterSelf(masterEp)) { #define ISDALICLIENT // JCSMORE plugins *can* access dali - though I think we should probably prohibit somehow. #ifdef ISDALICLIENT const char *daliServers = globals->queryProp("@DALISERVERS"); if (!daliServers) { LOG(MCerror, thorJob, "No Dali server list specified\n"); return 1; } Owned<IGroup> serverGroup = createIGroup(daliServers, DALI_SERVER_PORT); unsigned retry = 0; loop { try { LOG(MCdebugProgress, thorJob, "calling initClientProcess"); initClientProcess(serverGroup,DCR_ThorSlave, getFixedPort(TPORT_mp)); break; } catch (IJSOCK_Exception *e) { if ((e->errorCode()!=JSOCKERR_port_in_use)) throw; FLLOG(MCexception(e), thorJob, e,"InitClientProcess"); if (retry++>10) throw; e->Release(); LOG(MCdebugProgress, thorJob, "Retrying"); Sleep(retry*2000); } } setPasswordsFromSDS(); #endif IDaFileSrvHook *daFileSrvHook = queryDaFileSrvHook(); if (daFileSrvHook) // probably always installed daFileSrvHook->addSubnetFilters(globals->queryPropTree("NAS"), NULL); StringBuffer thorPath; globals->getProp("@thorPath", thorPath); recursiveCreateDirectory(thorPath.str()); int err = _chdir(thorPath.str()); if (err) { IException *e = MakeErrnoException(-1, "Failed to change dir to '%s'",thorPath.str()); FLLOG(MCexception(e), thorJob, e); throw e; } // Initialization from globals setIORetryCount(globals->getPropInt("Debug/@ioRetries")); // default == 0 == off StringBuffer str; if (globals->getProp("@externalProgDir", str.clear())) _mkdir(str.str()); else globals->setProp("@externalProgDir", thorPath); const char * overrideBaseDirectory = globals->queryProp("@thorDataDirectory"); const char * overrideReplicateDirectory = globals->queryProp("@thorReplicateDirectory"); StringBuffer datadir; StringBuffer repdir; if (getConfigurationDirectory(globals->queryPropTree("Directories"),"data","thor",globals->queryProp("@name"),datadir)) overrideBaseDirectory = datadir.str(); if (getConfigurationDirectory(globals->queryPropTree("Directories"),"mirror","thor",globals->queryProp("@name"),repdir)) overrideReplicateDirectory = repdir.str(); if (overrideBaseDirectory&&*overrideBaseDirectory) setBaseDirectory(overrideBaseDirectory, false); if (overrideReplicateDirectory&&*overrideBaseDirectory) setBaseDirectory(overrideReplicateDirectory, true); StringBuffer tempdirstr; const char *tempdir = globals->queryProp("@thorTempDirectory"); if (getConfigurationDirectory(globals->queryPropTree("Directories"),"temp","thor",globals->queryProp("@name"),tempdirstr)) tempdir = tempdirstr.str(); SetTempDir(tempdir,true); useMemoryMappedRead(globals->getPropBool("@useMemoryMappedRead")); LOG(MCdebugProgress, thorJob, "ThorSlave Version LCR - %d.%d started",THOR_VERSION_MAJOR,THOR_VERSION_MINOR); StringBuffer url; LOG(MCdebugProgress, thorJob, "Slave %s - temporary dir set to : %s", slfEp.getUrlStr(url).toCharArray(), queryTempDir()); #ifdef _WIN32 ULARGE_INTEGER userfree; ULARGE_INTEGER total; ULARGE_INTEGER free; if (GetDiskFreeSpaceEx("c:\\",&userfree,&total,&free)&&total.QuadPart) { unsigned pc = (unsigned)(free.QuadPart*100/total.QuadPart); LOG(MCdebugProgress, thorJob, "Total disk space = %"I64F"d k", total.QuadPart/1000); LOG(MCdebugProgress, thorJob, "Free disk space = %"I64F"d k", free.QuadPart/1000); LOG(MCdebugProgress, thorJob, "%d%% disk free\n",pc); } #endif if (getConfigurationDirectory(globals->queryPropTree("Directories"),"query","thor",globals->queryProp("@name"),str.clear())) globals->setProp("@query_so_dir", str.str()); else globals->getProp("@query_so_dir", str.clear()); if (str.length()) { if (globals->getPropBool("Debug/@dllsToSlaves", true)) { StringBuffer uniqSoPath; if (PATHSEPCHAR == str.charAt(str.length()-1)) uniqSoPath.append(str.length()-1, str.str()); else uniqSoPath.append(str); uniqSoPath.append("_").append(getMachinePortBase()); str.swapWith(uniqSoPath); globals->setProp("@query_so_dir", str.str()); } PROGLOG("Using querySo directory: %s", str.str()); recursiveCreateDirectory(str.str()); } multiThorMemoryThreshold = globals->getPropInt("@multiThorMemoryThreshold")*0x100000; if (multiThorMemoryThreshold) { StringBuffer lgname; if (!globals->getProp("@multiThorResourceGroup",lgname)) globals->getProp("@nodeGroup",lgname); if (lgname.length()) { Owned<ILargeMemLimitNotify> notify = createMultiThorResourceMutex(lgname.str()); setMultiThorMemoryNotify(multiThorMemoryThreshold,notify); PROGLOG("Multi-Thor resource limit for %s set to %"I64F"d",lgname.str(),(__int64)multiThorMemoryThreshold); } else multiThorMemoryThreshold = 0; } slaveMain(); } LOG(MCdebugProgress, thorJob, "ThorSlave terminated OK"); } catch (IException *e) { FLLOG(MCexception(e), thorJob, e,"ThorSlave"); e->Release(); } catch (CATCHALL) { FLLOG(MCerror, thorJob, "ThorSlave exiting because of uncaught exception"); } ClearTempDirs(); if (multiThorMemoryThreshold) setMultiThorMemoryNotify(0,NULL); roxiemem::releaseRoxieHeap(); #ifdef ISDALICLIENT closeEnvironment(); closedownClientProcess(); // dali client closedown #endif #ifdef USE_MP_LOG stopLogMsgReceivers(); #endif stopMPServer(); ::Release(globals); releaseAtoms(); // don't know why we can't use a module_exit to destruct these... return 0; }
int CDfuPlusHelper::spray() { const char* srcxml = globals->queryProp("srcxml"); const char* srcip = globals->queryProp("srcip"); const char* srcfile = globals->queryProp("srcfile"); bool nowait = globals->getPropBool("nowait", false); MemoryBuffer xmlbuf; if(srcxml == NULL) { if(srcfile == NULL) throw MakeStringException(-1, "srcfile not specified"); if(srcip == NULL) { #ifdef DAFILESRV_LOCAL progress("srcip not specified - assuming spray from local machine\n"); srcip = "."; #else throw MakeStringException(-1, "srcip not specified"); #endif } } else { if(srcip != NULL || srcfile != NULL) throw MakeStringException(-1, "srcip/srcfile and srcxml can't be used at the same time"); StringBuffer buf; buf.loadFile(srcxml); int len = buf.length(); xmlbuf.setBuffer(len, buf.detach(), true); } const char* dstname = globals->queryProp("dstname"); if(dstname == NULL) throw MakeStringException(-1, "dstname not specified"); const char* dstcluster = globals->queryProp("dstcluster"); if(dstcluster == NULL) throw MakeStringException(-1, "dstcluster not specified"); const char* format = globals->queryProp("format"); if(format == NULL) format = "fixed"; SocketEndpoint localep; StringBuffer localeps; if (checkLocalDaFileSvr(srcip,localep)) srcip = localep.getUrlStr(localeps).str(); StringBuffer wuid; StringBuffer errmsg; bool ok; if ((stricmp(format, "fixed") == 0)||(stricmp(format, "recfmvb") == 0)||(stricmp(format, "recfmv") == 0)||(stricmp(format, "variablebigendian") == 0)) ok = fixedSpray(srcxml,srcip,srcfile,xmlbuf,dstcluster,dstname,format,wuid,errmsg); else if((stricmp(format, "csv") == 0) ||(stricmp(format, "xml") == 0)||(stricmp(format, "variable") == 0)) ok = variableSpray(srcxml,srcip,srcfile,xmlbuf,dstcluster,dstname,format,wuid, errmsg); else throw MakeStringException(-1, "format %s not supported", format); if (!ok) { if(errmsg.length()) error("%s\n", errmsg.str()); else throw MakeStringException(-1, "unknown error spraying"); } else { const char* jobname = globals->queryProp("jobname"); if(jobname && *jobname) updatejobname(wuid.str(), jobname); info("Submitted WUID %s\n", wuid.str()); if(!nowait) waitToFinish(wuid.str()); } return 0; }
int CDfuPlusHelper::despray() { const char* srcname = globals->queryProp("srcname"); if(srcname == NULL) throw MakeStringException(-1, "srcname not specified"); const char* dstxml = globals->queryProp("dstxml"); const char* dstip = globals->queryProp("dstip"); const char* dstfile = globals->queryProp("dstfile"); bool nowait = globals->getPropBool("nowait", false); MemoryBuffer xmlbuf; if(dstxml == NULL) { if(dstfile == NULL) throw MakeStringException(-1, "dstfile not specified"); if(dstip == NULL) { #ifdef DAFILESRV_LOCAL progress("dstip not specified - assuming spray from local machine\n"); dstip = "."; #else throw MakeStringException(-1, "dstip not specified"); #endif } } else { if(dstip != NULL || dstfile != NULL) throw MakeStringException(-1, "dstip/dstfile and dstxml can't be used at the same time"); StringBuffer buf; buf.loadFile(dstxml); int len = buf.length(); xmlbuf.setBuffer(len, buf.detach(), true); } if(dstxml == NULL) info("\nDespraying %s to host %s file %s\n", srcname, dstip, dstfile); else info("\nDespraying %s\n", srcname); Owned<IClientDespray> req = sprayclient->createDesprayRequest(); req->setSourceLogicalName(srcname); if(dstxml == NULL) { req->setDestIP(dstip); req->setDestPath(dstfile); } else req->setDstxml(xmlbuf); req->setOverwrite(globals->getPropBool("overwrite", false)); if(globals->hasProp("connect")) req->setMaxConnections(globals->getPropInt("connect")); if(globals->hasProp("throttle")) req->setThrottle(globals->getPropInt("throttle")); if(globals->hasProp("transferbuffersize")) req->setTransferBufferSize(globals->getPropInt("transferbuffersize")); if(globals->hasProp("norecover")) req->setNorecover(globals->getPropBool("norecover", false)); else if(globals->hasProp("noRecover")) req->setNorecover(globals->getPropBool("noRecover", false)); if(globals->hasProp("splitprefix")) req->setSplitprefix(globals->queryProp("splitprefix")); else if(globals->hasProp("splitPrefix")) req->setSplitprefix(globals->queryProp("splitPrefix")); if(globals->hasProp("wrap")) req->setWrap(globals->getPropBool("wrap", false)); if(globals->hasProp("multicopy")) req->setMultiCopy(globals->getPropBool("multicopy", false)); else if(globals->hasProp("multiCopy")) req->setMultiCopy(globals->getPropBool("multiCopy", false)); if(globals->hasProp("compress")) req->setCompress(globals->getPropBool("compress", false)); if(globals->hasProp("encrypt")) req->setEncrypt(globals->queryProp("encrypt")); if(globals->hasProp("decrypt")) req->setDecrypt(globals->queryProp("decrypt")); SocketEndpoint localep; StringBuffer localeps; if (checkLocalDaFileSvr(dstip,localep)) dstip = localep.getUrlStr(localeps).str(); Owned<IClientDesprayResponse> result = sprayclient->Despray(req); const char* wuid = result->getWuid(); if(wuid == NULL || *wuid == '\0') exc(result->getExceptions(),"despraying"); else { const char* jobname = globals->queryProp("jobname"); if(jobname && *jobname) updatejobname(wuid, jobname); info("Submitted WUID %s\n", wuid); if(!nowait) waitToFinish(wuid); } return 0; }
int COneServerHttpProxyThread::start() { try { char peername[256]; int port = m_client->peer_name(peername, 256); if(httptest_tracelevel > 5) fprintf(m_ofile, "\n>>receivd request from %s:%d\n", peername, port); StringBuffer requestbuf; Owned<IByteOutputStream> reqstream = createOutputStream(requestbuf); receiveData(m_client, reqstream.get(), false); if(httptest_tracelevel > 10) fprintf(m_ofile, "%s%s%s", sepstr, requestbuf.str(), sepstr); SocketEndpoint ep; Owned<ISocket> socket2; ep.set(m_host.str(), m_port); socket2.setown(ISocket::connect(ep)); if(m_use_ssl && m_ssctx != NULL) { Owned<ISecureSocket> securesocket = m_ssctx->createSecureSocket(socket2.getLink()); int res = securesocket->secure_connect(); if(res >= 0) { socket2.set(securesocket.get()); } } if(socket2.get() == NULL) { StringBuffer urlstr; DBGLOG(">>Can't connect to %s", ep.getUrlStr(urlstr).str()); return -1; } char newhost[1024]; sprintf(newhost, "%s:%d", m_host.str(), m_port); replaceHeader(requestbuf, "Host", newhost); //checkContentLength(requestbuf); if(httptest_tracelevel > 5) fprintf(m_ofile, "\n>>sending request to %s:%d\n", m_host.str(), m_port); if(httptest_tracelevel > 10) fprintf(m_ofile, "%s%s%s", sepstr, requestbuf.str(), sepstr); socket2->write(requestbuf.str(), requestbuf.length()); StringBuffer respbuf; Owned<IByteOutputStream> respstream = createOutputStream(respbuf); receiveData(socket2.get(), respstream.get(), true); if(httptest_tracelevel > 5) fprintf(m_ofile, ">>received response from %s:%d:\n", m_host.str(), m_port); if(httptest_tracelevel > 10) fprintf(m_ofile, "%s%s%s", sepstr, respbuf.str(), sepstr); m_client->write(respbuf.str(), respbuf.length()); fflush(m_ofile); if(httptest_tracelevel > 5) fprintf(m_ofile, ">>sent the response back to %s:%d:\n", peername, port); socket2->shutdown(); socket2->close(); m_client->shutdown(); m_client->close(); } catch(IException *excpt) { StringBuffer errMsg; DBGLOG("%s", excpt->errorMessage(errMsg).str()); return -1; } catch(...) { DBGLOG("unknown exception"); return -1; } return 0; }
int HttpClient::sendRequest(int times, HttpStat& stat, StringBuffer& req) { StringBuffer request; if(req.length() <= 2) { throw MakeStringException(-1, "request too short"); } bool endofheaders = false; char c0 = req.charAt(0); char c1 = req.charAt(1); if(c0 == '\n') request.append("\r\n"); else request.append(c0); if(c1 == '\n') { if(c0 == '\r') request.append(c1); else { request.append("\r\n"); if(c0 == '\n') endofheaders = true; } } else request.append(c1); unsigned seq = 2; while(seq < req.length() && !endofheaders) { char c = req.charAt(seq); if(c == '\n') { char c1 = req.charAt(seq - 1); char c2 = req.charAt(seq - 2); if(c1 == '\n' || (c1 == '\r' && c2 == '\n')) endofheaders = true; if(c1 != '\r') request.append("\r\n"); else request.append(c); } else request.append(c); seq++; } if(seq < req.length()) request.append(req.length() - seq, req.str() + seq); if(httptest_tracelevel > 5) fprintf(m_ofile, ">>sending out request to %s:%d for %d times\n", m_host.str(), m_port, times); unsigned start = msTick(); int slowest = 0; int fastest = 2147483647; for(int i = 0; i < times; i++) { SocketEndpoint ep; ep.set(m_host.str(), m_port); Owned<ISocket> socket; try { socket.setown(ISocket::connect(ep)); if(m_use_ssl && m_ssctx.get() != NULL) { Owned<ISecureSocket> securesocket = m_ssctx->createSecureSocket(socket.getLink()); int res = securesocket->secure_connect(); if(res >= 0) { socket.set(securesocket.get()); } } } catch(IException *excpt) { StringBuffer errMsg; DBGLOG("Error connecting to %s:%d - %d:%s", m_host.str(), m_port, excpt->errorCode(), excpt->errorMessage(errMsg).str()); continue; } catch(...) { DBGLOG("can't connect to %s:%d", m_host.str(), m_port); continue; } if(socket.get() == NULL) { StringBuffer urlstr; DBGLOG(">>Can't connect to %s", ep.getUrlStr(urlstr).str()); continue; } if(m_delay > 0) sleep(m_delay); if(httptest_tracelevel > 5) fprintf(m_ofile, ">>sending out request:\n"); if(httptest_tracelevel > 10) fprintf(m_ofile, "%s%s%s\n", sepstr, request.str(), sepstr); unsigned start1 = msTick(); socket->write(request.str(), request.length()); if(httptest_tracelevel > 5) fprintf(m_ofile, ">>receiving response:\n"); StringBuffer buf; Owned<IByteOutputStream> ostream = createOutputStream(buf); stat.totalresplen += receiveData(socket.get(), ostream.get(), true); if(httptest_tracelevel > 10) fprintf(m_ofile, "%s%s%s\n", sepstr, buf.str(), sepstr); char tmpbuf[256]; unsigned int sizeread; do { socket->read(tmpbuf, 0, 256, sizeread); } while(sizeread > 0); socket->shutdown(); socket->close(); fflush(m_ofile); unsigned end1 = msTick(); int duration = end1 - start1; if(duration <= fastest) fastest = duration; if(duration > slowest) slowest = duration; if(i % 100 == 0) fprintf(stderr, "sent out %d\n", i); } unsigned end = msTick(); stat.msecs = end - start; stat.numrequests = times; stat.totalreqlen = times * request.length(); stat.slowest = slowest; stat.fastest = fastest; return 0; }
int COneServerHttpProxyThread::start() { try { char peername[256]; int port = m_client->peer_name(peername, 256); if(http_tracelevel >= 5) fprintf(m_ofile, "\n>>receivd request from %s:%d\n", peername, port); StringBuffer requestbuf; Owned<IByteOutputStream> reqstream = createOutputStream(requestbuf); bool isRoxie; Http::receiveData(m_client, reqstream.get(), false, isRoxie); if(http_tracelevel >= 10) fprintf(m_ofile, "%s%s%s", sepstr, requestbuf.str(), sepstr); else if(http_tracelevel >= 5) { const char* endofline = strstr(requestbuf.str(), "\n"); if(endofline) { StringBuffer firstline; firstline.append((endofline - requestbuf.str()), requestbuf.str()); fprintf(m_ofile, "%s", firstline.str()); } else fprintf(m_ofile, "%s\n", requestbuf.str()); } if (0 != stricmp(m_url_prefix, "/")) { int url_offset; if (!strnicmp(requestbuf.str(), "GET ", 4)) url_offset = 4; else if (!strnicmp(requestbuf.str(), "POST ", 5)) url_offset = 5; else url_offset = -1; if (url_offset > 0) { const int prefix_len = strlen(m_url_prefix); if (0 != strnicmp(requestbuf.str()+url_offset, m_url_prefix, prefix_len)) { const char* endofline = strstr(requestbuf.str(), "\n"); if(endofline) { StringBuffer firstline; firstline.append((endofline - requestbuf.str()), requestbuf.str()); fprintf(m_ofile, "INVALID request: %s", firstline.str()); } else fprintf(m_ofile, "INVALID request:\n%s\n", requestbuf.str()); StringBuffer respbuf; respbuf.append("HTTP/1.1 404 Not Found\n") .append("Content-Type: text/xml; charset=UTF-8\n") .append("Connection: close\n"); m_client->write(respbuf.str(), respbuf.length()); if(http_tracelevel >= 5) fprintf(m_ofile, ">>sent the response back to %s:%d:\n", peername, port); if(http_tracelevel >= 10) fprintf(m_ofile, "%s%s%s", sepstr, respbuf.str(), sepstr); fflush(m_ofile); m_client->shutdown(); m_client->close(); return -1; } else { //we want to map /x to / and /x/y to /y as follows: //if m_url_prefix is /x and url is /x/y then remove x //to result in //y requestbuf.remove(++url_offset, prefix_len-1); //now, if we have //y then change it to /y if (*(requestbuf.str()+url_offset) == '/') requestbuf.remove(url_offset, 1); } } } SocketEndpoint ep; Owned<ISocket> socket2; ep.set(m_host.str(), m_port); socket2.setown(ISocket::connect(ep)); if(m_use_ssl && m_ssctx != NULL) { Owned<ISecureSocket> securesocket = m_ssctx->createSecureSocket(socket2.getLink()); int res = securesocket->secure_connect(); if(res >= 0) { socket2.set(securesocket.get()); } } if(socket2.get() == NULL) { StringBuffer urlstr; DBGLOG(">>Can't connect to %s", ep.getUrlStr(urlstr).str()); return -1; } char newhost[1024]; sprintf(newhost, "%s:%d", m_host.str(), m_port); replaceHeader(requestbuf, "Host", newhost); //checkContentLength(requestbuf); if(http_tracelevel >= 5) fprintf(m_ofile, "\n>>sending request to %s:%d\n", m_host.str(), m_port); if(http_tracelevel >= 10) fprintf(m_ofile, "%s%s%s", sepstr, requestbuf.str(), sepstr); socket2->write(requestbuf.str(), requestbuf.length()); StringBuffer respbuf; Owned<IByteOutputStream> respstream = createOutputStream(respbuf); isRoxie; Http::receiveData(socket2.get(), respstream.get(), true, isRoxie); if(http_tracelevel >= 5) fprintf(m_ofile, ">>received response from %s:%d:\n", m_host.str(), m_port); if(http_tracelevel >= 10) fprintf(m_ofile, "%s%s%s", sepstr, respbuf.str(), sepstr); m_client->write(respbuf.str(), respbuf.length()); fflush(m_ofile); if(http_tracelevel >= 5) fprintf(m_ofile, ">>sent the response back to %s:%d:\n", peername, port); if(http_tracelevel >= 10) fprintf(m_ofile, "%s%s%s", sepstr, respbuf.str(), sepstr); socket2->shutdown(); socket2->close(); m_client->shutdown(); m_client->close(); } catch(IException *excpt) { StringBuffer errMsg; DBGLOG("%s", excpt->errorMessage(errMsg).str()); return -1; } catch(...) { DBGLOG("unknown exception"); return -1; } return 0; }
int main(int argc,char **argv) { InitModuleObjects(); EnableSEHtoExceptionMapping(); #ifndef __64BIT__ // Restrict stack sizes on 32-bit systems Thread::setDefaultStackSize(0x10000); // 64K stack (also set in windows DSP) #endif Owned<IFile> sentinelFile = createSentinelTarget(); removeSentinelFile(sentinelFile); SocketEndpoint listenep; unsigned sendbufsize = 0; unsigned recvbufsize = 0; int i = 1; bool isdaemon = (memicmp(argv[0]+strlen(argv[0])-4,".exe",4)==0); // bit of a kludge for windows - if .exe not specified then not daemon bool locallisten = false; const char *logdir=NULL; bool requireauthenticate = false; StringBuffer logDir; StringBuffer instanceName; //Get SSL Settings const char * sslCertFile; bool useSSL; unsigned short dafsPort;//DAFILESRV_PORT or SECURE_DAFILESRV_PORT querySecuritySettings(&useSSL, &dafsPort, &sslCertFile, NULL); unsigned parallelRequestLimit = DEFAULT_PARALLELREQUESTLIMIT; unsigned throttleDelayMs = DEFAULT_THROTTLEDELAYMS; unsigned throttleCPULimit = DEFAULT_THROTTLECPULIMIT; Owned<IPropertyTree> env = getHPCCEnvironment(); if (env) { StringBuffer dafilesrvPath("Software/DafilesrvProcess"); if (instanceName.length()) dafilesrvPath.appendf("[@name=\"%s\"]", instanceName.str()); IPropertyTree *daFileSrv = env->queryPropTree(dafilesrvPath); if (daFileSrv) { // global DaFileSrv settings: parallelRequestLimit = daFileSrv->getPropInt("@parallelRequestLimit", DEFAULT_PARALLELREQUESTLIMIT); throttleDelayMs = daFileSrv->getPropInt("@throttleDelayMs", DEFAULT_THROTTLEDELAYMS); throttleCPULimit = daFileSrv->getPropInt("@throttleCPULimit", DEFAULT_THROTTLECPULIMIT); // any overrides by Instance definitions? // NB: This won't work if netAddress is "." or if we start supporting hostnames there StringBuffer ipStr; queryHostIP().getIpText(ipStr); VStringBuffer daFileSrvPath("Instance[@netAddress=\"%s\"]", ipStr.str()); IPropertyTree *dafileSrvInstance = daFileSrv->queryPropTree(daFileSrvPath); if (dafileSrvInstance) { parallelRequestLimit = dafileSrvInstance->getPropInt("@parallelRequestLimit", parallelRequestLimit); throttleDelayMs = dafileSrvInstance->getPropInt("@throttleDelayMs", throttleDelayMs); throttleCPULimit = dafileSrvInstance->getPropInt("@throttleCPULimit", throttleCPULimit); } } } while (argc>i) { if (stricmp(argv[i],"-D")==0) { i++; isdaemon = true; } else if (stricmp(argv[i],"-R")==0) { // for remote run i++; #ifdef _WIN32 isdaemon = false; #else isdaemon = true; #endif } else if (stricmp(argv[i],"-A")==0) { i++; requireauthenticate = true; } else if ((argv[i][0]=='-')&&(toupper(argv[i][1])=='T')&&(!argv[i][2]||isdigit(argv[i][2]))) { if (argv[i][2]) setDafsTrace(NULL,(byte)atoi(argv[i]+2)); i++; isdaemon = false; } else if ((argc>i+1)&&(stricmp(argv[i],"-L")==0)) { i++; logDir.clear().append(argv[i++]); } else if ((argc>i+1)&&(stricmp(argv[i],"-I")==0)) { i++; instanceName.clear().append(argv[i++]); } else if (stricmp(argv[i],"-LOCAL")==0) { i++; locallisten = true; } else if (stricmp(argv[i],"-NOSSL")==0) {//overrides config setting i++; if (useSSL) { PROGLOG("DaFileSrv SSL specified in config but overridden by -NOSSL in command line"); useSSL = false; dafsPort = DAFILESRV_PORT; } } else break; } if (useSSL && !sslCertFile) { ERRLOG("DaFileSrv SSL specified but certificate file information missing from environment.conf"); exit(-1); } if (0 == logDir.length()) { getConfigurationDirectory(NULL,"log","dafilesrv",instanceName.str(),logDir); if (0 == logDir.length()) logDir.append("."); } if (instanceName.length()) { addPathSepChar(logDir); logDir.append(instanceName.str()); } #ifdef _WIN32 if ((argc>i)&&(stricmp(argv[i],"-install")==0)) { if (installService(DAFS_SERVICE_NAME,DAFS_SERVICE_DISPLAY_NAME,NULL)) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Installed"); return 0; } return 1; } if ((argc>i)&&(stricmp(argv[i],"-remove")==0)) { if (uninstallService(DAFS_SERVICE_NAME,DAFS_SERVICE_DISPLAY_NAME)) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Uninstalled"); return 0; } return 1; } #endif if (argc == i) listenep.port = dafsPort; else { if (strchr(argv[i],'.')||!isdigit(argv[i][0])) listenep.set(argv[i], dafsPort); else listenep.port = atoi(argv[i]); if (listenep.port==0) { usage(); exit(-1); } sendbufsize = (argc>i+1)?(atoi(argv[i+1])*1024):0; recvbufsize = (argc>i+2)?(atoi(argv[i+2])*1024):0; } if (isdaemon) { #ifdef _WIN32 class cserv: public CService { bool stopped; bool started; SocketEndpoint listenep; bool useSSL; bool requireauthenticate; class cpollthread: public Thread { cserv *parent; public: cpollthread( cserv *_parent ) : Thread("CService::cpollthread"), parent(_parent) { } int run() { while (parent->poll()) Sleep(1000); return 1; } } pollthread; Owned<IRemoteFileServer> server; public: cserv(SocketEndpoint _listenep, bool _useSSL) : listenep(_listenep),useSSL(_useSSL),pollthread(this) { stopped = false; started = false; } virtual ~cserv() { stopped = true; if (started) pollthread.join(); } bool init() { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Initialized"); started = true; pollthread.start(); return true; } bool poll() { if (stopped||!running()) { PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Stopping"); if (server) { server->stop(); server.clear(); } return false; } return true; } void run() { // Get params from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DaFileSrv\Parameters int requireauthenticate=0; HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\DaFileSrv\\Parameters", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { DWORD dwType = 0; DWORD dwSize = sizeof(requireauthenticate); RegQueryValueEx(hkey, "RequireAuthentication", NULL, &dwType, (BYTE*)&requireauthenticate, &dwSize); RegCloseKey(hkey); } StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate!=0); PROGLOG("Opening " DAFS_SERVICE_DISPLAY_NAME " on %s%s", useSSL?"SECURE ":"",eps.str()); const char * verstring = remoteServerVersionString(); PROGLOG("Version: %s", verstring); PROGLOG("Authentication:%s required",requireauthenticate?"":" not"); PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Running"); server.setown(createRemoteFileServer(parallelRequestLimit, throttleDelayMs, throttleCPULimit)); try { server->run(listenep, useSSL); } catch (IException *e) { EXCLOG(e,DAFS_SERVICE_NAME); e->Release(); } PROGLOG(DAFS_SERVICE_DISPLAY_NAME " Stopped"); stopped = true; } } service(listenep, useSSL); service.start(); return 0; #else int ret = initDaemon(); if (ret) return ret; #endif } { Owned<IComponentLogFileCreator> lf = createComponentLogFileCreator(logDir.str(), "DAFILESRV"); lf->setCreateAliasFile(false); lf->setMaxDetail(TopDetail); lf->beginLogging(); } PROGLOG("Parallel request limit = %d, throttleDelayMs = %d, throttleCPULimit = %d", parallelRequestLimit, throttleDelayMs, throttleCPULimit); const char * verstring = remoteServerVersionString(); StringBuffer eps; if (listenep.isNull()) eps.append(listenep.port); else listenep.getUrlStr(eps); enableDafsAuthentication(requireauthenticate); PROGLOG("Opening Dali File Server on %s%s", useSSL?"SECURE ":"",eps.str()); PROGLOG("Version: %s", verstring); PROGLOG("Authentication:%s required",requireauthenticate?"":" not"); startPerformanceMonitor(10*60*1000, PerfMonStandard); server.setown(createRemoteFileServer(parallelRequestLimit, throttleDelayMs, throttleCPULimit)); writeSentinelFile(sentinelFile); try { server->run(listenep, useSSL); } catch (IException *e) { EXCLOG(e,"DAFILESRV"); e->Release(); } if (server) server->stop(); server.clear(); PROGLOG("Stopped Dali File Server"); return 0; }
void Do(unsigned i) { ISocket *sock = sockets.item(i); StringBuffer epstr; SocketEndpoint ep = eps.item(i); ep.getUrlStr(epstr); // PROGLOG("T.1 %s %x",epstr.str(),(unsigned)sock); StringBuffer verstr; unsigned rver=0; if (sock) { rver = getRemoteVersion(sock, verstr); switch (mode) { case AMcheck: if (rver!=0) return; case AMver: { CriticalBlock block(sect); result.append(ep); StringBuffer ln; ln.append(rver).append(",\"").append(verstr).append('"'); resultstr.append(* new StringAttrItem(ln.str())); } return; case AMstopver: case AMcheckver: case AMcheckvermajor: { // compares versions up to the '-' const char *rv = verstr.str(); const char *v = remoteServerVersionString(); if (mode!=AMcheckvermajor) { while (*v&&(*v!='-')&&(*v==*rv)) { v++; rv++; } } if ((*rv==*v)&&(rver==ver)) return; while (*rv&&(*rv!='-')) rv++; verstr.setLength(rv-verstr.str()); if ((mode==AMcheckver)||(mode==AMcheckvermajor)) break; } // fall through case AMstop: { unsigned err = stopRemoteServer(sock); if (err!=0) { ERRLOG("Could not stop server on %s, %d returned",epstr.str(),err); if (mode!=AMstopver) return; // even though failed to stop - still return code } else Sleep(1000); // let stop } break; default: return; } } CriticalBlock block(sect); result.append(ep); if ((mode!=AMver)&&(mode!=AMcheckver)&&(mode!=AMcheckvermajor)&&(mode!=AMstopver)) resultstr.append(* new StringAttrItem("")); else resultstr.append(* new StringAttrItem(verstr.str())); }