00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 const char *XrdCmsManagerCVSID = "$Id: XrdCmsManager.cc 35287 2010-09-14 21:19:35Z ganis $";
00016
00017 #include <stdlib.h>
00018 #include <unistd.h>
00019 #include <netinet/in.h>
00020 #include <sys/types.h>
00021
00022 #include "XrdCms/XrdCmsConfig.hh"
00023 #include "XrdCms/XrdCmsManager.hh"
00024 #include "XrdCms/XrdCmsNode.hh"
00025 #include "XrdCms/XrdCmsRouting.hh"
00026 #include "XrdCms/XrdCmsTrace.hh"
00027
00028 #include "XrdSys/XrdSysTimer.hh"
00029
00030 using namespace XrdCms;
00031
00032
00033
00034
00035
00036 XrdCmsManager XrdCms::Manager;
00037
00038
00039
00040
00041
00042 XrdCmsManager::XrdCmsManager()
00043 {
00044 memset((void *)MastTab, 0, sizeof(MastTab));
00045 MTHi = -1;
00046 }
00047
00048
00049
00050
00051
00052 XrdCmsNode *XrdCmsManager::Add(XrdLink *lp, int Lvl)
00053 {
00054 EPNAME("Add")
00055 XrdCmsNode *nP;
00056 int i;
00057
00058
00059
00060 MTMutex.Lock();
00061 for (i = 0; i < MTMax; i++) if (!MastTab[i]) break;
00062
00063
00064
00065 if (i >= MTMax)
00066 {MTMutex.UnLock();
00067 Say.Emsg("Manager", "Login to", lp->Name(), "failed; too many managers");
00068 return 0;
00069 }
00070
00071
00072
00073 lp->setID("manager",0);
00074 if (!(nP = new XrdCmsNode(lp, 0, 0, Lvl, i)))
00075 {Say.Emsg("Manager", "Unable to obtain node object."); return 0;}
00076
00077
00078
00079 MastTab[i] = nP;
00080 if (i > MTHi) MTHi = i;
00081 nP->isOffline = 0;
00082 nP->isNoStage = 0;
00083 nP->isSuspend = 0;
00084 nP->isBound = 1;
00085 nP->isConn = 1;
00086 nP->isMan = (Config.asManager() ? 1 : 0);
00087 MTMutex.UnLock();
00088
00089
00090
00091 DEBUG(nP->Name() <<" to manager config; id=" <<i);
00092 return nP;
00093 }
00094
00095
00096
00097
00098
00099 void XrdCmsManager::Inform(const char *What, const char *Data, int Dlen)
00100 {
00101 EPNAME("Inform");
00102 XrdCmsNode *nP;
00103 int i;
00104
00105
00106
00107 MTMutex.Lock();
00108
00109
00110
00111 for (i = 0; i <= MTHi; i++)
00112 {if ((nP=MastTab[i]) && !nP->isOffline)
00113 {nP->Lock();
00114 MTMutex.UnLock();
00115 DEBUG(nP->Name() <<" " <<What);
00116 nP->Send(Data, Dlen);
00117 nP->UnLock();
00118 MTMutex.Lock();
00119 }
00120 }
00121 MTMutex.UnLock();
00122 }
00123
00124
00125
00126 void XrdCmsManager::Inform(const char *What, struct iovec *vP, int vN, int vT)
00127 {
00128 EPNAME("Inform");
00129 int i;
00130 XrdCmsNode *nP;
00131
00132
00133
00134 MTMutex.Lock();
00135
00136
00137
00138 for (i = 0; i <= MTHi; i++)
00139 {if ((nP=MastTab[i]) && !nP->isOffline)
00140 {nP->Lock();
00141 MTMutex.UnLock();
00142 DEBUG(nP->Name() <<" " <<What);
00143 nP->Send(vP, vN, vT);
00144 nP->UnLock();
00145 MTMutex.Lock();
00146 }
00147 }
00148 MTMutex.UnLock();
00149 }
00150
00151
00152
00153 void XrdCmsManager::Inform(XrdCms::CmsReqCode rCode, int rMod,
00154 const char *Arg, int Alen)
00155 {
00156 CmsRRHdr Hdr = {0, rCode, rMod, htons(static_cast<unsigned short>(Alen))};
00157 struct iovec ioV[2] = {{(char *)&Hdr, sizeof(Hdr)},{(char *)Arg, Alen}};
00158
00159 Inform(Router.getName((int)rCode), ioV, (Arg ? 2 : 1), Alen+sizeof(Hdr));
00160 }
00161
00162
00163
00164 void XrdCmsManager::Inform(CmsRRHdr &Hdr, const char *Arg, int Alen)
00165 {
00166 struct iovec ioV[2] = {{(char *)&Hdr, sizeof(Hdr)},{(char *)Arg, Alen}};
00167
00168 Hdr.datalen = htons(static_cast<unsigned short>(Alen));
00169
00170 Inform(Router.getName(Hdr.rrCode), ioV, (Arg ? 2 : 1), Alen+sizeof(Hdr));
00171 }
00172
00173
00174
00175
00176
00177 void XrdCmsManager::Remove(XrdCmsNode *nP, const char *reason)
00178 {
00179 EPNAME("Remove")
00180 int sinst, sent = nP->ID(sinst);
00181
00182
00183
00184 MTMutex.Lock();
00185
00186
00187
00188 if (!(nP == MastTab[sent]))
00189 {MTMutex.UnLock();
00190 DEBUG("manager " <<sent <<'.' <<sinst <<" failed.");
00191 return;
00192 }
00193
00194
00195
00196 MastTab[sent] = 0;
00197 nP->isOffline = 1;
00198 DEBUG("completed " <<nP->Name() <<" manager " <<sent <<'.' <<sinst);
00199
00200
00201
00202 if (sent == MTHi) while(MTHi >= 0 && !MastTab[MTHi]) MTHi--;
00203 MTMutex.UnLock();
00204
00205
00206
00207 if (reason) Say.Emsg("Manager", nP->Ident, "removed;", reason);
00208 }
00209
00210
00211
00212
00213
00214 void XrdCmsManager::Reset()
00215 {
00216 EPNAME("Reset");
00217 static CmsStatusRequest myState = {{0, kYR_status,
00218 CmsStatusRequest::kYR_Reset, 0}};
00219 static const int szReqst = sizeof(CmsStatusRequest);
00220 XrdCmsNode *nP;
00221 int i;
00222
00223
00224
00225 MTMutex.Lock();
00226
00227
00228
00229 for (i = 0; i <= MTHi; i++)
00230 {if ((nP=MastTab[i]) && !nP->isOffline && nP->isKnown)
00231 {nP->Lock();
00232 nP->isKnown = 0;
00233 MTMutex.UnLock();
00234 DEBUG("sent to " <<nP->Name());
00235 nP->Send((char *)&myState, szReqst);
00236 nP->UnLock();
00237 MTMutex.Lock();
00238 }
00239 }
00240 MTMutex.UnLock();
00241 }