XRootD
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 
39 #include "XProtocol/XProtocol.hh"
40 #include "XProtocol/YProtocol.hh"
41 
42 #include "XrdCms/XrdCmsAdmin.hh"
43 #include "XrdCms/XrdCmsConfig.hh"
44 #include "XrdCms/XrdCmsManager.hh"
45 #include "XrdCms/XrdCmsMeter.hh"
46 #include "XrdCms/XrdCmsPrepare.hh"
47 #include "XrdCms/XrdCmsState.hh"
48 #include "XrdCms/XrdCmsTrace.hh"
49 #include "XrdNet/XrdNetSocket.hh"
50 #include "XrdOuc/XrdOuca2x.hh"
52 #include "XrdOuc/XrdOucTList.hh"
53 #include "XrdSys/XrdSysError.hh"
54 #include "XrdSys/XrdSysPlatform.hh"
55 #include "XrdSys/XrdSysTimer.hh"
56 
57 using namespace XrdCms;
58 
59 /******************************************************************************/
60 /* L o c a l C l a s s e s */
61 /******************************************************************************/
62 
63 namespace XrdCms
64 {
65 class AdminReq
66 {
67 public:
68 
70 const char *Req;
71 const char *Path;
73  char *Data;
74  int Dlen;
75 static int numinQ;
76 static const int maxinQ = 1024;
77 
78 static 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 
109 private:
110 
111 static XrdSysSemaphore QPresent;
112 static XrdSysMutex QMutex;
113 static AdminReq *First;
114 static AdminReq *Last;
115 };
116 
117 extern 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 
146 namespace
147 {
148 void *AdminLogin(void *carg)
149  {XrdCmsAdmin *Admin = new XrdCmsAdmin();
150  Admin->Login(*(int *)carg);
151  delete Admin;
152  return (void *)0;
153  }
154 
155 void *AdminMonAds(void *carg)
156  {XrdCmsAdmin *Admin = (XrdCmsAdmin *)carg;
157  Admin->MonAds();
158  return (void *)0;
159  }
160 
161 void *AdminMonARE(void *carg)
163  return (void *)0;
164  }
165 
166 void *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 
176 bool XrdCmsAdmin::InitAREvents(void *arFunc)
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 
200 void 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 //
282 do{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 
344 void 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 //
404 do{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 {
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 
439 void 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 
492 void 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 
511 void 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 
535 bool 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 
565 int 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 //
581 do{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 
633 int 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 
750 void 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 
765 void 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 
809 void 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)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define XrdCmsMAX_PATH_LEN
Definition: XrdCmsTypes.hh:46
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)
#define close(a)
Definition: XrdPosix.hh:43
int emsg(int rc, char *msg)
void Send(const char *Req, XrdCmsRRData &Data)
Definition: XrdCmsAdmin.cc:439
static bool InitAREvents(void *arFunc)
Definition: XrdCmsAdmin.cc:176
void * Start(XrdNetSocket *AdminSock)
Definition: XrdCmsAdmin.cc:451
void * Notes(XrdNetSocket *AdminSock)
Definition: XrdCmsAdmin.cc:301
static void RelayAREvent()
Definition: XrdCmsAdmin.cc:395
static void Relay(int setSock, int newSock)
Definition: XrdCmsAdmin.cc:344
void Login(int socknum)
Definition: XrdCmsAdmin.cc:200
void MonAds()
Definition: XrdCmsAdmin.cc:268
XrdOucName2Name * lcl_N2N
const char * myVNID
static void Inform(const char *What, const char *Data, int Dlen)
bool Update(char *line, bool alert=false)
Definition: XrdCmsMeter.cc:502
void Gone(char *path)
void Update(StateType StateT, int ActivVal, int StageVal=0)
Definition: XrdCmsState.cc:258
AdminReq * Next
Definition: XrdCmsAdmin.cc:69
static int numinQ
Definition: XrdCmsAdmin.cc:75
static const int maxinQ
Definition: XrdCmsAdmin.cc:76
static AdminReq * getReq()
Definition: XrdCmsAdmin.cc:78
const char * Req
Definition: XrdCmsAdmin.cc:70
const char * Path
Definition: XrdCmsAdmin.cc:71
AdminReq(const char *req, XrdCmsRRData &RRD)
Definition: XrdCmsAdmin.cc:95
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)
Definition: XrdNetSocket.cc:99
virtual int lfn2pfn(const char *lfn, char *buff, int blen)=0
virtual int pfn2lfn(const char *pfn, char *buff, int blen)=0
XrdOucTList * next
Definition: XrdOucTList.hh:45
char * text
Definition: XrdOucTList.hh:46
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)
Definition: XrdSysError.cc:95
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Snooze(int seconds)
Definition: XrdSysTimer.cc:168
XrdCmsMeter Meter
Definition: XrdCmsMeter.hh:131
XrdCmsAdmin Admin
XrdSysError Say
XrdCmsState CmsState
Definition: XrdCmsState.cc:55
XrdCmsPrepare PrepQ
XrdCmsConfig Config
@ kYR_raw
Definition: YProtocol.hh:132
CmsReqCode
Definition: YProtocol.hh:90
@ kYR_have
Definition: YProtocol.hh:105
@ kYR_gone
Definition: YProtocol.hh:104
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.