147{
148public:
149
151 if (idInt >= 0)
154 }
155 if ((doIdnt || doHail) && idInt > 0)
157 }
158
160 idInt(idt), doIdnt(ison), doHail(true) {}
162
163private:
164int idInt;
165bool doIdnt;
166bool doHail;
167};
168
169
170
171
172
174{
175public:
176
178#ifndef NODEBUG
179 const char *TraceID = "MonTick";
180#endif
182 if (Window && Now)
184 else {
TRACE(
DEBUG,
"Monitor clock stopping.");}
185 }
186
188
190 Sched(0), Window(0) {}
192
193private:
195int Window;
196};
197
198
199
200
201
203{
204public:
205
207
209
212 else {unLock = 1; monLock.
Lock();}
213 }
215
216private:
217
219 char unLock;
220};
221
223
224
225
226
227
229 : Next(0), theDest(0), theMode(0)
230{
231 if (dest)
232 {Hello *nP = First;
233 while(nP) {if (!strcmp(dest, nP->theDest) && mode == theMode) return;
234 nP = nP->Next;
235 }
236 Next = First;
237 First = this;
238 theDest = strdup(dest);
239 theMode = mode;
240 }
241}
242
243
244
245
246
248
250{
252
253
254
255 while(nP) {nP->
Ident(); nP = nP->Next;}
256
257
258
259 return First != 0;
260}
261
262
263
264
265
267{
268 if (Agent)
269 {XrdXrootdMonitor::unAlloc(Agent); Agent = 0;}
270 Fops = Iops = 0;
271}
272
273
274
275
276
278{
279 if (Agent || (Agent = XrdXrootdMonitor::Alloc(1)))
280 {Iops = XrdXrootdMonitor::monIO;
281 Fops = XrdXrootdMonitor::monFILE;
282 } else Iops = Fops = 0;
283}
284
285
286
287
288
290 const char *Hname,
291 const char *Pname, unsigned int xSID)
292{
293#ifndef NODEBUG
294 const char *TraceID = "Monitor";
295#endif
296 char *dotP, *colonP, *atP;
297 char uBuff[1024], tBuff[1024], sBuff[64];
298
299
300
301
302 snprintf(tBuff, sizeof(tBuff), "%s", Uname);
303 if ((dotP = index(tBuff, '.')) && (colonP = index(dotP+1, ':')) &&
304 (atP = index(colonP+1, '@')))
305 {*dotP = 0; *colonP = 0; *atP = 0;
306 if (xSID)
307 {snprintf(sBuff, sizeof(sBuff), " %u", xSID);
308 dotP = sBuff;
309 }
310
311 int n = snprintf(uBuff, sizeof(uBuff), "%s/%s.%s:%s@%s", Pname, tBuff,
312 dotP+1,
kySID, atP+1);
313
314 if (n < 0 || n >= (int) sizeof(uBuff))
315 TRACE(LOGIN,
"Login ID was truncated: " << uBuff);
316
317 if (xSID) {
TRACE(LOGIN,
"Register remap "<<Uname<<
" -> "<<uBuff);}
318 } else snprintf(uBuff, sizeof(uBuff), "%s/%s", Pname, Uname);
319
320
321
322
323 Agent = XrdXrootdMonitor::Alloc();
324 Did = 0;
325 Len = strlen(uBuff);
326 Name = strdup(uBuff);
327 Iops = XrdXrootdMonitor::monIO;
328 Fops = XrdXrootdMonitor::monFILE;
329}
330
331
332
333
334
336{
337 char buff[1024];
338
339 snprintf(buff, sizeof(buff), "&Uc=%d&Ec=%d&Ac=%d", ntohl(Did), eCode, aCode);
340
342}
343
344
345
347{
348 char buff[4096];
349
350
351
352 if (infoT != TokenInfo) return false;
353
354 snprintf(buff, sizeof(buff), "&Uc=%d%s%s", ntohl(Did),
355 (*info == '&' ? "" : "&"), info);
356
358
359 return true;
360}
361
362
363
364
366{
368
369
370
371 lastWindow = 0;
372 localWindow = currWindow;
373
374
375
376 if (posix_memalign((void **)&monBuff, getpagesize(), monBlen))
377 eDest->
Emsg(
"Monitor",
"Unable to allocate monitor buffer.");
378 else {nextEnt = 1;
380 }
381}
382
383
384
385
386
387XrdXrootdMonitor::~XrdXrootdMonitor()
388{
389
390 if (monBuff) {Flush(); free(monBuff);}
391}
392
393
394
395
396
398{
400
401
402
403 if (
this ==
altMon || !*
id)
return;
404
405
406
407 if (lastWindow != currWindow) Mark();
408 else if (nextEnt == lastEnt) Flush();
410 strncpy((char *)(&(monBuff->info[nextEnt])+4), id, apInfoSize);
411}
412
413
414
415
416
418{
420 int lastVal;
421
422
423
424
425
426 if (!isEnabled) mp = 0;
427 else if (!monIO) mp =
altMon;
429 if (!(mp->monBuff)) {delete mp; mp = 0;}
430
431
432
433 if (mp && isEnabled < 0)
435 lastVal = numMonitor; numMonitor++;
436 if (!lastVal && !monREDR) startClock();
438 }
439
440
441
442 return mp;
443}
444
445
446
447
448
450{
452 unsigned int rVal, wVal;
453
454
455
456 if (lastWindow != currWindow) Mark();
457 else if (nextEnt == lastEnt) Flush();
459 monBuff->info[nextEnt].arg0.id[1] = do_Shift(rTot, rVal);
460 monBuff->info[nextEnt].arg0.rTot[1] = htonl(rVal);
461 monBuff->info[nextEnt].arg0.id[2] = do_Shift(wTot, wVal);
462 monBuff->info[nextEnt].arg0.id[3] = 0;
463 monBuff->info[nextEnt].arg1.wTot = htonl(wVal);
464 monBuff->info[nextEnt++].arg2.dictid = dictid;
465
466
467
469}
470
471
472
473
474
475
476
478{
479 int mmode;
480
481
482
483
484 if (!dest1 && !dest2) {isEnabled = 0; return;}
485 if (!dest1) {dest1 = dest2; dest2 = 0; mode1 |= mode2; mode2 = 0;}
486
487
488
489 if (Dest1) free(Dest1);
490 Dest1 = dest1; monMode1 = mode1;
491 if (Dest2) free(Dest2);
492 Dest2 = dest2; monMode2 = mode2;
493
494
495
496 mmode = mode1 | mode2;
497 monACTIVE = (mmode ? 1 : 0);
507
508
509
510 if (monREDR || (isEnabled > 0 && (monIO || monFILE))) monCLOCK = 1;
511
512
513
518 else monUSER = 2;
519 }
520
521
522
523
525}
526
527
528
530 int flush, int flash, int idt, int rnm,
531 int fbsz, int fsint, int fsopt, int fsion)
532{
533
534
535
536 sizeWindow = (wsz <= 0 ? 60 : wsz);
537 autoFlush = (flush <= 0 ? 600 : flush);
538 autoFlash = (flash <= 0 ? 0 : flash);
539 monIdent = idt;
540 rdrNum = (rnm <= 0 || rnm >
rdrMax ? 3 : rnm);
541 rdrWin = (sizeWindow > 16777215 ? 16777215 : sizeWindow);
542 rdrWin = htonl(rdrWin);
543
544
545
547 monFSTAT = fsint != 0;
548
549
550
551 if (msz <= 0) msz = 16384;
552 else if (msz < 1024) msz = 1024;
556 lastEnt--;
557
558
559
560 if (rsz <= 0) rsz = 32768;
561 else if (rsz < 2048) rsz = 2048;
564 lastRnt--;
565}
566
567
568
569
570
572{
574
575
576
579
580
581
582 if (lastWindow != currWindow) Mark();
583 else if (nextEnt == lastEnt) Flush();
584 monBuff->info[nextEnt].arg0.rTot[0] = 0;
586 monBuff->info[nextEnt].arg0.id[1] = Flags;
587 monBuff->info[nextEnt].arg1.wTot = htonl(csec);
588 monBuff->info[nextEnt++].arg2.dictid = dictid;
589
590
591
593 altMon->Dup(&monBuff->info[nextEnt-1]);
594}
595
596
597
598
599
601{
603
604
605
606 if (lastWindow != currWindow) Mark();
607 else if (nextEnt == lastEnt) Flush();
609 nextEnt++;
610}
611
612
613
614
615
616XrdXrootdMonitor::MonRdrBuff *XrdXrootdMonitor::Fetch()
617{
618 MonRdrBuff *bP;
619
620
621
623 if ((bP = rdrMP)) rdrMP = rdrMP->Next;
625 return bP;
626}
627
628
629
630
631
633 const char *iHost, const char *iProg,
634 const char *iName, int Port)
635{
636 const char *cgID0 = "&site=%s";
637 const char *cgID1 = "&host=%s";
638 const char *cgID2 = "&port=%d&inst=%s";
639 const char *cgID3 = "&pgm=%s&ver=%s";
640
641 const char *jsID0 = "\"src\":{\"site\":\"%s\"}";
642 const char *jsID1 = "%s\"host\":\"%s\"}";
643 const char *jsID2 = "%s\"port\":%d,\"inst\":\"%s\"}";
644 const char *jsID3 = "%s\"pgm\":\"%s\",\"ver\":\"%s\"}";
645
647 char iBuff[1024], iMuff[2048], iPuff[1024];
648 int n, i, j;
649
650
651
654
655
656
657 strcpy(iBuff, "=/");
659 iHost, iProg, iName, Port);
660 n = strlen(iBuff);
661 snprintf(iBuff+n, sizeof(iBuff)-n, "&ver=%s", XrdVERSION);
662
665
666
667
668#if defined(__GNUC__) && __GNUC__ >= 12
669#pragma GCC diagnostic push
670#pragma GCC diagnostic ignored "-Warray-bounds"
671#endif
672
673
675 idRec = (char *)malloc(idLen+1);
680 strcpy(mP->
info, iBuff);
681#if defined(__GNUC__) && __GNUC__ >= 12
682#pragma GCC diagnostic pop
683#endif
684
685
686
687 const char *Site (getenv("XRDSITE") ? getenv("XRDSITE") : "");
688 i = snprintf(iPuff, sizeof(iPuff), cgID0, Site);
689 SidCGI[0] = strdup(iPuff);
690 LidCGI[0] = strlen(iPuff);
691
692 n = sizeof(iPuff)-i; j = i;
693 i = snprintf(iPuff+j, n, cgID1, iHost);
694 SidCGI[1] = strdup(iPuff);
695 LidCGI[1] = strlen(iPuff);
696
697 n -= i; j += i;
698 i = snprintf(iPuff+j, n, cgID2, Port, iName);
699 SidCGI[2] = strdup(iPuff);
700 LidCGI[2] = strlen(iPuff);
701
702 n -= i; j += i;
703 snprintf(iPuff+j, n, cgID3, iProg, XrdVERSION);
704 SidCGI[3] = strdup(iPuff);
705 LidCGI[3] = strlen(iPuff);
706
707
708
709 n = snprintf(iPuff, sizeof(iPuff), jsID0, Site);
712
713 strcpy(iPuff+n-1, ",");
714 n = snprintf(iMuff, sizeof(iMuff), jsID1, iPuff, iHost);
717
718 strcpy(iMuff+n-1, ",");
719 n = snprintf(iPuff, sizeof(iPuff), jsID2, iMuff, Port, iName);
722
723 strcpy(iPuff+n-1, ",");
724 snprintf(iMuff, sizeof(iMuff), jsID3, iPuff, iProg, XrdVERSION);
727}
728
729
730
732{
734 int i, Now = time(0);
735 bool aOK;
736
737
738
739 if (Dest1)
741 if (!aOK)
742 {
eDest->
Emsg(
"Monitor",
"Unable to setup primary monitor collector.");
743 return 0;
744 }
745 }
746
747
748
749 if (Dest2)
751 if (!aOK)
752 {
eDest->
Emsg(
"Monitor",
"Unable to setup secondary monitor collector.");
753 return 0;
754 }
755 }
756
757
758
760
761
762
763 if (!isEnabled) return 1;
764
765
766
767
772 eDest->
Emsg(
"Monitor",
"allocate monitor; insufficient storage.");
773 return 0;
774 }
775
776
777
778 if (monCLOCK) startClock();
779
780
781
782 if (!
Sched || !monFSTAT) monFSTAT = 0;
784
785
786
787 if (!monREDR) return 1;
788
789
790
791 for (i = 0; i < rdrNum; i++)
792 {if (posix_memalign((void **)&rdrMon[i].Buff, getpagesize(),monRlen))
793 {
eDest->
Emsg(
"Monitor",
"Unable to allocate monitor rdr buffer.");
794 return 0;
795 }
796 rdrMon[i].Buff->sID =
mySID;
798 rdrMon[i].Next = (i ? &rdrMon[i-1] : &rdrMon[0]);
799 rdrMon[i].nextEnt = 0;
800 rdrMon[i].flushIt = Now + autoFlush;
801 rdrMon[i].lastTOD = 0;
802 }
803 rdrMon[0].Next = &rdrMon[i-1];
804 rdrMP = &rdrMon[0];
805
806
807
808 return 1;
809}
810
811
812
813
814
816{
818 static unsigned int monSeqID = 1;
819 unsigned int mySeqID;
820
821
822
824 mySeqID = monSeqID++;
826
827
828
829 if (hbo) return mySeqID;
830 return htonl(mySeqID);
831}
832
833
834
835
836
838 const char *path)
839{
841 int size, montype;
842
843
844
848 if (path)
849 {*(map.
info+size) =
'\n';
851 size = size + strlen(path) + 1;
852 }
853
854
855
857 fillHeader(&map.
hdr, code, size);
858
859
860
866 Send(montype, (
void *)&map, size);
867
868
869
871}
872
873
874
875
876
878{
880
881 if (lastWindow != currWindow) Mark();
882 else if (nextEnt == lastEnt) Flush();
883 h2nll(fsize, monBuff->info[nextEnt].arg0.val);
885 monBuff->info[nextEnt].arg1.buflen = 0;
886 monBuff->info[nextEnt++].arg2.dictid = dictid;
887
888
889
891}
892
893
894
895
896
898 char opC,
const char *
Path)
899{
901 MonRdrBuff *mP = Fetch();
902 int n, slots, hLen, pLen;
903 char *dest;
904
905
906
907 if (*hName ==
'/') {
Path = hName; hName =
""; hLen = 0;}
908 else {const char *quest = index(hName, '?');
909 hLen = (quest ? quest - hName : strlen(hName));
910 if (hLen > 256) hLen = 256;
911 }
912
913
914
916 if (pLen > 1024) pLen = 1024;
917
918
919
920 n = (hLen + 1 + pLen + 1);
924
925
926
927 if (!mP) return 0;
928 mP->Mutex.Lock();
929
930
931
932
933 if (mP->nextEnt + slots + 2 >= lastRnt) Flush(mP);
934
935
936
937 if (mP->lastTOD != rdrTOD)
938 {mP->lastTOD = rdrTOD;
939 setTMurk(mP->Buff, mP->nextEnt, mP->lastTOD);
940 mP->nextEnt++;
941 }
942
943
944
945 mtP = &(mP->Buff->info[mP->nextEnt]);
947 mtP->
arg0.rdr.Dent =
static_cast<char>(slots);
948 mtP->
arg0.rdr.Port = htons(
static_cast<short>(Port));
949 mtP->
arg1.dictid = mID;
950 dest = (char *)(mtP+1);
951 strncpy(dest, hName,hLen); dest += hLen; *dest++ = ':';
952 strncpy(dest,
Path, pLen);
953
954
955
956 mP->nextEnt = mP->nextEnt + (slots+1);
957 mP->Mutex.UnLock();
958 return 0;
959}
960
961
962
963
964
965
967{
968 time_t Now = time(0);
969 int nextFlush;
970
971
972
973
974 currWindow =
static_cast<kXR_int32>(Now);
975 rdrTOD = htonl(currWindow);
976 nextFlush = currWindow + autoFlush;
977
978
979
980 if (
altMon && currWindow >= FlushTime)
982 if (currWindow >= FlushTime)
984 else FlushTime = nextFlush;
985 }
987 }
988
989
990
991 if (monREDR)
992 {int n = rdrNum;
993 while(n--)
994 {rdrMon[n].Mutex.Lock();
995 if (rdrMon[n].nextEnt == 0) rdrMon[n].flushIt = nextFlush;
996 else if (rdrMon[n].flushIt <= currWindow) Flush(&rdrMon[n]);
997 rdrMon[n].Mutex.UnLock();
998 }
999 }
1000
1001
1002
1003
1004
1005 if (!monREDR && isEnabled < 0)
1006 {windowMutex.
Lock();
1007 if (!numMonitor) Now = 0;
1009 }
1010 return Now;
1011}
1012
1013
1014
1015
1016
1018{
1019
1020
1021
1022 if (monp !=
altMon)
delete monp;
1023
1024
1025
1026 if (isEnabled < 0)
1027 {windowMutex.
Lock();
1028 numMonitor--;
1030 }
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040unsigned char XrdXrootdMonitor::do_Shift(long long xTot, unsigned int &xVal)
1041{
1042 const long long smask = 0x7fffffff00000000LL;
1043 const long long xmask = 0x7fffffffffffffffLL;
1044 unsigned char xshift = 0;
1045
1046 xTot &= xmask;
1047 while(xTot & smask) {xTot = xTot >> 1LL; xshift++;}
1048 xVal = static_cast<unsigned int>(xTot);
1049
1050 return xshift;
1051}
1052
1053
1054
1055
1056
1058 const char id, int size)
1059{
1060
1061
1062
1064
1065 hdr->
plen = htons(
static_cast<uint16_t
>(size));
1067}
1068
1069
1070
1071
1072
1073void XrdXrootdMonitor::Flush()
1074{
1075 int size;
1077
1078
1079
1080 if (nextEnt <= 1) return;
1081
1082
1083
1084
1085 localWindow = currWindow;
1086
1087
1088
1091
1092
1093
1094
1095
1096
1097 now = lastWindow + sizeWindow;
1099
1100
1101
1104 FlushTime = localWindow + autoFlush;
1105 }
1107 nextEnt = 1;
1108}
1109
1110
1111
1112void XrdXrootdMonitor::Flush(XrdXrootdMonitor::MonRdrBuff *mP)
1113{
1114 int size;
1115
1116
1117
1118
1119 mP->flushIt = static_cast<int>(time(0)) + autoFlush;
1120 if (mP->nextEnt <= 1) return;
1121
1122
1123
1124 setTMurk(mP->Buff, mP->nextEnt, rdrTOD);
1125 mP->lastTOD = 0;
1126
1127
1128
1131
1132
1133
1135 mP->nextEnt = 0;
1136}
1137
1138
1139
1140
1141
1142void XrdXrootdMonitor::Mark()
1143{
1145
1146
1147
1148
1149 localWindow = currWindow;
1150
1151
1152
1153
1154
1155
1156
1157 if (
this !=
altMon && autoFlash && nextEnt > 1)
1159 static_cast<kXR_int32>(ntohl(monBuff->info[0].arg2.Window));
1160 if (localWindow - bufStartWindow >= autoFlash)
1161 {Flush();
1162 lastWindow = localWindow;
1163 return;
1164 }
1165 }
1166
1167
1168
1169
1170
1172 {
1173 monBuff->info[nextEnt-1].arg2.Window =
1174 static_cast<kXR_int32>(htonl(localWindow));
1175 }
1176 else if (nextEnt+8 > lastEnt)
1177 {
1178 Flush();
1179 }
1180 else
1181 {
1182 monBuff->info[nextEnt].arg0.val =
mySID;
1184 monBuff->info[nextEnt].arg1.Window =
1185 static_cast<kXR_int32>(htonl(lastWindow + sizeWindow));
1186 monBuff->info[nextEnt].arg2.Window =
1187 static_cast<kXR_int32>(htonl(localWindow));
1188 nextEnt++;
1189 }
1190 lastWindow = localWindow;
1191}
1192
1193
1194
1195
1196
1198{
1199#ifndef NODEBUG
1200 const char *TraceID = "Monitor";
1201#endif
1203 static int seq1=0, seq2=0;
1205 int rc1, rc2;
1206
1207
1208
1209
1211
1213 if (monMode & monMode1 && InetDest1)
1214 {
if (mHdr) mHdr->
pseq = (seq1++) & 0xff;
1215 rc1 = InetDest1->
Send((
char *)buff, blen);
1216 TRACE(
DEBUG,blen <<
" bytes sent to " <<Dest1 <<
" rc=" <<rc1);
1217 }
1218 else rc1 = 0;
1219 if (monMode & monMode2 && InetDest2)
1220 {
if (mHdr) mHdr->
pseq = (seq2++) & 0xff;
1221 rc2 = InetDest2->
Send((
char *)buff, blen);
1222 TRACE(
DEBUG,blen <<
" bytes sent to " <<Dest2 <<
" rc=" <<rc2);
1223 }
1224 else rc2 = 0;
1226
1227 return (rc1 ? rc1 : rc2);
1228}
1229
1230
1231
1232
1233
1234void XrdXrootdMonitor::startClock()
1235{
1237 time_t Now;
1238
1239
1240
1241 Now = time(0);
1242 currWindow =
static_cast<kXR_int32>(Now);
1243 rdrTOD = htonl(currWindow);
1245 FlushTime = autoFlush + currWindow;
1247}
int DoIt(int argpnt, int argc, char **argv, bool singleshot)
static XrdSysError eDest(0,"crypto_")
const kXR_char XROOTD_MON_DISC
const kXR_char XROOTD_MON_MAPUEAC
const kXR_char XROOTD_MON_MAPUSER
const kXR_char XROOTD_MON_APPID
const kXR_char XROOTD_MON_REDSID
union XrdXrootdMonRedir::@174 arg1
const kXR_char XROOTD_MON_MAPIDNT
const kXR_char XROOTD_MON_MAPTRCE
const kXR_char XROOTD_MON_CLOSE
const kXR_char XROOTD_MON_MAPPATH
const kXR_char XROOTD_MON_OPEN
const kXR_char XROOTD_MON_REDIRECT
const kXR_char XROOTD_MON_MAPTOKN
union XrdXrootdMonRedir::@172 arg0
const kXR_char XROOTD_MON_MAPREDR
#define setTMurk(TM_mb, TM_en, TM_tm)
#define setTMark(TM_mb, TM_en, TM_tm)
int Send(const char *buff, int blen=0, const char *dest=0, int tmo=-1)
static int Export(const char *Var, const char *Val)
static char * Ident(long long &mySID, char *iBuff, int iBlen, const char *iHost, const char *iProg, const char *iName, int Port)
void Schedule(XrdJob *jp)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
static void Defaults(int intv, int opts, int iocnt, int fbsz)
Hello(const char *dest, char mode)
void Register(const char *Uname, const char *Hname, const char *Pname, unsigned int xSID=0)
void Report(const char *Info)
void Set(XrdScheduler *sp, int intvl)
static XrdXrootdMonitor * altMon
static void Defaults(char *dest1, int m1, char *dest2, int m2)
void Disc(kXR_unt32 dictid, int csec, char Flags=0)
void Close(kXR_unt32 dictid, long long rTot, long long wTot)
static int Send(int mmode, void *buff, int size, bool setseq=true)
void Open(kXR_unt32 dictid, off_t fsize)
static kXR_unt32 GetDictID(bool hbo=false)