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)
413 {evType = XrdOssStatEvent::PendAdded;
414 evWhat = "pend ";
415 } else {
416 evType = XrdOssStatEvent::FileAdded;
417 evWhat = "have ";
418 }
419 } else {
420 evType = XrdOssStatEvent::FileRemoved;
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:120
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:48
#define write(a, b, c)
Definition XrdPosix.hh:121
#define read(a, b, c)
Definition XrdPosix.hh:86
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
XrdOucTList(const char *tval, long long *dv, XrdOucTList *np=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
XrdCmsPrepare PrepQ
XrdCmsConfig Config