#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