Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
0
 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;
 }
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
    }
}
Ejemplo n.º 6
0
 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();
 }
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
 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());
     }
 }   
Ejemplo n.º 9
0
    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();
        }
    }
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
 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());
 }
Ejemplo n.º 12
0
    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
    }
Ejemplo n.º 13
0
    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;
    }
Ejemplo n.º 14
0
 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;
 }
Ejemplo n.º 15
0
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();
    }
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
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()));
        }