#ifndef __CMS_NODE__H #define __CMS_NODE__H /******************************************************************************/ /* */ /* X r d C m s N o d e . h h */ /* */ /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include #include #include #include #include "Xrd/XrdLink.hh" #include "XrdCms/XrdCmsTypes.hh" #include "XrdCms/XrdCmsRRQ.hh" #include "XrdNet/XrdNetIF.hh" #include "XrdNet/XrdNetAddr.hh" #include "XrdSys/XrdSysPthread.hh" class XrdCmsBaseFR; class XrdCmsBaseFS; class XrdCmsClustID; class XrdCmsDrop; class XrdCmsManager; class XrdCmsPrepArgs; class XrdCmsRRData; class XrdCmsSelected; class XrdOucProg; class XrdCmsNode { friend class XrdCmsCluster; public: char *Ident; // -> role hostname char hasNet; //0 Network selection mask char isBad; //1 Set on an event that makes it unselectable char isOffline; //2 Set when a link failure occurs char isRW; //3 Set when node can write or stage data char isNoStage; //4 Set upon a nostage event char isMan; //5 Set when node acts as manager char isPeer; //6 Set when node acts as peer manager char isBound; //7 Set when node is in the configuration char isKnown; //0 Set when we have recieved a "state" char isConn; //1 Set when node is network connected char isGone; //2 Set when node must be deleted char isPerm; //3 Set when node is permanently bound char incUL; //4 Set when unlock count nedds to be incremented char RoleID; //5 The converted XrdCmsRole::RoleID char TimeZone; //6 Time zone in +UTC- char TZValid; //7 Time zone has been set static const char isBlisted = 0x01; // in isBad -> Node is black listed static const char isDisabled = 0x02; // in isBad -> Node is disable (internal) static const char isSuspend = 0x04; // in isBad -> Node is suspended via event static const char isDoomed = 0x08; // in isBad -> Node socket must be closed static const char allowsRW = 0x01; // in isRW -> Server allows r/w access static const char allowsSS = 0x02; // in isRW -> Server can stage data unsigned int DiskTotal; // Total disk space in GB int DiskNums; // Number of file systems int DiskMinF; // Minimum MB needed for selection int DiskFree; // Largest free MB int DiskUtil; // Total disk utilization unsigned int ConfigID; // Configuration identifier const char *do_Avail(XrdCmsRRData &Arg); const char *do_Chmod(XrdCmsRRData &Arg); const char *do_Disc(XrdCmsRRData &Arg); const char *do_Gone(XrdCmsRRData &Arg); const char *do_Have(XrdCmsRRData &Arg); const char *do_Load(XrdCmsRRData &Arg); const char *do_Locate(XrdCmsRRData &Arg); static int do_LocFmt(char *buff, XrdCmsSelected *sP, SMask_t pf, SMask_t wf, bool lsall=false, bool lsuniq=false); const char *do_Mkdir(XrdCmsRRData &Arg); const char *do_Mkpath(XrdCmsRRData &Arg); const char *do_Mv(XrdCmsRRData &Arg); const char *do_Ping(XrdCmsRRData &Arg); const char *do_Pong(XrdCmsRRData &Arg); const char *do_PrepAdd(XrdCmsRRData &Arg); const char *do_PrepDel(XrdCmsRRData &Arg); const char *do_Rm(XrdCmsRRData &Arg); const char *do_Rmdir(XrdCmsRRData &Arg); const char *do_Select(XrdCmsRRData &Arg); static int do_SelPrep(XrdCmsPrepArgs &Arg); const char *do_Space(XrdCmsRRData &Arg); const char *do_State(XrdCmsRRData &Arg); static void do_StateDFS(XrdCmsBaseFR *rP, int rc); int do_StateFWD(XrdCmsRRData &Arg); const char *do_StatFS(XrdCmsRRData &Arg); const char *do_Stats(XrdCmsRRData &Arg); const char *do_Status(XrdCmsRRData &Arg); const char *do_Trunc(XrdCmsRRData &Arg); const char *do_Try(XrdCmsRRData &Arg); const char *do_Update(XrdCmsRRData &Arg); const char *do_Usage(XrdCmsRRData &Arg); void Delete(XrdSysMutex &gMutex); void Disc(const char *reason=0, int needLock=1); inline int ID(int &INum) {INum = Instance; return NodeID;} inline int Inst() {return Instance;} bool inDomain() {return netIF.InDomain(&netID);} inline int isNode(SMask_t smask) {return (smask & NodeMask) != 0;} inline int isNode(const XrdNetAddr *addr) // Only for avoid processing! {return netID.Same(addr);} inline int isNode(XrdLink *lp, const char *nid, int port) {if (nid) {if (strcmp(myNID, nid)) return 0; if (*nid == '*') return 1; } return netID.Same(lp->NetAddr()) && port == netIF.Port(); } inline char *Name() {return (myName ? myName : (char *)"?");} inline SMask_t Mask() {return NodeMask;} inline void g2Ref(XrdSysMutex &gMutex) {lkCount++; gMutex.UnLock();} inline void Ref2g(XrdSysMutex &gMutex) {gMutex.Lock(); lkCount--;} inline void g2nLock(XrdSysMutex &gMutex) {lkCount++; // gMutex must be held gMutex.UnLock(); // Safe because lkCount != ulCount nodeMutex.Lock(); // Downgrade to node lock incUL = 1; isLocked = 1; } inline void n2gLock(XrdSysMutex &gMutex) {isLocked = 0; if (incUL) {ulCount++; incUL = 0; if (isGone) nodeMutex.Signal(); } nodeMutex.UnLock(); // Release this node gMutex.Lock(); // Upgade to global mutex } inline void Lock(bool doinc) {if (!doinc) nodeMutex.Lock(); else {lkCount++; // Global lock must be held nodeMutex.Lock(); incUL = 1; } isLocked = 1; } inline void UnLock() {isLocked = 0; if (incUL) {ulCount++; incUL = 0; if (isGone) nodeMutex.Signal(); } nodeMutex.UnLock(); } static void Report_Usage(XrdLink *lp); inline int Send(const char *buff, int blen=0) {return (isOffline ? -1 : Link->Send(buff, blen));} inline int Send(const struct iovec *iov, int iovcnt, int iotot=0) {return (isOffline ? -1 : Link->Send(iov, iovcnt, iotot));} void setManager(XrdCmsManager *mP) {Manager = mP;} void setName(XrdLink *lnkp, const char *theIF, int port); void setShare(int shrval) {if (shrval > 99) Shrem = Shrip = Share = 0; else {Shrem = Share = shrval; Shrip = 100 - shrval;} } int setTZone(int tZone) {TimeZone = tZone & 0x0f; if (tZone & 0x10) TimeZone = -TimeZone; TZValid = (tZone != 0); return TimeZone; } void setVersion(unsigned short vnum) {myVersion = vnum;} inline void setSlot(short rslot) {RSlot = rslot;} inline short getSlot() {return RSlot;} inline void ShowIF() {netIF.Display("=====> ");} void SyncSpace(); XrdCmsNode(XrdLink *lnkp, const char *theIF=0, const char *sid=0, int port=0, int lvl=0, int id=-1); ~XrdCmsNode(); private: static const int fsL2PFail1 = 999991; static const int fsL2PFail2 = 999992; void DeleteWarn(XrdSysMutex &gMutex, unsigned int &lkVal); int fsExec(XrdOucProg *Prog, char *Arg1, char *Arg2=0); const char *fsFail(const char *Who, const char *What, const char *Path, int rc); int getMode(const char *theMode, mode_t &Mode); int getSize(const char *theSize, long long &Size); XrdSysCondVar nodeMutex; unsigned int lkCount; // Only Modified with global lock held unsigned int ulCount; // Only Modified with node lock held XrdLink *Link; XrdNetAddr netID; XrdNetIF netIF; XrdCmsManager *Manager; XrdCmsNode *Next; time_t DropTime; XrdCmsDrop *DropJob; XrdCmsClustID *cidP; SMask_t NodeMask; int NodeID; int Instance; int myLevel; short subsPort; // Subscription port number unsigned short myVersion; char *myCID; char *myNID; char *myName; int myNlen; int logload; int myCost; // Overall cost (determined by location) int myLoad; // Overall load int myMass; // Overall load including space utilization int RefW; // Number of times used for writing int RefTotW; int RefR; // Number of times used for redirection int RefTotR; short RSlot; char isLocked; char Share; // Share of requests for this node (0 -> n/a) char Shrem; // Share of requests left char Shrip; // Share of requests to skip char Rsvd[2]; int Shrin; // Share intervals used // The following fields are used to keep the supervisor's free space value // static XrdSysMutex mlMutex; static int LastFree; }; #endif