Пример #1
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;
}
Пример #2
0
 ~Cwriteintercept() 
 {
     flush();
     if (overflowed)
         PROGLOG("Overflowed by %"I64F"d",overflowsize);
 }
Пример #3
0
void sighandler(int signum, siginfo_t *info, void *extra) 
{
    PROGLOG("Caught signal %d, %p", signum, info?info->si_addr:0);
    if (server)
        server->stop();
}
Пример #4
0
int main(int argc, const char *argv[])
{
    InitModuleObjects();

    int ret = 0;
    bool dryRun = false;
    bool offline = false;
    StringAttr daliServer, envPath;

    enum CmdType { cmd_none, cmd_swap, cmd_auto, cmd_history, cmd_email, cmd_swapped, cmd_reset, cmd_resetspares, cmd_addspares, cmd_removespares, cmd_resethistory };
    CmdType cmd = cmd_none;

    ArgvIterator iter(argc, argv);

    try
    {
        bool stop=false;
        StringArray params;
        for (; !ret&&!iter.done(); iter.next())
        {
            const char *arg = iter.query();
            if ('-' == *arg)
            {
                bool value;
                if (iter.matchFlag(value, "-dryrun"))
                    dryRun = value;
                else if (iter.matchFlag(value, "-offline"))
                    offline = value;
                else
                {
                    PROGLOG("Unknown option");
                    ret = 2;
                    usage();
                    break;
                }
            }
            else
            {
                switch (cmd)
                {
                    case cmd_none:
                        if (strieq("swap", arg))
                            cmd = cmd_swap;
                        else if (strieq("auto", arg))
                            cmd = cmd_auto;
                        else if (strieq("history", arg))
                            cmd = cmd_history;
                        else if (strieq("email", arg))
                            cmd = cmd_email;
                        else if (strieq("swapped", arg))
                            cmd = cmd_swapped;
                        else if (strieq("reset", arg))
                            cmd = cmd_reset;
                        else if (strieq("resetspares", arg))
                            cmd = cmd_resetspares;
                        else if (strieq("addspares", arg))
                            cmd = cmd_addspares;
                        else if (strieq("removespares", arg))
                            cmd = cmd_removespares;
                        else if (strieq("resethistory", arg))
                            cmd = cmd_resethistory;
                        else
                        {
                            PROGLOG("Unknown command");
                            usage();
                            ret = 2;
                        }
                        break;
                    default:
                        params.append(iter.query());
                        break;
                }
            }
        }
        unsigned requiredParams=UINT_MAX;
        switch (cmd)
        {
            case cmd_swap:
                requiredParams = 4;
                break;
            case cmd_addspares:
            case cmd_removespares:
                requiredParams = 3;
                break;
            case cmd_auto:
            case cmd_history:
            case cmd_email:
            case cmd_swapped:
            case cmd_reset:
            case cmd_resetspares:
            case cmd_resethistory:
                requiredParams = 2;
                break;
        }
        if (params.ordinality() < requiredParams)
        {
            usage();
            ret = 2;
        }
        else
        {
            StringAttr daliServer = params.item(0);
            StringAttr clusterName = params.item(1);

            DaliClient dclient(daliServer);
            StringBuffer logname;
            splitFilename(argv[0], NULL, NULL, &logname, NULL);
            addFileTimestamp(logname, true);
            logname.append(".log");
            StringBuffer lf;
            openLogFile(lf, logname.str(),0,false,true);
            queryStderrLogMsgHandler()->setMessageFields(MSGFIELD_prefix);

            Owned<IRemoteConnection> conn = querySDS().connect("/Environment", myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT);
            IPropertyTree *environment = conn->queryRoot();
            StringBuffer xpath("Software/ThorCluster[@name=\"");
            xpath.append(clusterName).append("\"]");
            IPropertyTree *cluster = environment->queryPropTree(xpath.str());
            if (!cluster)
            {
                PROGLOG("Unknown cluster: %s", clusterName.get());
                ret = 3;
            }
            if (!ret)
            {
                Owned<IPropertyTree> options = createPTreeFromIPT(cluster);
                conn.clear();
                if (options&&options->getPropBool("@enableSysLog",true))
                    UseSysLogForOperatorMessages();

                switch (cmd)
                {
                    case cmd_auto:
                    {
                        if (!autoSwapNode(clusterName, dryRun))
                            ret = 3;
                        break;
                    }
                    case cmd_swap:
                    {
                        const char *oldip=params.item(2);
                        const char *newip=params.item(3);
                        if (!swapNode(clusterName, oldip, newip))
                            ret = 3;
                        break;
                    }
                    case cmd_history:
                    case cmd_swapped:
                    case cmd_email:
                    {
                        unsigned days = params.isItem(2) ? atoi(params.item(2)) : 0; // for history or swapped
                        switch (cmd)
                        {
                            case cmd_history:
                                swapNodeHistory(clusterName, days, NULL);
                                break;
                            case cmd_swapped:
                                swappedList(clusterName, days, NULL);
                                break;
                            case cmd_email:
                            {
                                bool sendSwapped = false;
                                bool sendHistory = false;
                                if (params.isItem(2))
                                {
                                    if (strieq("swapped", params.item(2)))
                                        sendSwapped = true;
                                    else if (strieq("history", params.item(2)))
                                        sendHistory = true;
                                }
                                emailSwap(clusterName, NULL, true, sendSwapped, sendHistory);
                                break;
                            }
                        }
                        break;
                    }
                    case cmd_reset:
                    case cmd_resetspares:
                    {
                        StringBuffer response;
                        if (!resetClusterGroup(clusterName, "ThorCluster", cmd==cmd_resetspares, response))
                        {
                            WARNLOG("%s", response.str());
                            ret = 3;
                        }
                        break;
                    }
                    case cmd_addspares:
                    case cmd_removespares:
                    {
                        SocketEndpointArray allEps;
                        unsigned p=2;
                        do
                        {
                            const char *ipOrRange = params.item(p);
                            SocketEndpointArray epa;
                            epa.fromText(ipOrRange, 0);
                            ForEachItemIn(e, epa)
                                allEps.append(epa.item(e));
                            p++;
                        }
                        while (p<params.ordinality());
                        StringBuffer response;
                        bool res;
                        if (cmd == cmd_addspares)
                            res = addClusterSpares(clusterName, "ThorCluster", allEps, response);
                        else
                            res = removeClusterSpares(clusterName, "ThorCluster", allEps, response);
                        if (!res)
                        {
                            WARNLOG("%s", response.str());
                            ret = 3;
                        }
                        break;
                    }
                    case cmd_resethistory:
                    {
                        Owned<IRemoteConnection> conn = querySDS().connect("/SwapNode", myProcessSession(), RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
                        if (conn)
                        {
                            StringBuffer groupName;
                            getClusterGroupName(*options, groupName);
                            VStringBuffer xpath("Thor[@group=\"%s\"]", groupName.str());
                            if (conn->queryRoot()->removeProp(xpath.str()))
                                PROGLOG("SwapNode info for cluster %s removed", clusterName.get());
                            else
                                PROGLOG("SwapNode info for cluster %s not found", clusterName.get());
                        }
                        break;
                    }
                }
            }
        }
        UseSysLogForOperatorMessages(false);
    }
    catch (IException *e) {
        EXCLOG(e,"SWAPNODE");
        e->Release();
        ret = -1;
    }

    ExitModuleObjects();
    return ret;
}
Пример #5
0
 virtual void handle(offset_t bytesRead) { PROGLOG("Read %" I64F "d bytes from old index", bytesRead); }
Пример #6
0
void TransferServer::deserializeAction(MemoryBuffer & msg, unsigned action)
{
    SocketEndpoint ep;
    ep.deserialize(msg);
    if (!ep.isLocal())
    {
        StringBuffer host, expected;
        queryHostIP().getIpText(host);
        ep.getIpText(expected);
        throwError2(DFTERR_WrongComputer, expected.str(), host.str());
    }

    srcFormat.deserialize(msg);
    tgtFormat.deserialize(msg);
    msg.read(calcInputCRC);
    msg.read(calcOutputCRC);
    deserialize(partition, msg);
    msg.read(numParallelSlaves);
    msg.read(updateFrequency);
    msg.read(replicate);
    msg.read(mirror);
    msg.read(isSafeMode);

    srand((unsigned)get_cycles_now());
    int adjust = fastRand() % updateFrequency - (updateFrequency/2);
    lastTick = msTick() + adjust;

    StringBuffer localFilename;
    if (action == FTactionpull)
    {
        partition.item(0).outputName.getPath(localFilename);
        LOG(MCdebugProgress, unknownJob, "Process Pull Command: %s", localFilename.str());
    }
    else
    {
        partition.item(0).inputName.getPath(localFilename);
        LOG(MCdebugProgress, unknownJob, "Process Push Command: %s", localFilename.str());
    }
    LOG(MCdebugProgress, unknownJob, "Num Parallel Slaves=%d Adjust=%d/%d", numParallelSlaves, adjust, updateFrequency);
    LOG(MCdebugProgress, unknownJob, "replicate(%d) mirror(%d) safe(%d) incrc(%d) outcrc(%d)", replicate, mirror, isSafeMode, calcInputCRC, calcOutputCRC);

    displayPartition(partition);

    unsigned numProgress;
    msg.read(numProgress);
    for (unsigned i = 0; i < numProgress; i++)
    {
        OutputProgress & next = *new OutputProgress;
        next.deserializeCore(msg);
        progress.append(next);
    }
    if (msg.remaining())
        msg.read(throttleNicSpeed);
    if (msg.remaining())
        msg.read(compressedInput).read(compressOutput);
    if (msg.remaining())
        msg.read(copyCompressed);
    if (msg.remaining())
        msg.read(transferBufferSize);
    if (msg.remaining()) 
        msg.read(encryptKey).read(decryptKey);
    if (msg.remaining())
    {
        srcFormat.deserializeExtra(msg, 1);
        tgtFormat.deserializeExtra(msg, 1);
    }

    ForEachItemIn(i1, progress)
        progress.item(i1).deserializeExtra(msg, 1);

    if (msg.remaining())
        msg.read(fileUmask);

    LOG(MCdebugProgress, unknownJob, "throttle(%d), transferBufferSize(%d)", throttleNicSpeed, transferBufferSize);
    PROGLOG("compressedInput(%d), compressedOutput(%d), copyCompressed(%d)", compressedInput?1:0, compressOutput?1:0, copyCompressed?1:0);
    PROGLOG("encrypt(%d), decrypt(%d)", encryptKey.isEmpty()?0:1, decryptKey.isEmpty()?0:1);
    if (fileUmask != -1)
        PROGLOG("umask(0%o)", fileUmask);
    else
        PROGLOG("umask(default)");

    //---Finished deserializing ---
    displayProgress(progress);

    totalLengthRead = 0;
    totalLengthToRead = 0;
    ForEachItemIn(idx, partition)
        totalLengthToRead += partition.item(idx).inputLength;
}
Пример #7
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;
}
Пример #8
0
int LdapUtils::getServerInfo(const char* ldapserver, int ldapport, StringBuffer& domainDN, LdapServerType& stype, const char* domainname)
{
    LdapServerType deducedSType = LDAPSERVER_UNKNOWN;
    LDAP* ld = LdapInit("ldap", ldapserver, ldapport, 636);
    if(ld == NULL)
    {
        ERRLOG("ldap init error");
        return false;
    }

    int err = LdapSimpleBind(ld, NULL, NULL);
    if(err != LDAP_SUCCESS)
    {
        DBGLOG("ldap anonymous bind error (%d) - %s", err, ldap_err2string(err));

        // for new versions of openldap, version 2.2.*
        if(err == LDAP_PROTOCOL_ERROR)
            DBGLOG("If you're trying to connect to an OpenLdap server, make sure you have \"allow bind_v2\" enabled in slapd.conf");

        return err;
    }

    LDAPMessage* msg = NULL;
    char* attrs[] = {"namingContexts", NULL};
    TIMEVAL timeOut = {LDAPTIMEOUT,0};
    err = ldap_search_ext_s(ld, NULL, LDAP_SCOPE_BASE, "objectClass=*", attrs, false, NULL, NULL, &timeOut, LDAP_NO_LIMIT, &msg);
    if(err != LDAP_SUCCESS)
    {
        DBGLOG("ldap_search_ext_s error: %s", ldap_err2string( err ));
        if (msg)
            ldap_msgfree(msg);
        return err;
    }
    LDAPMessage* entry = ldap_first_entry(ld, msg);
    if(entry != NULL)
    {
        CLDAPGetValuesLenWrapper vals(ld, entry, "namingContexts");
        if(vals.hasValues())
        {
            int i = 0;
            const char* curdn;
            StringBuffer onedn;
            while((curdn = vals.queryCharValue(i)) != NULL)
            {
                if(*curdn != '\0' && (strncmp(curdn, "dc=", 3) == 0 || strncmp(curdn, "DC=", 3) == 0) && strstr(curdn,"DC=ForestDnsZones")==0 && strstr(curdn,"DC=DomainDnsZones")==0 )
                {
                    if(domainDN.length() == 0)
                    {
                        StringBuffer curdomain;
                        getName(curdn, curdomain);
                        if(onedn.length() == 0)
                        {
                            DBGLOG("Queried '%s', selected basedn '%s'",curdn, curdomain.str());
                            onedn.append(curdomain.str());
                        }
                        else
                            DBGLOG("Ignoring %s", curdn);
                        if(!domainname || !*domainname || stricmp(curdomain.str(), domainname) == 0)
                            domainDN.append(curdn);
                    }
                }
                else if(*curdn != '\0' && strcmp(curdn, "o=NetscapeRoot") == 0)
                {
                    PROGLOG("Deduced LDAP Server Type 'iPlanet'");
                    deducedSType = IPLANET;
                }
                i++;
            }

            if(domainDN.length() == 0)
                domainDN.append(onedn.str());

            if (deducedSType == LDAPSERVER_UNKNOWN)
            {
                if(i <= 1)
                {
                    PROGLOG("Deduced LDAP Server Type 'OpenLDAP'");
                    deducedSType = OPEN_LDAP;
                }
                else
                {
                    PROGLOG("Deduced LDAP Server Type 'Active Directory'");
                    deducedSType = ACTIVE_DIRECTORY;
                }
            }
        }
    }
    ldap_msgfree(msg);
    LDAP_UNBIND(ld);

    if (stype == LDAPSERVER_UNKNOWN)
        stype = deducedSType;
    else if (deducedSType != stype)
        WARNLOG("Ignoring deduced LDAP Server Type, does not match config LDAPServerType");

    return err;
}
Пример #9
0
unsigned applyNodes(const char *grpip, ApplyMode mode, unsigned ver, bool isdali, bool quiet)
{
    SocketEndpointArray eps;
    if (isdali&&(stricmp(grpip,"all")==0)) {
        Owned<IRemoteConnection> conn = querySDS().connect("/Environment/Software", myProcessSession(), RTM_LOCK_READ, SDS_CONNECT_TIMEOUT);
        if (!conn) 
            return 0;
        IPropertyTree* root = conn->queryRoot();
        Owned<IPropertyTreeIterator> clusters= root->getElements("ThorCluster");
        unsigned ret = 0;
        if (clusters->first()) {
            do {
                IPropertyTree &cluster = clusters->query();
                ret += applyNodes(cluster.queryProp("@name"),mode,ver,true,quiet);
            } while (clusters->next());
        }
        return ret;
    }
    SocketEndpointArray result;
    StringAttrArray resultstr;
    if (!isdali||!getCluster(grpip,eps)) {
        SocketEndpoint ep(grpip);
        if (ep.isNull()) {
            ERRLOG("%s is not a group name or ip",grpip);
            return 0;
        }
        if (ep.port==0)
            ep.port = getDaliServixPort();
        eps.append(ep);
    }
    PointerIArrayOf<ISocket> sockets;
    unsigned to=10*1000;
    unsigned n=eps.ordinality();    // use approx log scale (timeout is long but only for failure situation)
    while (n>1) {
        n/=2;
        to+=10*1000;
    }
    if (!quiet&&(n>1))
        PROGLOG("Scanning %s...",grpip);
    multiConnect(eps,sockets,to);
    CriticalSection sect;
    class casyncfor: public CAsyncFor
    {
        SocketEndpointArray &eps;
        PointerIArrayOf<ISocket> &sockets;
        ApplyMode mode;
        unsigned ver;
        SocketEndpointArray &result;
        StringAttrArray &resultstr;
        CriticalSection &sect;
    public:
        casyncfor(ApplyMode _mode, unsigned _ver,SocketEndpointArray &_eps,PointerIArrayOf<ISocket> &_sockets,SocketEndpointArray &_result, StringAttrArray &_resultstr,CriticalSection &_sect) 
            : eps(_eps), sockets(_sockets), result(_result), resultstr(_resultstr), sect(_sect)
        { 
            mode = _mode;
            ver = _ver;
        }
        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()));
        }
    } afor(mode,ver,eps,sockets,result,resultstr,sect);
    afor.For(eps.ordinality(), 10, false, true);
    if (result.ordinality()==0)
        return 0;
    switch (mode) {
    case AMstopver: 
    case AMcheckver: 
    case AMcheckvermajor: 
        if (!quiet) {
            StringBuffer epstr;
            ForEachItemIn(i,result) {
                result.item(i).getUrlStr(epstr.clear());
                StringAttrItem &attr = resultstr.item(i);
                if (attr.text.length()==0) 
                    ERRLOG("%s: %s not running DAFILESRV",grpip,epstr.str());
                else 
                    ERRLOG("%s: %s %s running DAFILESRV version %s",grpip,(mode==AMstopver)?"was":"is",epstr.str(),attr.text.get());
            }
            unsigned numok = eps.ordinality()-result.ordinality();
            if (mode==AMcheckvermajor)
                PROGLOG("%s: %d node%s running version %.1f of DAFILESRV",grpip,numok,(numok!=1)?"s":"",((double)FILESRV_VERSION)/10.0);
            else {
                StringBuffer vs;
                const char *v = remoteServerVersionString();
                while (*v&&(*v!='-'))
                    vs.append(*(v++));
                PROGLOG("%s: %d node%s running version %s of DAFILESRV",grpip,numok,(numok!=1)?"s":"",vs.str());
            }
        }
Пример #10
0
    void processMessage(CMessageBuffer &mb)
    {
        ICoven &coven=queryCoven();
        SessionId id;
        int fn;
        mb.read(fn);
        switch (fn) {
        case MSR_REGISTER_PROCESS_SESSION: {
                acceptConnections.wait();
                acceptConnections.signal();
                Owned<INode> node(deserializeINode(mb));
                Owned<INode> servernode(deserializeINode(mb));  // hopefully me, but not if forwarded
                int role=0;
                if (mb.length()-mb.getPos()>=sizeof(role)) { // a capability block present
                    mb.read(role);
                    if (!manager.authorizeConnection(role,false)) {
                        SocketEndpoint sender = mb.getSender();
                        mb.clear();
                        coven.reply(mb);
                        MilliSleep(100+getRandom()%1000); // Causes client to 'work' for a short time.
                        Owned<INode> node = createINode(sender);
                        coven.disconnect(node);
                        break;
                    }
#ifdef _DEBUG
                    StringBuffer eps;
                    PROGLOG("Connection to %s authorized",mb.getSender().getUrlStr(eps).str());
#endif
                }
                
                IGroup *covengrp;
                id = manager.registerClientProcess(node.get(),covengrp,(DaliClientRole)role);
                mb.clear().append(id);
                if (covengrp->rank(servernode)==RANK_NULL) { // must have been redirected
                    covengrp->Release(); // no good, so just use one we know about (may use something more sophisticated later)
                    INode *na = servernode.get();
                    covengrp = createIGroup(1, &na);
                }
                covengrp->serialize(mb);
                covengrp->Release();
                coven.reply(mb);
            }
            break;
        case MSR_SECONDARY_REGISTER_PROCESS_SESSION: {
                mb.read(id);
                Owned<INode> node (deserializeINode(mb));
                int role;
                mb.read(role);
                manager.addProcessSession(id,node.get(),(DaliClientRole)role);
                mb.clear();
                coven.reply(mb);
            }
            break;
        case MSR_REGISTER_SESSION: {
                SecurityToken tok;
                SessionId parentid;
                mb.read(tok).read(parentid);
                SessionId id = manager.registerSession(tok,parentid);
                mb.clear().append(id);
                coven.reply(mb);
            }
            break;
        case MSR_SECONDARY_REGISTER_SESSION: {
                mb.read(id);
                manager.addSession(id);
                mb.clear();
                coven.reply(mb);
            }
            break;
        case MSR_LOOKUP_PROCESS_SESSION: {
                // looks up from node or from id
                Owned<INode> node (deserializeINode(mb));
                if (node->endpoint().isNull()&&(mb.length()-mb.getPos()>=sizeof(id))) {
                    mb.read(id);
                    INode *n = manager.getProcessSessionNode(id);
                    if (n)
                        node.setown(n);
                    node->serialize(mb.clear());
                }
                else {
                    id = manager.lookupProcessSession(node.get());
                    mb.clear().append(id);
                }
                coven.reply(mb);
            }
            break;
        case MSR_STOP_SESSION: {
                SessionId sessid;
                bool failed;
                mb.read(sessid).read(failed);
                manager.stopSession(sessid,failed);
                mb.clear();
                coven.reply(mb);
            }
            break;
        case MSR_LOOKUP_LDAP_PERMISSIONS: {
                StringAttr key;
                StringAttr obj;
                Owned<IUserDescriptor> udesc=createUserDescriptor();
                StringAttr username;
                StringAttr passwordenc;
                mb.read(key).read(obj);
                udesc->deserialize(mb);
#ifndef _NO_DALIUSER_STACKTRACE
                //following debug code to be removed
                StringBuffer sb;
                udesc->getUserName(sb);
                if (0==sb.length())
                {
                    DBGLOG("UNEXPECTED USER (NULL) in dasess.cpp CSessionRequestServer::processMessage() line %d", __LINE__);
                }
#endif
                unsigned auditflags = 0;
                if (mb.length()-mb.getPos()>=sizeof(auditflags))
                    mb.read(auditflags);
                int err = 0;
                int ret=manager.getPermissionsLDAP(key,obj,udesc,auditflags,&err);
                mb.clear().append(ret);
                if (err)
                    mb.append(err);
                coven.reply(mb);
            }
            break;
        case MSR_CLEAR_PERMISSIONS_CACHE: {
                Owned<IUserDescriptor> udesc=createUserDescriptor();
                udesc->deserialize(mb);
                bool ok = manager.clearPermissionsCache(udesc);
                mb.append(ok);
                coven.reply(mb);
            }
            break;
        }
    }
Пример #11
0
int init_main(int argc, char* argv[])
{
    InitModuleObjects();

    Owned<IProperties> inputs = createProperties(true);

    bool interactive = false;

    for (int i = 1; i < argc; i++)
    {
        if (stricmp(argv[i], "-?")==0 || stricmp(argv[i], "-h")==0 || stricmp(argv[i], "-help")==0
             || stricmp(argv[i], "/?")==0 || stricmp(argv[i], "/h")==0)
             usage();
        else if(stricmp(argv[i], "interactive") == 0)
            interactive = true;
        else if (strchr(argv[i],'='))
        {
            inputs->loadProp(argv[i]);
        }
        else
        {
            fprintf(stderr, "Unknown option: %s", argv[i]);
            return 0;
        }
    }

    int result = -1;

#ifdef _WIN32 
    if (!interactive)
        ::SetErrorMode(SEM_NOGPFAULTERRORBOX|SEM_FAILCRITICALERRORS);
#endif

    SET_ESP_SIGNAL_HANDLER(SIGPIPE, brokenpipe_handler);

    bool SEHMappingEnabled = false;

    CEspAbortHandler abortHandler;

    Owned<IFile> sentinelFile = createSentinelTarget();
    removeSentinelFile(sentinelFile);

    Owned<CEspConfig> config;
    Owned<CEspServer> server;
    try
    {
        const char* cfgfile = NULL;
        const char* procname = NULL;
        if(inputs.get())
        {
            if(inputs->hasProp("config"))
                cfgfile = inputs->queryProp("config");
            if(inputs->hasProp("process"))
                procname = inputs->queryProp("process");
        }
        if(!cfgfile || !*cfgfile)
            cfgfile = "esp.xml";

        Owned<IPropertyTree> envpt= createPTreeFromXMLFile(cfgfile, ipt_caseInsensitive);
        Owned<IPropertyTree> procpt = NULL;
        if (envpt)
        {
            envpt->addProp("@config", cfgfile);
            StringBuffer xpath;
            if (procname==NULL || strcmp(procname, ".")==0)
                xpath.appendf("Software/EspProcess[1]");
            else
                xpath.appendf("Software/EspProcess[@name=\"%s\"]", procname);

            DBGLOG("Using ESP configuration section [%s]", xpath.str());
            procpt.set(envpt->queryPropTree(xpath.str()));
            if (!procpt)
                throw MakeStringException(-1, "Config section [%s] not found", xpath.str());
        }
        else
            throw MakeStringException(-1, "Failed to load config file %s", cfgfile);

        StringBuffer logdir;
        if(procpt->hasProp("@name"))
        {
            StringBuffer espNameStr;
            procpt->getProp("@name", espNameStr);
            if (!getConfigurationDirectory(envpt->queryPropTree("Software/Directories"), "log", "esp", espNameStr.str(), logdir))
            {
                logdir.clear();
            }
        }

        const char* build_ver = BUILD_TAG;
        setBuildVersion(build_ver);

        const char* build_level = BUILD_LEVEL;
        setBuildLevel(build_level);

        if(logdir.length() == 0)
        {
            if(procpt->hasProp("@logDir"))
                procpt->getProp("@logDir", logdir);
        }
        if(logdir.length() == 0)
            logdir.append(".");
        if(stricmp(logdir.str(), ".") != 0)
        {
            recursiveCreateDirectory(logdir.str());
        }
        if(logdir.charAt(logdir.length() - 1) != PATHSEPCHAR)
            logdir.append(PATHSEPCHAR);
        
        openEspLogFile(logdir.str(), procpt.get());

        StringBuffer componentfilesDir;
        if(procpt->hasProp("@componentfilesDir"))
            procpt->getProp("@componentfilesDir", componentfilesDir);
        if(componentfilesDir.length() > 0 && strcmp(componentfilesDir.str(), ".") != 0)
        {
            DBGLOG("componentfiles are under %s", componentfilesDir.str());
            setCFD(componentfilesDir.str());
        }

        StringBuffer sehsetting;
        procpt->getProp("@enableSEHMapping", sehsetting);
        if(!interactive && sehsetting.length() > 0 && (stricmp(sehsetting.str(), "true") == 0 || stricmp(sehsetting.str(), "1") == 0))
            SEHMappingEnabled = true;
        if(SEHMappingEnabled)
            EnableSEHtoExceptionMapping();

        CEspConfig* cfg = new CEspConfig(inputs.getLink(), envpt.getLink(), procpt.getLink(), false);
        if(cfg && cfg->isValid())
        {
            config.setown(cfg);
            abortHandler.setConfig(cfg);
        }
    }
    catch(IException* e)
    {
        StringBuffer description;
        ERRLOG("ESP Unhandled IException (%d -- %s)", e->errorCode(), e->errorMessage(description).str());
        e->Release();
        return -1;
    }
    catch (...)
    {
        ERRLOG("ESP Unhandled General Exception.");
        return -1;
    }

    if (config && config->isValid())
    {
        PROGLOG("Configuring Esp Platform...");

        try
        {
            CEspServer *srv = new CEspServer(config);
            if(SEHMappingEnabled)
                srv->setSavedSEHHandler(SEHMappingEnabled);
            server.setown(srv);
            abortHandler.setServer(srv);
            setEspContainer(server.get());

            config->loadAll();
            config->bindServer(*server.get(), *server.get()); 
            
        }
        catch(IException* e)
        {
            StringBuffer description;
            ERRLOG("ESP Unhandled IException (%d -- %s)", e->errorCode(), e->errorMessage(description).str());
            e->Release();
            return -1;
        }
        catch (...)
        {
            ERRLOG("ESP Unhandled General Exception.");
            return -1;
        }

        writeSentinelFile(sentinelFile);
        result = work_main(*config, *server.get());
    }
    else
    {
        ERRLOG("!!! Unable to load ESP configuration.");
    }
    
    return result;
}
Пример #12
0
 virtual void log(int level, const char *msg)
 {
     PROGLOG("%s", msg);
 }
Пример #13
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 maxThreads = DEFAULT_THREADLIMIT;
    unsigned maxThreadsDelayMs = DEFAULT_THREADLIMITDELAYMS;
    unsigned maxAsyncCopy = DEFAULT_ASYNCCOPYMAX;
    unsigned parallelRequestLimit = DEFAULT_STDCMD_PARALLELREQUESTLIMIT;
    unsigned throttleDelayMs = DEFAULT_STDCMD_THROTTLEDELAYMS;
    unsigned throttleCPULimit = DEFAULT_STDCMD_THROTTLECPULIMIT;
    unsigned throttleQueueLimit = DEFAULT_STDCMD_THROTTLEQUEUELIMIT;
    unsigned parallelSlowRequestLimit = DEFAULT_SLOWCMD_PARALLELREQUESTLIMIT;
    unsigned throttleSlowDelayMs = DEFAULT_SLOWCMD_THROTTLEDELAYMS;
    unsigned throttleSlowCPULimit = DEFAULT_SLOWCMD_THROTTLECPULIMIT;
    unsigned throttleSlowQueueLimit = DEFAULT_SLOWCMD_THROTTLEQUEUELIMIT;

    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:

            maxThreads = daFileSrv->getPropInt("@maxThreads", DEFAULT_THREADLIMIT);
            maxThreadsDelayMs = daFileSrv->getPropInt("@maxThreadsDelayMs", DEFAULT_THREADLIMITDELAYMS);
            maxAsyncCopy = daFileSrv->getPropInt("@maxAsyncCopy", DEFAULT_ASYNCCOPYMAX);

            parallelRequestLimit = daFileSrv->getPropInt("@parallelRequestLimit", DEFAULT_STDCMD_PARALLELREQUESTLIMIT);
            throttleDelayMs = daFileSrv->getPropInt("@throttleDelayMs", DEFAULT_STDCMD_THROTTLEDELAYMS);
            throttleCPULimit = daFileSrv->getPropInt("@throttleCPULimit", DEFAULT_STDCMD_THROTTLECPULIMIT);
            throttleQueueLimit = daFileSrv->getPropInt("@throttleQueueLimit", DEFAULT_STDCMD_THROTTLEQUEUELIMIT);

            parallelSlowRequestLimit = daFileSrv->getPropInt("@parallelSlowRequestLimit", DEFAULT_SLOWCMD_PARALLELREQUESTLIMIT);
            throttleSlowDelayMs = daFileSrv->getPropInt("@throttleSlowDelayMs", DEFAULT_SLOWCMD_THROTTLEDELAYMS);
            throttleSlowCPULimit = daFileSrv->getPropInt("@throttleSlowCPULimit", DEFAULT_SLOWCMD_THROTTLECPULIMIT);
            throttleSlowQueueLimit = daFileSrv->getPropInt("@throttleSlowQueueLimit", DEFAULT_SLOWCMD_THROTTLEQUEUELIMIT);

            // 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)
            {
                maxThreads = dafileSrvInstance->getPropInt("@maxThreads", maxThreads);
                maxThreadsDelayMs = dafileSrvInstance->getPropInt("@maxThreadsDelayMs", maxThreadsDelayMs);
                maxAsyncCopy = dafileSrvInstance->getPropInt("@maxAsyncCopy", maxAsyncCopy);

                parallelRequestLimit = dafileSrvInstance->getPropInt("@parallelRequestLimit", parallelRequestLimit);
                throttleDelayMs = dafileSrvInstance->getPropInt("@throttleDelayMs", throttleDelayMs);
                throttleCPULimit = dafileSrvInstance->getPropInt("@throttleCPULimit", throttleCPULimit);
                throttleQueueLimit = dafileSrvInstance->getPropInt("@throttleQueueLimit", throttleQueueLimit);

                parallelSlowRequestLimit = dafileSrvInstance->getPropInt("@parallelSlowRequestLimit", parallelSlowRequestLimit);
                throttleSlowDelayMs = dafileSrvInstance->getPropInt("@throttleSlowDelayMs", throttleSlowDelayMs);
                throttleSlowCPULimit = dafileSrvInstance->getPropInt("@throttleSlowCPULimit", throttleSlowCPULimit);
                throttleSlowQueueLimit = dafileSrvInstance->getPropInt("@throttleSlowQueueLimit", throttleSlowQueueLimit);
            }
        }
    }

    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;
            unsigned parallelRequestLimit;
            unsigned throttleDelayMs;
            unsigned throttleCPULimit;

            
            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, unsigned _parallelRequestLimit, unsigned _throttleDelayMs, unsigned _throttleCPULimit)
                : listenep(_listenep),useSSL(_useSSL),pollthread(this),
                  parallelRequestLimit(_parallelRequestLimit), throttleDelayMs(_throttleDelayMs), throttleCPULimit(_throttleCPULimit)
            {
                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(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;
            }
        } service(listenep, useSSL, parallelRequestLimit, throttleDelayMs, throttleCPULimit);
        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");
    server.setown(createRemoteFileServer(maxThreads, maxThreadsDelayMs, maxAsyncCopy));
    server->setThrottle(ThrottleStd, parallelRequestLimit, throttleDelayMs, throttleCPULimit);
    server->setThrottle(ThrottleSlow, parallelSlowRequestLimit, throttleSlowDelayMs, throttleSlowCPULimit);
    class CPerfHook : public CSimpleInterfaceOf<IPerfMonHook>
    {
    public:
        virtual void processPerfStats(unsigned processorUsage, unsigned memoryUsage, unsigned memoryTotal, unsigned __int64 fistDiskUsage, unsigned __int64 firstDiskTotal, unsigned __int64 secondDiskUsage, unsigned __int64 secondDiskTotal, unsigned threadCount)
        {
        }
        virtual StringBuffer &extraLogging(StringBuffer &extra)
        {
            return server->getStats(extra.newline(), true);
        }
        virtual void log(int level, const char *msg)
        {
            PROGLOG("%s", msg);
        }
    } perfHook;
    startPerformanceMonitor(10*60*1000, PerfMonStandard, &perfHook);
    writeSentinelFile(sentinelFile);
    try
    {
        server->run(listenep, useSSL);
    }
    catch (IException *e)
    {
        EXCLOG(e,"DAFILESRV");
        e->Release();
    }
    stopPerformanceMonitor();
    if (server)
        server->stop();
    server.clear();
    PROGLOG("Stopped Dali File Server");

    return 0;
}
Пример #14
0
int main( int argc, char *argv[] )
{
    int res=0;
    if (argc < 3)
    {
        printf
            ("frunssh <nodelistfile> \"command\" [options] \n"
            "    options: -i:<identity-file> \n"
            "             -u:<user> \n"
            "             -n:<number_of_threads>\n"
            "             -t:<connect-timeout-secs>\n"
            "             -a:<connect-attempts>\n"
            "             -d:<working_directory>\n"
            "             -s                -- strict, must match known_hosts\n"
            "             -b                -- background\n"
            "             -pw:<password>    -- INSECURE: requires pssh (NB identity file preferred)\n"
            "             -pe:<password>    -- INSECURE: as -pw except encrypted password\n"
            "             -pl               -- use plink (on windows)\n"
            "             -v                -- verbose, lists commands run\n"
            "             -d                -- dry run (for testing, enables verbose)\n"
            );
        return 255;
    }


    InitModuleObjects();

#ifndef __64BIT__
    // Restrict stack sizes on 32-bit systems
    Thread::setDefaultStackSize(0x10000);   // NB under windows requires linker setting (/stack:)
#endif

    try  {
        StringBuffer logname;
        splitFilename(argv[0], NULL, NULL, &logname, NULL);

        Owned<IComponentLogFileCreator> lf = createComponentLogFileCreator("frunssh");
        lf->setCreateAliasFile(false);
        lf->setMsgFields(MSGFIELD_prefix);
        lf->beginLogging();

        Owned<IFRunSSH> runssh = createFRunSSH();
        runssh->init(argc,argv);
        runssh->exec();
        const StringArray & strArray = runssh->getReplyText();
        const UnsignedArray & unsArray = runssh->getReply();
        for(unsigned i = 0;i < unsArray.ordinality();i++) {
            StringBuffer buf = strArray.item(i);
            // strip newlines off end of string buf
            if (buf.length() && (buf.charAt(buf.length()-1)) == '\n') {
                buf.setLength(buf.length()-1);
                buf.clip();
            }
            if (buf.length())
                PROGLOG("%d: ssh(%d): %s",i+1,unsArray.item(i),buf.str());
        }
    }
    catch(IException *e)
    {
        EXCLOG(e,"frunssh");
        e->Release();
        res=255;
    }
    releaseAtoms();
    return res;
}
Пример #15
0
static bool physicalPartCopy(IFile *from,const char *tofile, Owned<IException> &exc, StringBuffer *tmpname)
{
    StringBuffer tmpnamestr;
    if (!tmpname)
        tmpname = &tmpnamestr;
    tmpname->append(tofile).append("__");
    size32_t l = tmpname->length();
    genUUID(*tmpname,true); // true for windows
    StringAttr uuid(tmpname->str()+l);
    tmpname->append(".tmp");
    RemoteFilename tmpfn;
    tmpfn.setRemotePath(tmpname->str());
    //unsigned lastpc;
#ifdef LOG_PART_COPY
    PROGLOG("start physicalPartCopy(%s,%s)",from->queryFilename(),tmpname->str());
#endif
    try {
        recursiveCreateDirectoryForFile(tmpname->str());
        while(!asyncCopyFileSection(
                uuid,
                from,
                tmpfn,
                (offset_t)-1, // creates file
                0,
                (offset_t)-1, // all file
                NULL,
                PHYSICAL_COPY_POLL_TIME)) {
            // Abort check TBD
        }
    }
    catch (IException *e) {
        EXCLOG(e,"SingleFileCopy: File copy error");
        if (exc)
            exc.setown(e);
        else
            e->Release();
    }
    Owned<IFile> f = createIFile(tmpfn);
    if (!exc.get()&&(tmpnamestr.length()!=0)) {
        try {
#ifdef LOG_PART_COPY
            PROGLOG("physicalPartCopy rename(%s,%s)",tmpname->str(),pathTail(tofile));
#endif
            f->rename(pathTail(tofile));
        }
        catch (IException *e) {
            EXCLOG(e,"SingleFileCopy: File rename error");
            if (exc)
                exc.setown(e);
            else
                e->Release();
        }
    }
    if (exc.get()) {
        try {
            f->remove();
        }
        catch (IException *e) {
            // ignore
            e->Release();
        }
    }
#ifdef LOG_PART_COPY
    PROGLOG("done physicalPartCopy %s",(exc.get()==NULL)?"OK":"Failed");
#endif
    return exc.get()==NULL;
}
Пример #16
0
    void processMessage(CMessageBuffer &mb)
    {
        ICoven &coven=queryCoven();
        MemoryBuffer params;
        params.swapWith(mb);
        int fn;
        params.read(fn);
        switch (fn) {
        case MDR_GET_VALUE: {
                StringAttr id;
                StringBuffer buf;
                params.read(id);
                if (0 == stricmp(id,"threads")) {
                    mb.append(getThreadList(buf).str());
                }
                else if (0 == stricmp(id, "mpqueue")) {
                    mb.append(getReceiveQueueDetails(buf).str());
                }
                else if (0 == stricmp(id, "locks")) { // Legacy - newer diag clients should use querySDS().getLocks() directly
                    Owned<ILockInfoCollection> lockInfoCollection = querySDS().getLocks();
                    mb.append(lockInfoCollection->toString(buf).str());
                }
                else if (0 == stricmp(id, "sdsstats")) { // Legacy - newer diag clients should use querySDS().getUsageStats() directly
                    mb.append(querySDS().getUsageStats(buf).str());
                }
                else if (0 == stricmp(id, "connections")) { // Legacy - newer diag clients should use querySDS().getConnections() directly
                    mb.append(querySDS().getConnections(buf).str());
                }
                else if (0 == stricmp(id, "sdssubscribers")) { // Legacy - newer diag clients should use querySDS().getSubscribers() directly
                    mb.append(querySDS().getSubscribers(buf).str());
                }
                else if (0 == stricmp(id, "clients")) {
                    mb.append(querySessionManager().getClientProcessList(buf).str());
                }
                else if (0 == stricmp(id, "subscriptions")) {
                    mb.append(getSubscriptionList(buf).str());
                }
                else if (0 == stricmp(id, "mpverify")) {
                    queryWorldCommunicator().verifyAll(buf);
                    mb.append(buf.str());
                }
                else if (0 == stricmp(id, "extconsistency")) {
                    mb.append(querySDS().getExternalReport(buf).str());
                }
                else if (0 == stricmp(id, "build")) {
                    mb.append("$Id: dadiags.cpp 62376 2011-02-04 21:59:58Z sort $");
                }
                else if (0 == stricmp(id, "sdsfetch")) {
                    StringAttr branchpath;
                    params.read(branchpath);
                    Linked<IPropertyTree> sroot = querySDSServer().lockStoreRead();
                    try { sroot->queryPropTree(branchpath)->serialize(mb); }
                    catch (...) { querySDSServer().unlockStoreRead(); throw; }
                    querySDSServer().unlockStoreRead();
                }
                else if (0 == stricmp(id, "perf")) {
                    getSystemTraceInfo(buf,PerfMonStandard);
                    mb.append(buf.str());
                }
                else if (0 == stricmp(id, "sdssize")) {
                    StringAttr branchpath;
                    params.read(branchpath);
                    Linked<IPropertyTree> sroot = querySDSServer().lockStoreRead();
                    StringBuffer sbuf;
                    try { 
                        toXML(sroot->queryPropTree(branchpath),sbuf); 
                        DBGLOG("sdssize '%s' = %d",branchpath.get(),sbuf.length());
                    }
                    catch (...) { 
                        querySDSServer().unlockStoreRead(); 
                        throw; 
                    }
                    querySDSServer().unlockStoreRead();
                    mb.append(sbuf.length());
                }
                else if (0 == stricmp(id, "disconnect")) {
                    StringAttr client;
                    params.read(client);
                    SocketEndpoint ep(client);
                    PROGLOG("Dalidiag request to close client connection: %s", client.get());
                    Owned<INode> node = createINode(ep);
                    queryCoven().disconnect(node);
                }
                else if (0 == stricmp(id, "unlock")) {
                    __int64 connectionId;
                    bool disconnect;
                    params.read(connectionId);
                    params.read(disconnect);
                    PROGLOG("Dalidiag request to unlock connection id: %" I64F "x", connectionId);
                    StringBuffer connectionInfo;
                    bool success = querySDSServer().unlock(connectionId, disconnect, connectionInfo);
                    mb.append(success);
                    if (success)
                        mb.append(connectionInfo);
                }
                else if (0 == stricmp(id, "save")) {
                    PROGLOG("Dalidiag requests SDS save");
                    querySDSServer().saveRequest();
                }
                else if (0 == stricmp(id, "settracetransactions")) {
                    PROGLOG("Dalidiag requests Trace Transactions");
                    if(traceAllTransactions(true))
                        mb.append("OK - no change");
                    else
                        mb.append("OK - transaction tracing enabled");
                }
                else if (0 == stricmp(id, "cleartracetransactions")) {
                    PROGLOG("Dalidiag requests Trace Transactions stopped");
                    if(traceAllTransactions(false))
                        mb.append("OK - transaction tracing disabled");
                    else
                        mb.append("OK - no change");
                }
                else if (0 == stricmp(id, "setldapflags")) {
                    unsigned f;
                    params.read(f);
                    PROGLOG("Dalidiag requests setldapflags %d",f);
                    querySessionManager().setLDAPflags(f);

                }
                else if (0 == stricmp(id, "getldapflags")) {
                    unsigned f=querySessionManager().getLDAPflags();;
                    mb.append(f);
                }
                else if (0 == stricmp(id, "setsdsdebug")) {
                    PROGLOG("Dalidiag setsdsdebug");
                    unsigned p;
                    params.read(p);
                    StringArray arr;
                    while (p--)
                    {
                        StringAttr s;
                        params.read(s);
                        arr.append(s);
                    }
                    StringBuffer reply;
                    bool success = querySDSServer().setSDSDebug(arr, reply);
                    mb.append(success).append(reply);
                }
                else
                    mb.append(StringBuffer("UNKNOWN OPTION: ").append(id).str());
            }
            break;
        }
        coven.reply(mb);            
    }   
Пример #17
0
inline void traceWait(const char *name, T &sem,unsigned interval=60*1000)
{
    while (!sem.wait(interval))
        PROGLOG("Waiting for %s",name);
}
Пример #18
0
int CMCastRecvServer::run()
{
    SocketEndpoint ackEp(broadcastRoot);
    ackEp.port = ackPort;
    StringBuffer s;
    ackEp.getIpText(s);
    ackSock.setown(ISocket::udp_connect(ackEp.port, s.str()));
    ackSock->set_send_buffer_size(UDP_SEND_SIZE);

    StringBuffer ipStr;
    mcastEp.getIpText(ipStr);
    sock.setown(ISocket::multicast_create(mcastEp.port, ipStr.str()));
    sock->set_receive_buffer_size(UDP_RECV_SIZE);
    SocketEndpoint ep(ipStr.str());
    sock->join_multicast_group(ep);

    
    MemoryBuffer mbAck;
    MCAckPacketHeader *ackPacket = (MCAckPacketHeader *)mbAck.reserveTruncate(MC_ACK_PACKET_SIZE);

    ackPacket->node = groupMember;

    LOG(MCdebugProgress(10), unknownJob, "Running as client %d connected to server %s", groupMember, broadcastRoot.get());

    unsigned *nackList = (unsigned *)(((byte *)ackPacket)+sizeof(MCAckPacketHeader));
    const unsigned *nackUpper = (unsigned *)((byte *)ackPacket)+MC_ACK_PACKET_SIZE-sizeof(unsigned);

    Owned<CDataPacket> dataPacket = new CDataPacket();

    CTimeMon logTm(10000), logTmCons(5000), logTmPoll(5000), logTmOld(5000), logTmNoRecv(5000);
    loop
    {
        try
        {
            unsigned startTime = msTick();
            loop
            {
                try
                {
                    size32_t szRead;
                    sock->read(dataPacket->header, sizeof(MCPacketHeader), MC_PACKET_SIZE, szRead, 5000);
                    break;
                }
                catch (IException *e)
                {
                    if (JSOCKERR_timeout_expired != e->errorCode())
                        throw;
                    else e->Release();
                    LOG(MCdebugProgress(1), unknownJob, "Waiting on packet read socket (waited=%d)", msTick()-startTime);
                }
            }
            if (stopped) break;
            if (MCPacket_Stop == dataPacket->header->cmd)
            {
                stopped = true;
                break;
            }
            ackPacket->tag = dataPacket->header->tag;
            ackPacket->jobId = dataPacket->header->jobId;

            if (oldJobIds.find(dataPacket->header->jobId))
            {
                if (MCPacket_Poll == dataPacket->header->cmd)
                {
                    ackPacket->ackDone = true;
                    MilliSleep(MAX_POLL_REPLY_DELAY/(groupMember+1));
                    ackSock->write(ackPacket, sizeof(MCAckPacketHeader));
                }

                if (tracingPeriod && logTmOld.timedout())
                {
                    LOG(MCdebugProgress(1), unknownJob, "Old job polled=%s", MCPacket_Poll == dataPacket->header->cmd?"true":"false");
                    logTmOld.reset(tracingPeriod);
                }
            }
            else
            {
                CMCastReceiver *receiver = getReceiver(dataPacket->header->tag);
                if (receiver)
                {
                    if (MCPacket_Poll == dataPacket->header->cmd)
                    {
                        size32_t sz;
                        bool res = receiver->buildNack(ackPacket, sz, dataPacket->header->total);
                        MilliSleep(MAX_POLL_REPLY_DELAY/(groupMember+1));
                        ackSock->write(ackPacket, sz);
                        if (tracingPeriod && logTmPoll.timedout())
                        {
                            LOG(MCdebugProgress(1), unknownJob, "Send nack back sz=%d, res=%s, done=%s", sz, res?"true":"false", ackPacket->ackDone?"true":"false");
                            logTmPoll.reset(tracingPeriod);
                        }
                    }
                    else
                    {
                        unsigned total = dataPacket->header->total;
                        bool done;
                        if (receiver->packetReceived(*dataPacket, done)) // if true, packet consumed
                        {
                            unsigned level;
                            if (tracingPeriod && logTmCons.timedout())
                            {
                                level = 1;
                                logTmCons.reset(5000);
                            } else level = 110;
                            LOG(MCdebugProgress(level), unknownJob, "Pkt %d taken by receiver", dataPacket->header->id);
                            if (done)
                            {
                                LOG(MCdebugProgress(10), unknownJob, "Client (tag=%x, jobId=%d) received all %d packets", dataPacket->header->tag, dataPacket->header->jobId, dataPacket->header->total);
                                oldJobIds.replace(* new CUIntValue(dataPacket->header->jobId));
                            }
                            // JCSMORE should use packet pool.
                            // init new packet
                            dataPacket.setown(new CDataPacket());
                        }
                        else if (tracingPeriod && logTm.timedout())
                        {
                            LOG(MCdebugProgress(150), unknownJob, "throwing away packet %d", dataPacket->header->id);
                            logTm.reset(tracingPeriod);
                        }

                        if (!done)
                        {
                            size32_t sz;
                            if (receiver->buildNack(ackPacket, sz, total))
                                ackSock->write(ackPacket, sz);
                        }
                    }
                }
                else if (tracingPeriod && logTmNoRecv.timedout())
                {
                    LOG(MCdebugProgress(1), unknownJob, "No Receiver tag=%d", dataPacket->header->tag);
                    logTmNoRecv.reset(tracingPeriod);
                }
            }
        }
        catch (IException *e)
        {
            pexception("Client Exception",e);
            break;
        }
    }

    PROGLOG("Receive server stopping, aborting receivers");
    {
        CriticalBlock b(receiversCrit);
        SuperHashIteratorOf<CMCastReceiver> iter(receivers);
        ForEach (iter)
            iter.query().stop();
    }

    return 0;
}
Пример #19
0
void setFtSlaveLogDir(const char *dir)
{
    PROGLOG("ftslave log dir set to %s",dir);
    ftslavelogdir.set(dir);
}
Пример #20
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
            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;
}