// @(#)root/proofd:$Id$ // Author: G. Ganis Jan 2008 /************************************************************************* * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_XrdProofdProofServMgr #define ROOT_XrdProofdProofServMgr ////////////////////////////////////////////////////////////////////////// // // // XrdProofdProofServMgr // // // // Author: G. Ganis, CERN, 2008 // // // // Class managing proofserv sessions manager. // // // ////////////////////////////////////////////////////////////////////////// #include #include #include "XpdSysPthread.h" #include "XrdOuc/XrdOucHash.hh" #include "XrdOuc/XrdOucString.hh" #include "XrdProofdConfig.h" #include "XrdProofdProofServ.h" class XrdOucStream; class XrdProtocol_Config; class XrdProofdManager; class XrdROOTMgr; class XrdSysLogger; #define PSMMAXCNTS 3 #define PSMCNTOK(t) (t >= 0 && t < PSMMAXCNTS) // Security handle typedef int (*XrdSecCredsSaver_t)(XrdSecCredentials *, const char *fn, const XrdProofUI &ui); // Aux structure for session set env inputs typedef struct { XrdProofdProofServ *fPS; int fLogLevel; XrdOucString fCfg; XrdOucString fLogFile; XrdOucString fSessionTag; XrdOucString fTopSessionTag; XrdOucString fSessionDir; XrdOucString fWrkDir; bool fOld; } ProofServEnv_t; class XpdClientSessions { public: XrdSysRecMutex fMutex; XrdProofdClient *fClient; std::list fProofServs; XpdClientSessions(XrdProofdClient *c = 0) : fClient(c) { } int operator==(const XpdClientSessions c) { return (c.fClient == fClient) ? 1 : 0; } }; class XrdProofSessionInfo { public: time_t fLastAccess; int fPid; int fID; int fSrvType; int fStatus; XrdOucString fUser; XrdOucString fGroup; XrdOucString fUnixPath; XrdOucString fTag; XrdOucString fAlias; XrdOucString fLogFile; XrdOucString fOrdinal; XrdOucString fUserEnvs; XrdOucString fROOTTag; XrdOucString fAdminPath; int fSrvProtVers; XrdProofSessionInfo(XrdProofdClient *c, XrdProofdProofServ *s); XrdProofSessionInfo(const char *file) { ReadFromFile(file); } void FillProofServ(XrdProofdProofServ &s, XrdROOTMgr *rmgr); int ReadFromFile(const char *file); void Reset(); int SaveToFile(const char *file); }; class XpdEnv { public: XrdOucString fName; XrdOucString fEnv; XrdOucString fUsers; XrdOucString fGroups; int fSvnMin; int fSvnMax; int fVerMin; int fVerMax; XpdEnv(const char *n, const char *env, const char *usr = 0, const char *grp = 0, int smi = -1, int smx = -1, int vmi = -1, int vmx = -1) : fName(n), fEnv(env), fUsers(usr), fGroups(grp), fSvnMin(smi), fSvnMax(smx), fVerMin(vmi), fVerMax(vmx) { } void Reset(const char *n, const char *env, const char *usr = 0, const char *grp = 0, int smi = -1, int smx = -1, int vmi = -1, int vmx = -1) { fName = n; fEnv = env; fUsers = usr; fGroups = grp; fSvnMin = smi; fSvnMax = smx; fVerMin = vmi; fVerMax = vmx; } int Matches(const char *usr, const char *grp, int svn = -1, int ver = -1); void Print(const char *what); static int ToVersCode(int ver, bool hex = 0); }; class XrdProofdProofServMgr : public XrdProofdConfig { XrdProofdManager *fMgr; XrdSysRecMutex fMutex; XrdSysRecMutex fRecoverMutex; XrdSysRecMutex fEnvsMutex; // Protect usage of envs lists XrdSysSemWait fForkSem; // To serialize fork requests XrdSysSemWait fProcessSem; // To serialize process requests XrdSysLogger *fLogger; // Error logger int fInternalWait; // Timeout on replies from proofsrv XrdOucString fProofPlugin; // String identifying the plug-in to be loaded, e.g. "condor:" std::list fProofServEnvs; // Additional envs to be exported before proofserv std::list fProofServRCs; // Additional rcs to be passed to proofserv int fShutdownOpt; // What to do when a client disconnects int fShutdownDelay; // Delay shutdown by this (if enabled) XrdProofdPipe fPipe; int fCheckFrequency; int fTerminationTimeOut; int fVerifyTimeOut; int fReconnectTime; int fReconnectTimeOut; int fRecoverTimeOut; int fRecoverDeadline; bool fCheckLost; bool fUseFork; // If true, use fork to start proofserv XrdOucString fParentExecs; // List of possible 'proofserv' parent names int fCounters[PSMMAXCNTS]; // Internal counters (see enum PSMCounters) int fCurrentSessions; // Number of sessions (top masters) unsigned int fSeqSessionN; // Sequential number for sessions created by this instance int fNextSessionsCheck; // Time of next sessions check XrdOucString fActiAdminPath; // Active sessions admin area XrdOucString fTermAdminPath; // Terminated sessions admin area XrdOucHash fSessions; // List of sessions std::list fActiveSessions; // List of active sessions (non-idle) std::list *fRecoverClients; // List of client potentially recovering std::map fDestroyTimes; // Tracks destroyed sessions XrdSecCredsSaver_t fCredsSaver; // If defined, function to be used to save the credentials int DoDirectiveProofServMgr(char *, XrdOucStream *, bool); int DoDirectivePutEnv(char *, XrdOucStream *, bool); int DoDirectivePutRc(char *, XrdOucStream *, bool); int DoDirectiveShutdown(char *, XrdOucStream *, bool); void ExtractEnv(char *, XrdOucStream *, XrdOucString &users, XrdOucString &groups, XrdOucString &rcval, XrdOucString &rcnam, int &smi, int &smx, int &vmi, int &vmx, bool &hex); void FillEnvList(std::list *el, const char *nam, const char *val, const char *usrs = 0, const char *grps = 0, int smi = -1, int smx = -1, int vmi = -1, int vmx = -1, bool hex = 0); unsigned int GetSeqSessionN() { XrdSysMutexHelper mhp(fMutex); return ++fSeqSessionN; } int CreateAdminPath(XrdProofdProofServ *xps, XrdProofdProtocol *p, int pid, XrdOucString &emsg); int CreateSockPath(XrdProofdProofServ *xps, XrdProofdProtocol *p, unsigned int seq, XrdOucString &emsg); int CreateFork(XrdProofdProtocol *p); int CreateProofServEnvFile(XrdProofdProtocol *p, void *input, const char *envfn, const char *rcfn); int CreateProofServRootRc(XrdProofdProtocol *p, void *input, const char *rcfn); int SetupProtocol(XrdNetPeer &peerpsrv, XrdProofdProofServ *xps, XrdOucString &e); void ParseCreateBuffer(XrdProofdProtocol *p, XrdProofdProofServ *xps, XrdOucString &tag, XrdOucString &ord, XrdOucString &cffile, XrdOucString &uenvs, int &intwait); XrdProofdProofServ *PrepareProofServ(XrdProofdProtocol *p, XrdProofdResponse *r, unsigned short &sid); int PrepareSessionRecovering(); int ResolveSession(const char *fpid); void SendErrLog(const char *errlog, XrdProofdResponse *r); // Session Admin path management int AddSession(XrdProofdProtocol *p, XrdProofdProofServ *s); bool IsSessionSocket(const char *fpid); int RmSession(const char *fpid); int TouchSession(const char *fpid, const char *path = 0); int VerifySession(const char *fpid, int to = -1, const char *path = 0); void ResolveKeywords(XrdOucString &s, ProofServEnv_t *in); int SetUserOwnerships(XrdProofdProtocol *p, const char *ord, const char *stag); public: XrdProofdProofServMgr(XrdProofdManager *mgr, XrdProtocol_Config *pi, XrdSysError *e); virtual ~XrdProofdProofServMgr() { } enum PSMProtocol { kSessionRemoval = 0, kClientDisconnect = 1, kCleanSessions = 2, kProcessReq = 3, kChgSessionSt = 4} ; enum PSMCounters { kCreateCnt = 0, kCleanSessionsCnt = 1, kProcessCnt = 2} ; XrdSysRecMutex *Mutex() { return &fMutex; } int Config(bool rcf = 0); int DoDirective(XrdProofdDirective *d, char *val, XrdOucStream *cfg, bool rcf); void RegisterDirectives(); int CheckFrequency() const { return fCheckFrequency; } int InternalWait() const { return fInternalWait; } int VerifyTimeOut() const { return fVerifyTimeOut; } inline int NextSessionsCheck() { XrdSysMutexHelper mhp(fMutex); return fNextSessionsCheck; } inline void SetNextSessionsCheck(int t) { XrdSysMutexHelper mhp(fMutex); fNextSessionsCheck = t; } bool IsReconnecting(); bool IsClientRecovering(const char *usr, const char *grp, int &deadline); void SetReconnectTime(bool on = 1); bool Alive(XrdProofdProtocol *p); int Process(XrdProofdProtocol *p); XrdSysSemWait *ProcessSem() { return &fProcessSem; } int AcceptPeer(XrdProofdProofServ *xps, int to, XrdOucString &e); int Attach(XrdProofdProtocol *p); int Create(XrdProofdProtocol *p); int Destroy(XrdProofdProtocol *p); int Detach(XrdProofdProtocol *p); int Recover(XpdClientSessions *cl); void UpdateCounter(int t, int n) { if (PSMCNTOK(t)) { XrdSysMutexHelper mhp(fMutex); fCounters[t] += n; if (fCounters[t] < 0) fCounters[t] = 0;} } int CheckCounter(int t) { int cnt = -1; if (PSMCNTOK(t)) { XrdSysMutexHelper mhp(fMutex); cnt = fCounters[t];} return cnt; } void BroadcastClusterInfo(); int BroadcastPriorities(); int CurrentSessions(bool recalculate = 0); void DisconnectFromProofServ(int pid); std::list *ActiveSessions() { return &fActiveSessions; } XrdProofdProofServ *GetActiveSession(int pid); int CleanupProofServ(bool all = 0, const char *usr = 0); void FormFileNameInSessionDir(XrdProofdProtocol *p, XrdProofdProofServ *xps, const char *sessiondir, const char *extension, XrdOucString &outfn); void GetTagDirs(int opt, XrdProofdProtocol *p, XrdProofdProofServ *xps, XrdOucString &sesstag, XrdOucString &topsesstag, XrdOucString &sessiondir, XrdOucString &sesswrkdir); int SetProofServEnv(XrdProofdProtocol *p, void *in); int SetProofServEnvOld(XrdProofdProtocol *p, void *in); int SetUserEnvironment(XrdProofdProtocol *p); static int SetProofServEnv(XrdProofdManager *m, XrdROOT *r); inline XrdProofdPipe *Pipe() { return &fPipe; } // Checks run periodically by the cron job int DeleteFromSessions(const char *pid); int MvSession(const char *fpid); int CheckActiveSessions(bool verify = 1); int CheckTerminatedSessions(); int CleanClientSessions(const char *usr, int srvtype); int CleanupLostProofServ(); int RecoverActiveSessions(); }; class XpdSrvMgrCreateCnt { public: int fType; XrdProofdProofServMgr *fMgr; XpdSrvMgrCreateCnt(XrdProofdProofServMgr *m, int t) : fType(t), fMgr(m) { if (m && PSMCNTOK(t)) m->UpdateCounter(t,1); } ~XpdSrvMgrCreateCnt() { if (fMgr && PSMCNTOK(fType)) fMgr->UpdateCounter(fType,-1); } }; class XpdSrvMgrCreateGuard { public: int *fCnt; XpdSrvMgrCreateGuard(int *c = 0) { Set(c); } ~XpdSrvMgrCreateGuard() { if (fCnt) (*fCnt)--; } void Set(int *c) { fCnt = c; if (fCnt) (*fCnt)++;} }; #endif