bool FastMultipleConnect(unsigned n,HRPCmodule **modules,bool *done,int timeout) { CriticalSection sect; IPointerArrayOf<ISocket> sockets; SocketEndpointArray eps; unsigned i; for (i=0;i<n;i++) { SocketEndpoint ep; if (!getTcpTarget(modules[i]->queryTransport(),ep)) return false; eps.append(ep); done[i] = false; } multiConnect(eps,sockets,60*1000); assertex(n==sockets.ordinality()); bool ret = true; for (i=0;i<n;i++) { ISocket *sock = sockets.item(i); if (sock) { modules[i]->AttachConnect(sock,true); done[i] = true; } else { StringBuffer epstr; eps.item(i).getUrlStr(epstr); //ERRLOG("Failed to connect to %s",epstr.str()); ret = false; } } return ret; }
bool CWsDfuXRefEx::onDFUXRefUnusedFiles(IEspContext &context, IEspDFUXRefUnusedFilesRequest &req, IEspDFUXRefUnusedFilesResponse &resp) { const char *process = req.getProcessCluster(); if (!process || !*process) throw MakeStringExceptionDirect(ECLWATCH_INVALID_INPUT, "process cluster, not specified."); SocketEndpointArray servers; getRoxieProcessServers(process, servers); if (!servers.length()) throw MakeStringExceptionDirect(ECLWATCH_INVALID_CLUSTER_INFO, "process cluster, not found."); Owned<ISocket> sock = ISocket::connect_timeout(servers.item(0), 5000); Owned<IPropertyTree> controlXrefInfo = sendRoxieControlQuery(sock, "<control:getQueryXrefInfo/>", 5000); if (!controlXrefInfo) throw MakeStringExceptionDirect(ECLWATCH_INTERNAL_ERROR, "roxie cluster, not responding."); MapStringTo<bool> usedFileMap; Owned<IPropertyTreeIterator> roxieFiles = controlXrefInfo->getElements("//File"); ForEach(*roxieFiles) addLfnToUsedFileMap(usedFileMap, roxieFiles->query().queryProp("@name")); if (req.getCheckPackageMaps()) addUsedFilesFromActivePackageMaps(usedFileMap, process); StringArray unusedFiles; findUnusedFilesInDFS(unusedFiles, process, usedFileMap); resp.setUnusedFileCount(unusedFiles.length()); resp.setUnusedFiles(unusedFiles); return true; }
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; }
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())); }
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 § 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()); } }