Index: src/XrdProofdProofServMgr.cxx =================================================================== --- src/XrdProofdProofServMgr.cxx (revision 44700) +++ src/XrdProofdProofServMgr.cxx (working copy) @@ -144,21 +144,7 @@ TRACE(REQ, "kSessionRemoval: session: "<DisconnectFromProofServ(pid); - TRACE(DBG, "quick check of active sessions"); - // Quick check of active sessions in case of disconnections - mgr->CheckActiveSessions(0); + // obsolete } else if (msg.Type() == XrdProofdProofServMgr::kCleanSessions) { // Request for cleanup all sessions of a client (or all clients) XpdSrvMgrCreateCnt cnt(mgr, XrdProofdProofServMgr::kCleanSessionsCnt); Index: src/XrdProofdProtocol.cxx =================================================================== --- src/XrdProofdProtocol.cxx (revision 44700) +++ src/XrdProofdProtocol.cxx (working copy) @@ -736,15 +736,35 @@ if (pmgr) { - if (!Internal()) { - // Signal the client manager that a client has just gone - if (fgMgr && fgMgr->ClientMgr()) { - TRACE(HDBG, "fAdminPath: "<ClientMgr()->Pipe()->Post(XrdProofdClientMgr::kClientDisconnect, buf.c_str()); + TRACE(REQ,"External disconnection of protocol associated with pid "<ResetClientSlot(fCID); + if(fgMgr && fgMgr->SessionMgr()) { + XrdSysMutexHelper mhp(fgMgr->SessionMgr()->Mutex()); + + fgMgr->SessionMgr()->DisconnectFromProofServ(fPid); + if(pmgr->Running()) { + TRACE(REQ,"Non-idle proofserv processes attached to this client, setting reconnect time"); + fgMgr->SessionMgr()->SetReconnectTime(true); + } + fgMgr->SessionMgr()->CheckActiveSessions(0); + } + else { + TRACE(XERR,"No XrdProofdMgr ("<SessionMgr()<<")") } } else { @@ -753,11 +773,16 @@ // of proxy servers and to notify the attached clients. // Tell the session manager that this session has gone if (fgMgr && fgMgr->SessionMgr()) { + XrdSysMutexHelper mhp(fgMgr->SessionMgr()->Mutex()); TRACE(HDBG, "fAdminPath: "<SessionMgr()->Pipe()->Post(XrdProofdProofServMgr::kSessionRemoval, buf.c_str()); + fgMgr->SessionMgr()->DeleteFromSessions(buf.c_str()); + // Move the entry to the terminated sessions area + fgMgr->SessionMgr()->MvSession(buf.c_str()); } + else { + TRACE(XERR,"No XrdProofdMgr ("<SessionMgr()<<")") + } } } Index: src/XrdProofdClient.cxx =================================================================== --- src/XrdProofdClient.cxx (revision 44700) +++ src/XrdProofdClient.cxx (working copy) @@ -34,7 +34,7 @@ //__________________________________________________________________________ XrdProofdClient::XrdProofdClient(XrdProofUI ui, bool master, bool changeown, - XrdSysError *, const char *adminpath) + XrdSysError *, const char *adminpath, int rtime) : fSandbox(ui, master, changeown) { // Constructor @@ -48,6 +48,7 @@ fAskedToTouch = 0; fChangeOwn = changeown; fLauncher = 0; + fReconnectTimeOut = rtime; // Make sure the admin path exists XPDFORM(fAdminPath, "%s/%s.%s", adminpath, ui.fUser.c_str(), ui.fGroup.c_str()); @@ -104,6 +105,11 @@ // Search for free places in the existing vector for (ic = 0; ic < (int)fClients.size() ; ic++) { if (fClients[ic] && !fClients[ic]->IsValid()) { + int rtime = fClients[ic]->ResetTime(); + if ((rtime >= 0) && ((time(0) - rtime) < fReconnectTimeOut)) { + // The session using this cid disconnected too recently, do not reuse yet + continue; + } cid = fClients[ic]; cid->Reset(); break; @@ -388,7 +394,7 @@ //______________________________________________________________________________ XrdProofdProtocol *XrdProofdClient::GetProtocol(int ic) { - // Reset slot at 'ic' + // Return protocol attached to client slot at 'ic' XPDLOC(CMGR, "Client::GetProtocol") TRACE(DBG, "enter: ic: " << ic); @@ -627,6 +633,24 @@ } //______________________________________________________________________________ +bool XrdProofdClient::Running() +{ + // Check status of attached proofservs + + XrdSysMutexHelper mh(fMutex); + + int is = 0; bool running = false; + XrdProofdProofServ *s = 0; + for (is = 0; is < (int) fProofServs.size(); is++) { + if ((s = fProofServs.at(is)) && s->IsValid()) { + if(!running && (s->Status()!=kXPD_idle)) running = true; + } + } + + return running; +} + +//______________________________________________________________________________ void XrdProofdClient::TerminateSessions(int srvtype, XrdProofdProofServ *ref, const char *msg, XrdProofdPipe *pipe, bool changeown) Index: src/XrdProofdClientMgr.cxx =================================================================== --- src/XrdProofdClientMgr.cxx (revision 44700) +++ src/XrdProofdClientMgr.cxx (working copy) @@ -71,7 +71,7 @@ return (void *)0; } XrdProofdProofServMgr *smgr = mc->fSessionMgr; - if (!(mgr)) { + if (!(smgr)) { TRACE(REQ, "undefined session manager: cannot start"); return (void *)0; } @@ -93,45 +93,10 @@ continue; } // Parse type - XrdOucString buf; + //XrdOucString buf; if (msg.Type() == XrdProofdClientMgr::kClientDisconnect) { - // Read admin path and pointer to the client instance - XrdOucString adminpath; - rc = msg.Get(adminpath); - void *cp = 0; - rc = (rc == 0) ? msg.Get(&cp) : rc; - XrdProofdClient *c = (XrdProofdClient *)cp; - int cid = -1; - rc = (rc == 0) ? msg.Get(cid) : rc; - int pid = -1; - rc = (rc == 0) ? msg.Get(pid) : rc; - if (rc != 0) { - TRACE(XERR, "kClientDisconnect: problems parsing message: '"<< - msg.Buf()<<"'; errno: "<<-rc); - continue; - } - TRACE(DBG, "kClientDisconnect: got: '"<ResetClientSlot(cid); - } else { - TRACE(XERR, "kClientDisconnect: problems getting pointer to client instance: "<Pipe()->Post(XrdProofdProofServMgr::kClientDisconnect, buf.c_str()); - TRACE(DBG,"sending to ProofServMgr: "<Client()->AdminPath(), lid.c_str()); - // Check last access time - int rc = 0; + // Create disconnected path + XrdOucString discpath; + XPDFORM(discpath, "%s/%s/disconnected", p->Client()->AdminPath(), lid.c_str()); + + // Check last access time of disconnected if available, otherwise cid bool expired = false; struct stat st; - if ((rc = stat(cidpath.c_str(), &st)) != 0 || - (expired = ((int)(time(0) - st.st_atime) > fReconnectTimeOut))) { + int rc = stat(discpath.c_str(), &st); + if (rc != 0) rc = stat(cidpath.c_str(), &st); + if (rc != 0 || (expired = ((int)(time(0) - st.st_atime) > fReconnectTimeOut))) { if (expired || (rc != 0 && errno != ENOENT)) { // Remove the file cidpath.replace("/cid", ""); @@ -1020,13 +989,6 @@ // during last cycle and it did not do it, so we close // the link xclose = 1; - // This clients looks like disconnected - FILE *fd = fopen(discpath.c_str(), "w"); - if (!fd) { - TRACE(XERR, "unable to create path: " <Link()->Close(); } else { TRACE(XERR, "protocol or link associated with ID "<SrvType() != kXPD_Worker) ? 1 : 0; - c = new XrdProofdClient(ui, full, fMgr->ChangeOwn(), fEDest, fClntAdminPath.c_str()); + c = new XrdProofdClient(ui, full, fMgr->ChangeOwn(), fEDest, fClntAdminPath.c_str(), fReconnectTimeOut); newclient = 1; bool freeclient = 1; if (c && c->IsValid()) { Index: src/XrdProofdProofServ.cxx =================================================================== --- src/XrdProofdProofServ.cxx (revision 44700) +++ src/XrdProofdProofServ.cxx (working copy) @@ -341,7 +341,12 @@ for (i = fClients.begin(); i != fClients.end(); ++i) { if ((*i) && (*i)->P()) { if ((*i)->P()->Pid() == pid || (*i)->P()->Pid() == -1) { + if (fProtocol == (*i)->P()) { + SetProtocol(0); + SetConnection(0); + } (*i)->Reset(); + if (fParent == (*i)) SetParent(0); fNClients--; // Record time of last disconnection if (fNClients <= 0) Index: inc/XrdProofdClient.h =================================================================== --- inc/XrdProofdClient.h (revision 44700) +++ inc/XrdProofdClient.h (working copy) @@ -45,7 +45,7 @@ public: XrdProofdClient(XrdProofUI ui, - bool master, bool changeown, XrdSysError *edest, const char *tmp); + bool master, bool changeown, XrdSysError *edest, const char *tmp, int rtime); virtual ~XrdProofdClient(); @@ -74,6 +74,8 @@ void Broadcast(const char *msg); + bool Running(); + XrdOucString ExportSessions(XrdOucString &emsg, XrdProofdResponse *r = 0); void SkipSessionsCheck(std::list *active, XrdOucString &emsg, XrdProofdResponse *r = 0); @@ -105,6 +107,7 @@ bool fChangeOwn; // TRUE if ownership must be changed where relevant bool fIsValid; // TRUE if the instance is complete bool fAskedToTouch; // TRUE if a touch request has already been sent for this client + int fReconnectTimeOut; // Time given for disconnected clients to reconnect XrdProofUI fUI; // user info XrdROOT *fROOT; // ROOT vers instance to be used for proofserv @@ -133,18 +136,20 @@ XrdProofdProtocol *fP; XrdProofdResponse *fR; unsigned short fSid; + int fResetTime; void SetR() { fR = (fP && fSid > 0) ? fP->Response(fSid) : 0;} public: XrdClientID(XrdProofdProtocol *pt = 0, unsigned short id = 0) - { fP = pt; fSid = id; SetR();} + { fP = pt; fSid = id; SetR(); fResetTime = -1; } ~XrdClientID() { } XrdProofdClient *C() const { return fP->Client(); } bool IsValid() const { return (fP != 0); } XrdProofdProtocol *P() const { return fP; } XrdProofdResponse *R() const { return fR; } - void Reset() { fP = 0; fSid = 0; SetR(); } + void Reset() { fP = 0; fSid = 0; SetR(); fResetTime = time(0); } + int ResetTime() { return fResetTime; } void SetP(XrdProofdProtocol *p) { fP = p; SetR();} void SetSid(unsigned short sid) { fSid = sid; SetR();} unsigned short Sid() const { return fSid; }