XRootD
Loading...
Searching...
No Matches
XrdCmsAdmin.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d C m s A d m i n . c c */
4/* */
5/* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cstdio>
32#include <limits.h>
33#include <string>
34#include <unistd.h>
35#include <cinttypes>
36#include <netinet/in.h>
37#include <sys/types.h>
38
41
42#include "XrdCms/XrdCmsAdmin.hh"
45#include "XrdCms/XrdCmsMeter.hh"
47#include "XrdCms/XrdCmsState.hh"
48#include "XrdCms/XrdCmsTrace.hh"
50#include "XrdOuc/XrdOuca2x.hh"
52#include "XrdOuc/XrdOucTList.hh"
53#include "XrdSys/XrdSysError.hh"
55#include "XrdSys/XrdSysTimer.hh"
56
57using namespace XrdCms;
58
59/******************************************************************************/
60/* L o c a l C l a s s e s */
61/******************************************************************************/
62
63namespace XrdCms
64{
66{
67public:
68
70const char *Req;
71const char *Path;
73 char *Data;
74 int Dlen;
75static int numinQ;
76static const int maxinQ = 1024;
77
78static AdminReq *getReq() {AdminReq *arP;
79 do {QPresent.Wait();
80 QMutex.Lock();
81 if ((arP = First))
82 {if (!(First = arP->Next)) Last = 0;
83 numinQ--;
84 }
85 QMutex.UnLock();
86 } while (!arP);
87 return arP;
88 }
89
90 void Requeue() {QMutex.Lock();
91 Next=First; First=this; QPresent.Post(); numinQ++;
92 QMutex.UnLock();
93 }
94
95 AdminReq(const char *req, XrdCmsRRData &RRD)
96 : Next(0), Req(req), Path(RRD.Path ? RRD.Path : ""),
97 Hdr(RRD.Request), Data(RRD.Buff), Dlen(RRD.Dlen)
98 {RRD.Buff = 0;
99 QMutex.Lock();
100 if (Last) {Last->Next = this; Last = this;}
101 else First=Last = this;
102 QPresent.Post();
103 numinQ++;
104 QMutex.UnLock();
105 }
106
107 ~AdminReq() {if (Data) free(Data);}
108
109private:
110
111static XrdSysSemaphore QPresent;
112static XrdSysMutex QMutex;
113static AdminReq *First;
114static AdminReq *Last;
115};
116
117extern XrdCmsMeter Meter;
118};
119
120/******************************************************************************/
121/* G l o b a l s & S t a t i c s */
122/******************************************************************************/
123
124
125 XrdSysSemaphore AdminReq::QPresent(0);
126 XrdSysMutex AdminReq::QMutex;
127 AdminReq *AdminReq::First = 0;
128 AdminReq *AdminReq::Last = 0;
129 int AdminReq::numinQ= 0;
130
131 XrdOssStatInfo2_t XrdCmsAdmin::areFunc = 0;
132 XrdOucTList *XrdCmsAdmin::areFirst = 0;
133 XrdOucTList *XrdCmsAdmin::areLast = 0;
134 XrdSysMutex XrdCmsAdmin::areMutex;
135 XrdSysSemaphore XrdCmsAdmin::areSem(0);
136 bool XrdCmsAdmin::arePost = false;
137
138 XrdSysMutex XrdCmsAdmin::myMutex;
139 XrdSysSemaphore *XrdCmsAdmin::SyncUp = 0;
140 int XrdCmsAdmin::POnline= 0;
141
142/******************************************************************************/
143/* E x t e r n a l T h r e a d I n t e r f a c e s */
144/******************************************************************************/
145
146namespace
147{
148void *AdminLogin(void *carg)
149 {XrdCmsAdmin *Admin = new XrdCmsAdmin();
150 Admin->Login(*(int *)carg);
151 delete Admin;
152 return (void *)0;
153 }
154
155void *AdminMonAds(void *carg)
156 {XrdCmsAdmin *Admin = (XrdCmsAdmin *)carg;
157 Admin->MonAds();
158 return (void *)0;
159 }
160
161void *AdminMonARE(void *carg)
163 return (void *)0;
164 }
165
166void *AdminSend(void *carg)
167 {XrdCmsAdmin::Relay(0,0);
168 return (void *)0;
169 }
170}
171
172/******************************************************************************/
173/* I n i t A R E v e n t s */
174/******************************************************************************/
175
177{
178 pthread_t tid;
179
180// Record the function we will be using
181//
182 areFunc = (XrdOssStatInfo2_t)arFunc;
183
184// Start the event relay
185//
186 if (XrdSysThread::Run(&tid, AdminMonARE, (void *)0))
187 {Say.Emsg("InitAREvents", errno, "start arevent relay");
188 return false;
189 }
190
191// All done
192//
193 return true;
194}
195
196/******************************************************************************/
197/* L o g i n */
198/******************************************************************************/
199
200void XrdCmsAdmin::Login(int socknum)
201{
202 const char *epname = "Admin_Login";
203 const char *sMsg[2] = {"temporary suspend requested by",
204 "long-term suspend requested by"};
205 char *request, *tp;
206 int sPerm;
207
208// Attach the socket FD to a stream
209//
210 Stream.Attach(socknum);
211
212// The first request better be "login"
213//
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");
218 return;
219 }
220 } else {Say.Emsg(epname, "No admin login specified");
221 return;
222 }
223
224// Start receiving requests on this stream
225//
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;
231 else sPerm = 1;
233 }
234 else if (!strcmp("rmdid", tp)) do_RmDid(); // via lfn
235 else if (!strcmp("newfn", tp)) do_RmDud(); // via lfn
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;
240 else sPerm = 1;
242 Say.Emsg("Login", sMsg[sPerm], Stype, Sname);
243 }
244 else Say.Emsg(epname, "invalid admin request,", tp);
245 }
246 }
247
248// The socket disconnected
249//
250 Say.Emsg("Login", Stype, Sname, "logged out");
251
252// If this is a primary, we must suspend but do not record this event!
253//
254 if (Primary)
256 myMutex.Lock();
257 POnline = 0;
258 Relay(1,-1);
259 myMutex.UnLock();
260 }
261 return;
262}
263
264/******************************************************************************/
265/* M o n A d s */
266/******************************************************************************/
267
269{
270 const char *epname = "MonAds";
271 int sFD, rc;
272 char buff[256], pname[64];
273
274// Indicate what we are doing
275//
276 sprintf(pname, "'altds@localhost:%d'.", Config.adsPort);
277 Say.Emsg(epname, "Monitoring", pname);
278
279// Create a socket and to connect to the alternate data server then monitor it
280// draining any data that might be sent.
281//
282do{sFD = Con2Ads(pname);
283
284 do {do {rc = read(sFD, buff, sizeof(buff));} while(rc > 0);
285 } while(rc < 0 && errno == EINTR);
286
287 if (rc < 0) Say.Emsg(epname, errno, "maintain contact with", pname);
288 else Say.Emsg(epname,"Lost contact with", pname);
289
291 close(sFD);
293
294 } while(1);
295}
296
297/******************************************************************************/
298/* N o t e s */
299/******************************************************************************/
300
302{
303 const char *epname = "Notes";
304 char *request, *tp;
305 int rc;
306
307// Bind the udp socket to a stream
308//
309 Stream.Attach(AnoteSock->Detach());
310 Sname = strdup("anon");
311
312// Accept notifications in an endless loop
313//
314 do {while((request = Stream.GetLine()))
315 {DEBUG("received notification: '" <<request <<"'");
316 if ((tp = Stream.GetToken()))
317 { if (!strcmp("gone", tp)) do_RmDid(1); // via pfn
318 else if (!strcmp("rmdid", tp)) do_RmDid(0); // via lfn
319 else if (!strcmp("have", tp)) do_RmDud(1); // via pfn
320 else if (!strcmp("newfn", tp)) do_RmDud(0); // via lfn
321 else if (!strcmp("nostage", tp))
323 Say.Emsg("Notes","nostage requested by",Stype,Sname);
324 }
325 else if (!strcmp("stage", tp))
327 else Say.Emsg(epname, "invalid notification,", tp);
328 }
329 }
330 if ((rc = Stream.LastError())) break;
331 rc = Stream.Detach(); Stream.Attach(rc);
332 } while(1);
333
334// We should never get here
335//
336 Say.Emsg(epname, rc, "accept notification");
337 return (void *)0;
338}
339
340/******************************************************************************/
341/* R e l a y */
342/******************************************************************************/
343
344void XrdCmsAdmin::Relay(int setSock, int newSock)
345{
346 const char *epname = "Admin_Relay";
347 static const int HdrSz = sizeof(CmsRRHdr);
348 static XrdSysMutex SMutex;
349 static XrdSysSemaphore SReady(0);
350 static int curSock = -1;
351 AdminReq *arP;
352 int retc, mySock = -1;
353
354// Set socket for writing (called from admin thread when pimary logs on)
355 if (setSock)
356 {SMutex.Lock();
357 if (curSock >= 0) close(curSock);
358 else if (newSock >= 0) SReady.Post();
359 if (newSock < 0) curSock = -1;
360 else {curSock = dup(newSock); XrdNetSocket::setOpts(curSock, 0);}
361 SMutex.UnLock();
362 return;
363 }
364
365// This is just an endless loop
366//
367 do {while(mySock < 0)
368 {SMutex.Lock();
369 if (curSock < 0) {SMutex.UnLock(); SReady.Wait(); SMutex.Lock();}
370 mySock = curSock; curSock = -1;
371 SMutex.UnLock();
372 }
373
374 do {arP = AdminReq::getReq();
375
376 if ((retc = write(mySock, &arP->Hdr, HdrSz)) != HdrSz
377 || (retc = write(mySock, arP->Data, arP->Dlen)) != arP->Dlen)
378 retc = (retc < 0 ? errno : ECANCELED);
379 else {DEBUG("sent " <<arP->Req <<' ' <<arP->Path);
380 delete arP; retc = 0;
381 }
382 } while(retc == 0);
383
384 if (retc) Say.Emsg("AdminRelay", retc, "relay", arP->Req);
385 arP->Requeue();
386 close(mySock);
387 mySock = -1;
388 } while(1);
389}
390
391/******************************************************************************/
392/* R e l a y A R E v e n t */
393/******************************************************************************/
394
396{
397 EPNAME("RelayAREvent");
398 const char *evWhat;
399 XrdOucTList *evP;
400 int evType, mod;
401
402// Endless loop relaying events
403//
404do{areMutex.Lock();
405 while((evP = areFirst))
406 {if (evP == areLast) areFirst = areLast = 0;
407 else areFirst = evP->next;
408 areMutex.UnLock();
409 XrdCms::CmsReqCode reqCode = static_cast<CmsReqCode>(evP->ival[0]);
410 mod = evP->ival[1];
411 if (reqCode == kYR_have)
412 {if (mod & CmsHaveRequest::Pending)
414 evWhat = "pend ";
415 } else {
417 evWhat = "have ";
418 }
419 } else {
421 evWhat = "gone ";
422 }
423 (*areFunc)(evP->text, 0, evType, 0, evP->text);
424 DEBUG("sending managers " <<evWhat <<evP->text);
425 XrdCmsManager::Inform(reqCode, mod, evP->text, strlen(evP->text)+1);
426 delete evP;
427 areMutex.Lock();
428 }
429 arePost = true;
430 areMutex.UnLock();
431 areSem.Wait();
432 } while(true);
433}
434
435/******************************************************************************/
436/* S e n d */
437/******************************************************************************/
438
439void XrdCmsAdmin::Send(const char *Req, XrdCmsRRData &Data)
440{
441// AdminReq *arP;
442
443 if (AdminReq::numinQ < AdminReq::maxinQ) new AdminReq(Req, Data);
444 else Say.Emsg("Send", "Queue full; ignoring", Req, Data.Path);
445}
446
447/******************************************************************************/
448/* S t a r t */
449/******************************************************************************/
450
452{
453 const char *epname = "Start";
454 int InSock;
455 pthread_t tid;
456
457// Start the relay thread
458//
459 if (XrdSysThread::Run(&tid, AdminSend, (void *)0))
460 Say.Emsg(epname, errno, "start admin relay");
461
462// If we are in independent mode then let the caller continue
463//
464 if (Config.doWait)
465 {if (Config.adsPort) BegAds();
466 {char dest[512];
467 AdminSock->SockName(dest, sizeof(dest));
468 Say.Emsg(epname, "Waiting for primary server to login via", dest);
469 }
470 }
471 else if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
472
473// Accept connections in an endless loop
474//
475 while(1) if ((InSock = AdminSock->Accept()) >= 0)
476 {XrdNetSocket::setOpts(InSock, 0);
477 if (XrdSysThread::Run(&tid, AdminLogin, (void *)&InSock))
478 {Say.Emsg(epname, errno, "start admin");
479 close(InSock);
480 }
481 } else Say.Emsg(epname, errno, "accept connection");
482 return (void *)0;
483}
484
485/******************************************************************************/
486/* P r i v a t e M e t h o d s */
487/******************************************************************************/
488/******************************************************************************/
489/* A d d E v e n t */
490/******************************************************************************/
491
492void XrdCmsAdmin::AddEvent(const char *path, XrdCms::CmsReqCode req, int mods)
493{
494 int info[2] = {(int)req, mods};
495 XrdOucTList *evP = new XrdOucTList(path, info);
496
497// Add the event to he queue
498//
499 areMutex.Lock();
500 if (areLast) areLast->next = evP;
501 else areFirst = evP;
502 areLast = evP;
503 if (arePost) {areSem.Post(); arePost = false;}
504 areMutex.UnLock();
505}
506
507/******************************************************************************/
508/* B e g A d s */
509/******************************************************************************/
510
511void XrdCmsAdmin::BegAds()
512{
513 const char *epname = "BegAds";
514 pthread_t tid;
515
516// If we don't need to monitor he alternate data server then we are all set
517//
518 if (!Config.adsMon)
519 {Say.Emsg(epname, "Assuming alternate data server is functional.");
521 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
522 return;
523 }
524
525// Start the connection/ping thread for the alternate data server
526//
527 if (XrdSysThread::Run(&tid, AdminMonAds, (void *)this))
528 Say.Emsg(epname, errno, "start alternate data server monitor");
529}
530
531/******************************************************************************/
532/* C h e c k V N i d */
533/******************************************************************************/
534
535bool XrdCmsAdmin::CheckVNid(const char *xNid)
536{
537
538// Check if we have a vnid but the server is supplying one or is not the same
539//
540 if (Config.myVNID)
541 {if (!xNid)
542 {Say.Emsg("do_Login", "Warning! No xrootd vnid specified; "
543 "proceeding only with cmsd vnid.");
544 return true;
545 }
546 if (!strcmp(xNid, Config.myVNID)) return true;
547 std::string msg("xrootd vnid '");
548 msg += xNid; msg += "' does not match cmsd vnid '";
549 msg += Config.myVNID; msg += "'.";
550 Say.Emsg("do_Login", msg.c_str());
551 return false;
552 }
553
554// We don't have a vnid, check if one is present
555//
556 if (xNid) Say.Emsg("do_Login", "Warning! xrootd has a vnid but cmsd does "
557 "not; proceeding without a vnid!");
558 return true;
559}
560
561/******************************************************************************/
562/* C o n 2 A d s */
563/******************************************************************************/
564
565int XrdCmsAdmin::Con2Ads(const char *pname)
566{
567 const char *epname = "Con2Ads";
568 static ClientInitHandShake hsVal = {0, 0, 0, (int)htonl(4), (int)htonl(2012)};
569 static ClientLoginRequest loginReq = {{0, 0},
570 (kXR_unt16)htons(kXR_login),
571 (kXR_int32)htonl(getpid()),
572 {'c', 'm', 's', 'd', 0, 0, 0, 0},
573 0, 0, {0}, 0, 0};
574 struct {kXR_int32 siHS[4];} hsRsp;
575 XrdNetSocket adsSocket;
576 int ecode, snum;
577 char ecnt = 10;
578
579// Create a socket and to connect to the alternate data server
580//
581do{while((snum = adsSocket.Open("localhost", Config.adsPort)) < 0)
582 {if (ecnt >= 10)
583 {ecode = adsSocket.LastError();
584 Say.Emsg(epname, ecode, "connect to", pname);
585 ecnt = 1;
586 } else ecnt++;
588 }
589
590// Write the handshake to make sure the connection went fine
591//
592 if (write(snum, &hsVal, sizeof(hsVal)) < 0)
593 {Say.Emsg(epname, errno, "send handshake to", pname);
594 close(snum); continue;
595 }
596
597// Read the mandatory response
598//
599 if (recv(snum, &hsRsp, sizeof(hsRsp), MSG_WAITALL) < 0)
600 {Say.Emsg(epname, errno, "recv handshake from", pname);
601 close(snum); continue;
602 }
603
604// Now we need to send the login request
605//
606 if (write(snum, &loginReq, sizeof(loginReq)) < 0)
607 {Say.Emsg(epname, errno, "send login to", pname);
608 close(snum); continue;
609 } else break;
610
611 } while(1);
612
613// Indicate what we just did
614//
615 Say.Emsg(epname, "Logged into", pname);
616
617// We connected, so we indicate that the alternate is ok
618//
619 myMutex.Lock();
621 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
622 myMutex.UnLock();
623
624// All done
625//
626 return adsSocket.Detach();
627}
628
629/******************************************************************************/
630/* d o _ L o g i n */
631/******************************************************************************/
632
633int XrdCmsAdmin::do_Login()
634{
635 std::string vnidVal;
636 const char *emsg;
637 char buff[64], *tp, Ltype = 0;
638 int Port = 0;
639
640// Process: login {p | P | s | u} <name> [port <port>] [nid <nid>]
641//
642 if (!(tp = Stream.GetToken()))
643 {Say.Emsg("do_Login", "login type not specified");
644 return 0;
645 }
646
647 Ltype = *tp;
648 if (*(tp+1) == '\0')
649 switch (*tp)
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;
655 }
656
657 if (!Ltype)
658 {Say.Emsg("do_Login", "Invalid login type,", tp);
659 return 0;
660 } else Ltype = *tp;
661
662 if (Config.adsPort && Ltype != 'u')
663 {Say.Emsg("do_login", Stype, " login rejected; configured for an "
664 "alternate data server.");
665 return 0;
666 }
667
668 if (!(tp = Stream.GetToken()))
669 {Say.Emsg("do_Login", "login name not specified");
670 return 0;
671 } else Sname = strdup(tp);
672
673// Get any additional options
674//
675 while((tp = Stream.GetToken()))
676 { if (!strcmp(tp, "port"))
677 {if (!(tp = Stream.GetToken()))
678 {Say.Emsg("do_Login", "login port not specified");
679 return 0;
680 }
681 if (XrdOuca2x::a2i(Say,"login port",tp,&Port,0))
682 return 0;
683 }
684 else if (!strcmp(tp, "vnid"))
685 {if (!(tp = Stream.GetToken()))
686 {Say.Emsg("do_Login", "vnid value not specified");
687 return 0;
688 }
689 vnidVal = tp;
690 }
691 else {Say.Emsg("do_Login", "invalid login option -", tp);
692 return 0;
693 }
694 }
695
696// If this is not a primary, we are done. Otherwise there is much more. We
697// must make sure we are compatible with the login. Note that for alternate
698// data servers we already screened out primary logins, so we will return.
699//
700 if (Ltype != 'p' && Ltype != 'P') return 1;
701 if (Ltype == 'p' && Config.asProxy()) emsg = "only accepts proxies";
702 else if (Ltype == 'P' && !Config.asProxy()) emsg = "does not accept proxies";
703 else emsg = 0;
704 if (emsg)
705 {Say.Emsg("do_login", "Server login rejected; configured role", emsg);
706 return 0;
707 }
708
709// Verify virtual networking
710//
711 if ((vnidVal.length() || Config.myVNID)
712 && !CheckVNid(vnidVal.length() ? vnidVal.c_str() : 0))
713 {Say.Emsg("do_login", "Server login rejected; virtual networking error.");
714 return 0;
715 }
716
717// Discard login if this is a duplicate primary server
718//
719 myMutex.Lock();
720 if (POnline)
721 {myMutex.UnLock();
722 Say.Emsg("do_Login", "Primary server already logged in; login of",
723 tp, "rejected.");
724 return 0;
725 }
726
727// Indicate we have a primary
728//
729 Primary = 1;
730 POnline = 1;
731 Relay(1, Stream.FDNum());
733
734// Check if this is the first primary login and resume if we must
735//
736 if (SyncUp) {SyncUp->Post(); SyncUp = 0;}
737 myMutex.UnLock();
738
739// Document the login
740//
741 sprintf(buff, "logged in; data port is %d", Port);
742 Say.Emsg("do_Login:", Stype, Sname, buff);
743 return 1;
744}
745
746/******************************************************************************/
747/* d o _ P e r f */
748/******************************************************************************/
749
750void XrdCmsAdmin::do_Perf(bool alert)
751{
752 const char *epname = "do_Perf";
753 char buff[256];
754
755 if (!Stream.GetRest(buff, sizeof(buff)))
756 Say.Emsg(epname,"performance data is too long.");
757 else if (!Meter.Update(buff, alert))
758 Say.Emsg(epname,"performance data is invalid.");
759}
760
761/******************************************************************************/
762/* d o _ R m D i d */
763/******************************************************************************/
764
765void XrdCmsAdmin::do_RmDid(int isPfn)
766{
767 const char *epname = "do_RmDid";
768 char *tp, *thePath, apath[XrdCmsMAX_PATH_LEN];
769 int rc;
770
771 if (!(tp = Stream.GetToken()))
772 {Say.Emsg(epname,"removed path not specified by",Stype,Sname);
773 return;
774 }
775
776// Handle prepare queue removal
777//
778 if (PrepQ.isOK())
779 {if (!isPfn && Config.lcl_N2N)
780 if ((rc = Config.lcl_N2N->lfn2pfn(tp, apath, sizeof(apath))))
781 {Say.Emsg(epname, rc, "determine pfn for removed path", tp);
782 thePath = 0;
783 } else thePath = apath;
784 else thePath = tp;
785 if (thePath) PrepQ.Gone(thePath);
786 }
787
788// If we have a pfn then we must get the lfn to inform our manager about the file
789//
790 if (isPfn && Config.lcl_N2N)
791 {if ((rc = Config.lcl_N2N->pfn2lfn(tp, apath, sizeof(apath))))
792 {Say.Emsg(epname, rc, "determine lfn for removed path", tp);
793 return;
794 } else tp = apath;
795 }
796
797// Check if we are relaying remove events and, if so, vector through that.
798//
799 if (areFunc) AddEvent(tp, kYR_gone, kYR_raw);
800 else {DEBUG("sending managers gone " <<tp);
801 XrdCmsManager::Inform(kYR_gone, kYR_raw, tp, strlen(tp)+1);
802 }
803}
804
805/******************************************************************************/
806/* d o _ R m D u d */
807/******************************************************************************/
808
809void XrdCmsAdmin::do_RmDud(int isPfn)
810{
811 const char *epname = "do_RmDud";
812 char *tp, *pp, apath[XrdCmsMAX_PATH_LEN];
813 int rc, Mods = kYR_raw;
814
815 if (!(tp = Stream.GetToken()))
816 {Say.Emsg(epname,"added path not specified by",Stype,Sname);
817 return;
818 }
819
820 if ((pp = Stream.GetToken()) && *pp == 'p') Mods |= CmsHaveRequest::Pending;
821 else Mods |= CmsHaveRequest::Online;
822
823 if (isPfn && Config.lcl_N2N)
824 {if ((rc = Config.lcl_N2N->pfn2lfn(tp, apath, sizeof(apath))))
825 {Say.Emsg(epname, rc, "determine lfn for added path", tp);
826 return;
827 } else tp = apath;
828 }
829
830// Check if we are relaying remove events and, if so, vector through that.
831//
832 if (areFunc) AddEvent(tp, kYR_have, Mods);
833 else {DEBUG("sending managers have online " <<tp);
834 XrdCmsManager::Inform(kYR_have, Mods, tp, strlen(tp)+1);
835 }
836}
@ kXR_login
Definition XProtocol.hh:119
int kXR_int32
Definition XPtypes.hh:89
unsigned short kXR_unt16
Definition XPtypes.hh:67
#define DEBUG(x)
#define EPNAME(x)
#define XrdCmsMAX_PATH_LEN
int(* XrdOssStatInfo2_t)(const char *path, struct stat *buff, int opts, XrdOucEnv *envP, const char *lfn)
#define close(a)
Definition XrdPosix.hh:43
#define write(a, b, c)
Definition XrdPosix.hh:110
#define read(a, b, c)
Definition XrdPosix.hh:77
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)
void Login(int socknum)
XrdOucName2Name * lcl_N2N
const char * myVNID
static void Inform(const char *What, const char *Data, int Dlen)
bool Update(char *line, bool alert=false)
void Gone(char *path)
void Update(StateType StateT, int ActivVal, int StageVal=0)
AdminReq * Next
static int numinQ
static const int maxinQ
const char * Req
static AdminReq * getReq()
const char * Path
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)
int Accept(int ms=-1)
virtual int lfn2pfn(const char *lfn, char *buff, int blen)=0
virtual int pfn2lfn(const char *pfn, char *buff, int blen)=0
char * GetLine()
int Attach(int FileDescriptor, int bsz=2047)
char * GetToken(int lowcase=0)
int GetRest(char *theBuf, int Blen, int lowcase=0)
XrdOucTList * next
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:45
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)
XrdCmsMeter Meter
XrdCmsAdmin Admin
XrdSysError Say
XrdCmsState CmsState
XrdCmsConfig Config
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.