XRootD
XrdFrmMonitor.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d F r m M o n i t o r . c c */
4 /* */
5 /* (c) 2010 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 <cerrno>
32 #include <cstdlib>
33 #include <ctime>
34 #include <unistd.h>
35 #include <sys/types.h>
36 
37 #include "XrdFrc/XrdFrcTrace.hh"
38 #include "XrdFrm/XrdFrmMonitor.hh"
39 #include "XrdNet/XrdNetMsg.hh"
40 #include "XrdOuc/XrdOucUtils.hh"
41 #include "XrdSys/XrdSysError.hh"
42 #include "XrdSys/XrdSysPlatform.hh"
43 #include "XrdSys/XrdSysPthread.hh"
44 #include "XrdSys/XrdSysTimer.hh"
45 
46 using namespace XrdFrc;
47 
48 /******************************************************************************/
49 /* S t a t i c A l l o c a t i o n */
50 /******************************************************************************/
51 
52 char *XrdFrmMonitor::Dest1 = 0;
53 int XrdFrmMonitor::monMode1 = 0;
54 XrdNetMsg *XrdFrmMonitor::InetDest1 = 0;
55 char *XrdFrmMonitor::Dest2 = 0;
56 int XrdFrmMonitor::monMode2 = 0;
57 XrdNetMsg *XrdFrmMonitor::InetDest2 = 0;
58 kXR_int32 XrdFrmMonitor::startTime = 0;
59 int XrdFrmMonitor::isEnabled = 0;
60 char *XrdFrmMonitor::idRec = 0;
61 int XrdFrmMonitor::idLen = 0;
62 int XrdFrmMonitor::sidSize = 0;
63 char *XrdFrmMonitor::sidName = 0;
64 int XrdFrmMonitor::idTime = 3600;
65 char XrdFrmMonitor::monMIGR = 0;
68 
69 /******************************************************************************/
70 /* T h r e a d I n t e r f a c e s */
71 /******************************************************************************/
72 
73 void *XrdFrmMonitorID(void *parg)
74 {
75  (void)parg;
77  return (void *)0;
78 }
79 
80 /******************************************************************************/
81 /* D e f a u l t s */
82 /******************************************************************************/
83 
84 void XrdFrmMonitor::Defaults(char *dest1, int mode1, char *dest2, int mode2,
85  int iTime)
86 {
87 
88 // Make sure if we have a proper destinations and modes
89 //
90  if (dest1 && !mode1) {free(dest1); dest1 = 0; mode1 = 0;}
91  if (dest2 && !mode2) {free(dest2); dest2 = 0; mode2 = 0;}
92 
93 // Propogate the destinations
94 //
95  if (!dest1)
96  {mode1 = (dest1 = dest2) ? mode2 : 0;
97  dest2 = 0; mode2 = 0;
98  }
99 
100 // Set the default destinations (caller supplied strdup'd strings)
101 //
102  if (Dest1) free(Dest1);
103  Dest1 = dest1; monMode1 = mode1;
104  if (Dest2) free(Dest2);
105  Dest2 = dest2; monMode2 = mode2;
106 
107 // Set overall monitor mode
108 //
109  monMIGR = ((mode1 | mode2) & XROOTD_MON_MIGR ? 1 : 0);
110  monPURGE = ((mode1 | mode2) & XROOTD_MON_PURGE ? 1 : 0);
111  monSTAGE = ((mode1 | mode2) & XROOTD_MON_STAGE ? 1 : 0);
112 
113 // Do final check
114 //
115  isEnabled = (Dest1 == 0 && Dest2 == 0 ? 0 : 1);
116  idTime = iTime;
117 }
118 
119 /******************************************************************************/
120 /* I d e n t */
121 /******************************************************************************/
122 
124 {
125 do{Send(-1, idRec, idLen);
126  XrdSysTimer::Snooze(idTime);
127  } while(1);
128 }
129 
130 /******************************************************************************/
131 /* I n i t */
132 /******************************************************************************/
133 
134 int XrdFrmMonitor::Init(const char *iHost, const char *iProg, const char *iName)
135 {
136  XrdXrootdMonMap *mP;
137  long long mySid;
138  const char *etext = 0;
139  char iBuff[1024];
140  bool aOK;
141 
142 // Generate our server ID
143 //
144  sidName = XrdOucUtils::Ident(mySid, iBuff, sizeof(iBuff), iHost, iProg,
145  (iName ? iName : "anon"), 0);
146  sidSize = strlen(sidName);
147  startTime = htonl(time(0));
148 
149 // There is nothing to do unless we have been enabled via Defaults()
150 //
151  if (!isEnabled) return 1;
152 
153 // Ignore array bounds warning from gcc 12 triggered because the allocated
154 // memory for the XrdXrootdMonMap is smaller than sizeof(XrdXrootdMonMap)
155 #if defined(__GNUC__) && __GNUC__ >= 12
156 #pragma GCC diagnostic push
157 #pragma GCC diagnostic ignored "-Warray-bounds"
158 #endif
159 // Create identification record
160 //
161  idLen = strlen(iBuff) + sizeof(XrdXrootdMonHeader) + sizeof(kXR_int32);
162  idRec = (char *)malloc(idLen+1);
163  mP = (XrdXrootdMonMap *)idRec;
164  fillHeader(&(mP->hdr), XROOTD_MON_MAPIDNT, idLen);
165  mP->hdr.pseq = 0;
166  mP->dictid = 0;
167  strcpy(mP->info, iBuff);
168 #if defined(__GNUC__) && __GNUC__ >= 12
169 #pragma GCC diagnostic pop
170 #endif
171 
172 // Setup the primary destination
173 //
174  InetDest1 = new XrdNetMsg(&Say, Dest1, &aOK);
175  if (!aOK)
176  {Say.Emsg("Monitor", "setup monitor collector;", etext);
177  return 0;
178  }
179 
180 // Do the same for the secondary destination
181 //
182  if (Dest2)
183  {InetDest2 = new XrdNetMsg(&Say, Dest2, &aOK);
184  if (!aOK)
185  {Say.Emsg("Monitor", "setup monitor collector;", etext);
186  return 0;
187  }
188  }
189 
190 // Check if we will be producing identification records
191 //
192  if (idTime)
193  {pthread_t tid;
194  int retc;
195  if ((retc = XrdSysThread::Run(&tid,XrdFrmMonitorID,0,0,"mon ident")))
196  {Say.Emsg("Init", retc, "create monitor ident thread"); return 0;}
197  }
198 
199 // All done
200 //
201  return 1;
202 }
203 
204 /******************************************************************************/
205 /* M a p */
206 /******************************************************************************/
207 
208 kXR_unt32 XrdFrmMonitor::Map(char code, const char *uname, const char *path)
209 {
210  XrdXrootdMonMap map;
211  const char *colonP, *atP;
212  char uBuff[1024];
213  int size, montype;
214 
215 // Decode the user name as a.b:c@d
216 //
217  if ((colonP = index(uname, ':')) && (atP = index(colonP+1, '@')))
218  {int n = colonP - uname + 1;
219  strncpy(uBuff, uname, n);
220  strcpy(uBuff+n, sidName);
221  strcpy(uBuff+n+sidSize, atP);
222  } else strcpy(uBuff, uname);
223 
224 // Copy in the username and path the dictid is always zero for us.
225 //
226  map.dictid = 0;
227  strcpy(map.info, uBuff);
228  size = strlen(uBuff);
229  if (path)
230  {*(map.info+size) = '\n';
231  strlcpy(map.info+size+1, path, sizeof(map.info)-size-1);
232  size = size + strlen(path) + 1;
233  }
234 
235 // Route the packet to all destinations that need them
236 //
237  if (code == XROOTD_MON_MAPSTAG){montype = XROOTD_MON_STAGE;
238  code = XROOTD_MON_MAPXFER;
239  }
240  else if (code == XROOTD_MON_MAPMIGR){montype = XROOTD_MON_MIGR;
241  code = XROOTD_MON_MAPXFER;
242  }
243  else if (code == XROOTD_MON_MAPPURG) montype = XROOTD_MON_PURGE;
244  else montype = XROOTD_MON_INFO;
245 
246 // Fill in the header and route the packet
247 //
248  size = sizeof(XrdXrootdMonHeader)+sizeof(kXR_int32)+size;
249  fillHeader(&map.hdr, code, size);
250 // std::cerr <<"Mon send "<<code <<": " <<map.info <<std::endl;
251  Send(montype, (void *)&map, size);
252 
253 // Return the dictionary id
254 //
255  return map.dictid;
256 }
257 
258 /******************************************************************************/
259 /* P r i v a t e M e t h o d s */
260 /******************************************************************************/
261 /******************************************************************************/
262 /* f i l l H e a d e r */
263 /******************************************************************************/
264 
265 void XrdFrmMonitor::fillHeader(XrdXrootdMonHeader *hdr,
266  const char id, int size)
267 { static XrdSysMutex seqMutex;
268  static int seq = 0;
269  int myseq;
270 
271 // Generate a new sequence number
272 //
273  seqMutex.Lock();
274  myseq = 0x00ff & (seq++);
275  seqMutex.UnLock();
276 
277 // Fill in the header
278 //
279  hdr->code = static_cast<kXR_char>(id);
280  hdr->pseq = static_cast<kXR_char>(myseq);
281  hdr->plen = htons(static_cast<uint16_t>(size));
282  hdr->stod = startTime;
283 }
284 
285 /******************************************************************************/
286 /* S e n d */
287 /******************************************************************************/
288 
289 int XrdFrmMonitor::Send(int monMode, void *buff, int blen)
290 {
291  EPNAME("Send");
292  static XrdSysMutex sendMutex;
293  int rc1, rc2;
294  sendMutex.Lock();
295  if (monMode & monMode1 && InetDest1)
296  {rc1 = InetDest1->Send((char *)buff, blen);
297  DEBUG(blen <<" bytes sent to " <<Dest1 <<" rc=" <<rc1);
298  }
299  else rc1 = 0;
300  if (monMode & monMode2 && InetDest2)
301  {rc2 = InetDest2->Send((char *)buff, blen);
302  DEBUG(blen <<" bytes sent to " <<Dest2 <<" rc=" <<rc2);
303  }
304  else rc2 = 0;
305  sendMutex.UnLock();
306 
307  return (rc1 ? rc1 : rc2);
308 }
int kXR_int32
Definition: XPtypes.hh:89
unsigned int kXR_unt32
Definition: XPtypes.hh:90
unsigned char kXR_char
Definition: XPtypes.hh:65
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
void * XrdFrmMonitorID(void *parg)
#define XROOTD_MON_INFO
#define XROOTD_MON_PURGE
#define XROOTD_MON_MIGR
#define XROOTD_MON_STAGE
size_t strlcpy(char *dst, const char *src, size_t sz)
const kXR_char XROOTD_MON_MAPIDNT
const kXR_char XROOTD_MON_MAPXFER
const kXR_char XROOTD_MON_MAPMIGR
char info[1024+256]
const kXR_char XROOTD_MON_MAPSTAG
XrdXrootdMonHeader hdr
const kXR_char XROOTD_MON_MAPPURG
static char monPURGE
static kXR_unt32 Map(char code, const char *uname, const char *path)
static int Init(const char *iHost, const char *iProg, const char *iName)
static void Ident()
static char monMIGR
static void Defaults(char *dest1, int m1, char *dest2, int m2, int iTime)
static char monSTAGE
static char * Ident(long long &mySID, char *iBuff, int iBlen, const char *iHost, const char *iProg, const char *iName, int Port)
Definition: XrdOucUtils.cc:702
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
XrdSysError Say
ssize_t Send(int fd, KernelBuffer &buffer)