36 #include <netinet/in.h>
37 #include <sys/types.h>
82 {
if (!(First = arP->
Next)) Last = 0;
100 if (Last) {Last->
Next =
this; Last =
this;}
101 else First=Last =
this;
136 bool XrdCmsAdmin::arePost =
false;
140 int XrdCmsAdmin::POnline= 0;
148 void *AdminLogin(
void *carg)
155 void *AdminMonAds(
void *carg)
161 void *AdminMonARE(
void *carg)
166 void *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);
282 do{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;
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;}
511 void 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");
535 bool 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!");
565 int XrdCmsAdmin::Con2Ads(
const char *pname)
567 const char *epname =
"Con2Ads";
572 {
'c',
'm',
's',
'd', 0, 0, 0, 0},
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();
633 int 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);
750 void 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.");
765 void 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);
809 void 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)
ssize_t write(int fildes, const void *buf, size_t nbyte)
ssize_t read(int fildes, void *buf, size_t nbyte)
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
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)
static const int PendAdded
Path has been added in pending mode.
static const int FileRemoved
Path has been removed.
static const int FileAdded
Path has been added.