36#include <netinet/in.h>
82 {
if (!(First = arP->
Next)) Last = 0;
91 Next=First; First=
this; QPresent.Post();
numinQ++;
100 if (Last) {Last->Next =
this; Last =
this;}
101 else First=Last =
this;
136 bool XrdCmsAdmin::arePost =
false;
140 int XrdCmsAdmin::POnline= 0;
148void *AdminLogin(
void *carg)
155void *AdminMonAds(
void *carg)
161void *AdminMonARE(
void *carg)
166void *AdminSend(
void *carg)
187 {
Say.
Emsg(
"InitAREvents", errno,
"start arevent relay");
202 const char *epname =
"Admin_Login";
203 const char *sMsg[2] = {
"temporary suspend requested by",
204 "long-term suspend requested by"};
210 Stream.Attach(socknum);
214 if ((request = Stream.GetLine()))
215 {
DEBUG(
"initial request: '" <<request <<
"'");
216 if (!(tp = Stream.GetToken()) || strcmp(
"login", tp) || !do_Login())
217 {
Say.
Emsg(epname,
"Invalid admin login sequence");
220 }
else {
Say.
Emsg(epname,
"No admin login specified");
226 while((request = Stream.GetLine()))
227 {
DEBUG(
"received request: '" <<request <<
"'");
228 if ((tp = Stream.GetToken()))
229 {
if (!strcmp(
"resume", tp))
230 {
if ((tp = Stream.GetToken()) && *tp ==
't') sPerm = 0;
234 else if (!strcmp(
"rmdid", tp)) do_RmDid();
235 else if (!strcmp(
"newfn", tp)) do_RmDud();
236 else if (!strcmp(
"perf", tp)) do_Perf();
237 else if (!strcmp(
"PERF", tp)) do_Perf(
true);
238 else if (!strcmp(
"suspend", tp))
239 {
if ((tp = Stream.GetToken()) && *tp ==
't') sPerm = 0;
242 Say.
Emsg(
"Login", sMsg[sPerm], Stype, Sname);
244 else Say.
Emsg(epname,
"invalid admin request,", tp);
250 Say.
Emsg(
"Login", Stype, Sname,
"logged out");
270 const char *epname =
"MonAds";
272 char buff[256], pname[64];
277 Say.
Emsg(epname,
"Monitoring", pname);
282do{sFD = Con2Ads(pname);
284 do {
do {rc =
read(sFD, buff,
sizeof(buff));}
while(rc > 0);
285 }
while(rc < 0 && errno == EINTR);
287 if (rc < 0)
Say.
Emsg(epname, errno,
"maintain contact with", pname);
288 else Say.
Emsg(epname,
"Lost contact with", pname);
303 const char *epname =
"Notes";
309 Stream.Attach(AnoteSock->
Detach());
310 Sname = strdup(
"anon");
314 do {
while((request = Stream.GetLine()))
315 {
DEBUG(
"received notification: '" <<request <<
"'");
316 if ((tp = Stream.GetToken()))
317 {
if (!strcmp(
"gone", tp)) do_RmDid(1);
318 else if (!strcmp(
"rmdid", tp)) do_RmDid(0);
319 else if (!strcmp(
"have", tp)) do_RmDud(1);
320 else if (!strcmp(
"newfn", tp)) do_RmDud(0);
321 else if (!strcmp(
"nostage", tp))
323 Say.
Emsg(
"Notes",
"nostage requested by",Stype,Sname);
325 else if (!strcmp(
"stage", tp))
327 else Say.
Emsg(epname,
"invalid notification,", tp);
330 if ((rc = Stream.LastError()))
break;
331 rc = Stream.Detach(); Stream.Attach(rc);
336 Say.
Emsg(epname, rc,
"accept notification");
346 const char *epname =
"Admin_Relay";
347 static const int HdrSz =
sizeof(
CmsRRHdr);
350 static int curSock = -1;
352 int retc, mySock = -1;
357 if (curSock >= 0)
close(curSock);
358 else if (newSock >= 0) SReady.
Post();
359 if (newSock < 0) curSock = -1;
367 do {
while(mySock < 0)
370 mySock = curSock; curSock = -1;
376 if ((retc =
write(mySock, &arP->
Hdr, HdrSz)) != HdrSz
378 retc = (retc < 0 ? errno : ECANCELED);
380 delete arP; retc = 0;
384 if (retc)
Say.
Emsg(
"AdminRelay", retc,
"relay", arP->
Req);
405 while((evP = areFirst))
406 {
if (evP == areLast) areFirst = areLast = 0;
407 else areFirst = evP->
next;
413 {evType = XrdOssStatEvent::PendAdded;
416 evType = XrdOssStatEvent::FileAdded;
420 evType = XrdOssStatEvent::FileRemoved;
423 (*areFunc)(evP->
text, 0, evType, 0, evP->
text);
424 DEBUG(
"sending managers " <<evWhat <<evP->
text);
444 else Say.
Emsg(
"Send",
"Queue full; ignoring", Req, Data.
Path);
453 const char *epname =
"Start";
460 Say.
Emsg(epname, errno,
"start admin relay");
467 AdminSock->
SockName(dest,
sizeof(dest));
468 Say.
Emsg(epname,
"Waiting for primary server to login via", dest);
471 else if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
475 while(1)
if ((InSock = AdminSock->
Accept()) >= 0)
478 {
Say.
Emsg(epname, errno,
"start admin");
481 }
else Say.
Emsg(epname, errno,
"accept connection");
494 int info[2] = {(int)req, mods};
500 if (areLast) areLast->next = evP;
503 if (arePost) {areSem.Post(); arePost =
false;}
511void XrdCmsAdmin::BegAds()
513 const char *epname =
"BegAds";
519 {
Say.
Emsg(epname,
"Assuming alternate data server is functional.");
521 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
528 Say.
Emsg(epname, errno,
"start alternate data server monitor");
535bool XrdCmsAdmin::CheckVNid(
const char *xNid)
542 {
Say.
Emsg(
"do_Login",
"Warning! No xrootd vnid specified; "
543 "proceeding only with cmsd vnid.");
547 std::string msg(
"xrootd vnid '");
548 msg += xNid; msg +=
"' does not match cmsd vnid '";
550 Say.
Emsg(
"do_Login", msg.c_str());
556 if (xNid)
Say.
Emsg(
"do_Login",
"Warning! xrootd has a vnid but cmsd does "
557 "not; proceeding without a vnid!");
565int XrdCmsAdmin::Con2Ads(
const char *pname)
567 const char *epname =
"Con2Ads";
568 static ClientInitHandShake hsVal = {0, 0, 0, (int)htonl(4), (int)htonl(2012)};
569 static ClientLoginRequest loginReq = {{0, 0},
572 {
'c',
'm',
's',
'd', 0, 0, 0, 0},
575 XrdNetSocket adsSocket;
584 Say.
Emsg(epname, ecode,
"connect to", pname);
592 if (
write(snum, &hsVal,
sizeof(hsVal)) < 0)
593 {
Say.
Emsg(epname, errno,
"send handshake to", pname);
594 close(snum);
continue;
599 if (recv(snum, &hsRsp,
sizeof(hsRsp), MSG_WAITALL) < 0)
600 {
Say.
Emsg(epname, errno,
"recv handshake from", pname);
601 close(snum);
continue;
606 if (
write(snum, &loginReq,
sizeof(loginReq)) < 0)
607 {
Say.
Emsg(epname, errno,
"send login to", pname);
608 close(snum);
continue;
615 Say.
Emsg(epname,
"Logged into", pname);
621 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
626 return adsSocket.
Detach();
633int XrdCmsAdmin::do_Login()
637 char buff[64], *tp, Ltype = 0;
642 if (!(tp = Stream.GetToken()))
643 {
Say.
Emsg(
"do_Login",
"login type not specified");
650 {
case 'p': Stype =
"Primary server";
break;
651 case 'P': Stype =
"Proxy server";
break;
652 case 's': Stype =
"Server";
break;
653 case 'u': Stype =
"Admin";
break;
654 default: Ltype = 0;
break;
658 {
Say.
Emsg(
"do_Login",
"Invalid login type,", tp);
663 {
Say.
Emsg(
"do_login", Stype,
" login rejected; configured for an "
664 "alternate data server.");
668 if (!(tp = Stream.GetToken()))
669 {
Say.
Emsg(
"do_Login",
"login name not specified");
671 }
else Sname = strdup(tp);
675 while((tp = Stream.GetToken()))
676 {
if (!strcmp(tp,
"port"))
677 {
if (!(tp = Stream.GetToken()))
678 {
Say.
Emsg(
"do_Login",
"login port not specified");
684 else if (!strcmp(tp,
"vnid"))
685 {
if (!(tp = Stream.GetToken()))
686 {
Say.
Emsg(
"do_Login",
"vnid value not specified");
691 else {
Say.
Emsg(
"do_Login",
"invalid login option -", tp);
700 if (Ltype !=
'p' && Ltype !=
'P')
return 1;
705 {
Say.
Emsg(
"do_login",
"Server login rejected; configured role",
emsg);
712 && !CheckVNid(vnidVal.length() ? vnidVal.c_str() : 0))
713 {
Say.
Emsg(
"do_login",
"Server login rejected; virtual networking error.");
722 Say.
Emsg(
"do_Login",
"Primary server already logged in; login of",
731 Relay(1, Stream.FDNum());
736 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
741 sprintf(buff,
"logged in; data port is %d", Port);
742 Say.
Emsg(
"do_Login:", Stype, Sname, buff);
750void XrdCmsAdmin::do_Perf(
bool alert)
752 const char *epname =
"do_Perf";
755 if (!Stream.GetRest(buff,
sizeof(buff)))
756 Say.
Emsg(epname,
"performance data is too long.");
758 Say.
Emsg(epname,
"performance data is invalid.");
765void XrdCmsAdmin::do_RmDid(
int isPfn)
767 const char *epname =
"do_RmDid";
771 if (!(tp = Stream.GetToken()))
772 {
Say.
Emsg(epname,
"removed path not specified by",Stype,Sname);
781 {
Say.
Emsg(epname, rc,
"determine pfn for removed path", tp);
783 }
else thePath = apath;
792 {
Say.
Emsg(epname, rc,
"determine lfn for removed path", tp);
800 else {
DEBUG(
"sending managers gone " <<tp);
809void XrdCmsAdmin::do_RmDud(
int isPfn)
811 const char *epname =
"do_RmDud";
815 if (!(tp = Stream.GetToken()))
816 {
Say.
Emsg(epname,
"added path not specified by",Stype,Sname);
825 {
Say.
Emsg(epname, rc,
"determine lfn for added path", tp);
832 if (areFunc) AddEvent(tp,
kYR_have, Mods);
833 else {
DEBUG(
"sending managers have online " <<tp);
#define XrdCmsMAX_PATH_LEN
int(*) XrdOssStatInfo2_t(const char *path, struct stat *buff, int opts, XrdOucEnv *envP, const char *lfn)
int emsg(int rc, char *msg)
void Send(const char *Req, XrdCmsRRData &Data)
static bool InitAREvents(void *arFunc)
void * Start(XrdNetSocket *AdminSock)
void * Notes(XrdNetSocket *AdminSock)
static void RelayAREvent()
static void Relay(int setSock, int newSock)
XrdOucName2Name * lcl_N2N
static void Inform(const char *What, const char *Data, int Dlen)
bool Update(char *line, bool alert=false)
void Update(StateType StateT, int ActivVal, int StageVal=0)
static AdminReq * getReq()
AdminReq(const char *req, XrdCmsRRData &RRD)
int SockName(char *buff, int blen)
int Open(const char *path, int port=-1, int flags=0, int sockbuffsz=0)
static int setOpts(int fd, int options, XrdSysError *eDest=0)
virtual int lfn2pfn(const char *lfn, char *buff, int blen)=0
virtual int pfn2lfn(const char *pfn, char *buff, int blen)=0
XrdOucTList(const char *tval, long long *dv, XrdOucTList *np=0)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Snooze(int seconds)