/******************************************************************************/
/* */
/* X r d F r m M o n i t o r . c c */
/* */
/* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include
#include
#include
#include "XrdFrc/XrdFrcTrace.hh"
#include "XrdFrm/XrdFrmMonitor.hh"
#include "XrdNet/XrdNetMsg.hh"
#include "XrdOuc/XrdOucUtils.hh"
#include "XrdSys/XrdSysError.hh"
#include "XrdSys/XrdSysPlatform.hh"
#include "XrdSys/XrdSysPthread.hh"
#include "XrdSys/XrdSysTimer.hh"
using namespace XrdFrc;
/******************************************************************************/
/* S t a t i c A l l o c a t i o n */
/******************************************************************************/
char *XrdFrmMonitor::Dest1 = 0;
int XrdFrmMonitor::monMode1 = 0;
XrdNetMsg *XrdFrmMonitor::InetDest1 = 0;
char *XrdFrmMonitor::Dest2 = 0;
int XrdFrmMonitor::monMode2 = 0;
XrdNetMsg *XrdFrmMonitor::InetDest2 = 0;
kXR_int32 XrdFrmMonitor::startTime = 0;
int XrdFrmMonitor::isEnabled = 0;
char *XrdFrmMonitor::idRec = 0;
int XrdFrmMonitor::idLen = 0;
int XrdFrmMonitor::sidSize = 0;
char *XrdFrmMonitor::sidName = 0;
int XrdFrmMonitor::idTime = 3600;
char XrdFrmMonitor::monMIGR = 0;
char XrdFrmMonitor::monPURGE = 0;
char XrdFrmMonitor::monSTAGE = 0;
/******************************************************************************/
/* T h r e a d I n t e r f a c e s */
/******************************************************************************/
void *XrdFrmMonitorID(void *parg)
{
XrdFrmMonitor::Ident();
return (void *)0;
}
/******************************************************************************/
/* D e f a u l t s */
/******************************************************************************/
void XrdFrmMonitor::Defaults(char *dest1, int mode1, char *dest2, int mode2,
int iTime)
{
// Make sure if we have a proper destinations and modes
//
if (dest1 && !mode1) {free(dest1); dest1 = 0; mode1 = 0;}
if (dest2 && !mode2) {free(dest2); dest2 = 0; mode2 = 0;}
// Propogate the destinations
//
if (!dest1)
{mode1 = (dest1 = dest2) ? mode2 : 0;
dest2 = 0; mode2 = 0;
}
// Set the default destinations (caller supplied strdup'd strings)
//
if (Dest1) free(Dest1);
Dest1 = dest1; monMode1 = mode1;
if (Dest2) free(Dest2);
Dest2 = dest2; monMode2 = mode2;
// Set overall monitor mode
//
monMIGR = ((mode1 | mode2) & XROOTD_MON_MIGR ? 1 : 0);
monPURGE = ((mode1 | mode2) & XROOTD_MON_PURGE ? 1 : 0);
monSTAGE = ((mode1 | mode2) & XROOTD_MON_STAGE ? 1 : 0);
// Do final check
//
isEnabled = (Dest1 == 0 && Dest2 == 0 ? 0 : 1);
idTime = iTime;
}
/******************************************************************************/
/* I d e n t */
/******************************************************************************/
void XrdFrmMonitor::Ident()
{
do{Send(-1, idRec, idLen);
XrdSysTimer::Snooze(idTime);
} while(1);
}
/******************************************************************************/
/* I n i t */
/******************************************************************************/
int XrdFrmMonitor::Init(const char *iHost, const char *iProg, const char *iName)
{
XrdXrootdMonMap *mP;
long long mySid;
const char *etext = 0;
char iBuff[1024];
bool aOK;
// Generate our server ID
//
sidName = XrdOucUtils::Ident(mySid, iBuff, sizeof(iBuff), iHost, iProg,
(iName ? iName : "anon"), 0);
sidSize = strlen(sidName);
startTime = htonl(time(0));
// There is nothing to do unless we have been enabled via Defaults()
//
if (!isEnabled) return 1;
// Create identification record
//
idLen = strlen(iBuff) + sizeof(XrdXrootdMonHeader) + sizeof(kXR_int32);
idRec = (char *)malloc(idLen+1);
mP = (XrdXrootdMonMap *)idRec;
fillHeader(&(mP->hdr), XROOTD_MON_MAPIDNT, idLen);
mP->hdr.pseq = 0;
mP->dictid = 0;
strcpy(mP->info, iBuff);
// Setup the primary destination
//
InetDest1 = new XrdNetMsg(&Say, Dest1, &aOK);
if (!aOK)
{Say.Emsg("Monitor", "setup monitor collector;", etext);
return 0;
}
// Do the same for the secondary destination
//
if (Dest2)
{InetDest2 = new XrdNetMsg(&Say, Dest2, &aOK);
if (!aOK)
{Say.Emsg("Monitor", "setup monitor collector;", etext);
return 0;
}
}
// Check if we will be producing identification records
//
if (idTime)
{pthread_t tid;
int retc;
if ((retc = XrdSysThread::Run(&tid,XrdFrmMonitorID,0,0,"mon ident")))
{Say.Emsg("Init", retc, "create monitor ident thread"); return 0;}
}
// All done
//
return 1;
}
/******************************************************************************/
/* M a p */
/******************************************************************************/
kXR_unt32 XrdFrmMonitor::Map(char code, const char *uname, const char *path)
{
XrdXrootdMonMap map;
const char *colonP, *atP;
char uBuff[1024];
int size, montype;
// Decode the user name as a.b:c@d
//
if ((colonP = index(uname, ':')) && (atP = index(colonP+1, '@')))
{int n = colonP - uname + 1;
strncpy(uBuff, uname, n);
strcpy(uBuff+n, sidName);
strcpy(uBuff+n+sidSize, atP);
} else strcpy(uBuff, uname);
// Copy in the username and path the dictid is always zero for us.
//
map.dictid = 0;
strcpy(map.info, uBuff);
size = strlen(uBuff);
if (path)
{*(map.info+size) = '\n';
strlcpy(map.info+size+1, path, sizeof(map.info)-size-1);
size = size + strlen(path) + 1;
}
// Route the packet to all destinations that need them
//
if (code == XROOTD_MON_MAPSTAG){montype = XROOTD_MON_STAGE;
code = XROOTD_MON_MAPXFER;
}
else if (code == XROOTD_MON_MAPMIGR){montype = XROOTD_MON_MIGR;
code = XROOTD_MON_MAPXFER;
}
else if (code == XROOTD_MON_MAPPURG) montype = XROOTD_MON_PURGE;
else montype = XROOTD_MON_INFO;
// Fill in the header and route the packet
//
size = sizeof(XrdXrootdMonHeader)+sizeof(kXR_int32)+size;
fillHeader(&map.hdr, code, size);
// cerr <<"Mon send "<code = static_cast(id);
hdr->pseq = static_cast(myseq);
hdr->plen = htons(static_cast(size));
hdr->stod = startTime;
}
/******************************************************************************/
/* S e n d */
/******************************************************************************/
int XrdFrmMonitor::Send(int monMode, void *buff, int blen)
{
EPNAME("Send");
static XrdSysMutex sendMutex;
int rc1, rc2;
sendMutex.Lock();
if (monMode & monMode1 && InetDest1)
{rc1 = InetDest1->Send((char *)buff, blen);
DEBUG(blen <<" bytes sent to " <