44#define getdents(fd, dirp, cnt) syscall(SYS_getdents, fd, dirp, cnt)
69 int XrdXrootdPrepare::scrubtime = 60*60;
70 int XrdXrootdPrepare::scrubkeep = 60*60*24;
71 char *XrdXrootdPrepare::LogDir = 0;
72 int XrdXrootdPrepare::LogDirLen = 0;
73const char *XrdXrootdPrepare::TraceID =
"Prepare";
80 bool nomsg) :
XrdJob(
"Prep log scrubber")
101 if (!LogDir)
return -1;
106 {
if (!(pargs.dirP =
opendir((
const char *)LogDir)))
107 {eDest->Emsg(
"List", errno,
"open prep log directory", LogDir);
110 if (pargs.
reqid) pargs.reqlen = strlen(pargs.
reqid);
111 if (pargs.
user) pargs.usrlen = strlen(pargs.
user);
117 while((dp =
readdir(pargs.dirP)))
118 {
if (!(up = (
char *) index((
const char *)dp->d_name,
'_')))
continue;
119 if (pargs.reqlen && pargs.
reqid
120 && strncmp(dp->d_name, pargs.
reqid, pargs.reqlen))
122 if (pargs.usrlen && pargs.
user)
123 if (!up || strcmp((
const char *)up+1,(
const char *)pargs.
user))
125 strcpy(path, (
const char *)LogDir);
126 strcpy(path+LogDirLen, (
const char *)dp->d_name);
127 if (
stat((
const char *)path, &buf))
continue;
129 if ((up = (
char *) index((
const char *)(up+1), (
int)
'_'))) *up =
' ';
131 if ((up = (
char *) index((
const char *)(up+1), (
int)
'_'))) *up =
' ';
133 return snprintf(resp, resplen-1,
"%s %lld",
134 dp->d_name, (
long long) buf.st_mtime);
140 eDest->Emsg(
"List", errno,
"read prep log directory", LogDir);
143 return (rc ? -1 : 0);
152 int rc, pnum = 0, xfd;
154 char buff[2048], blink[2048];
155 struct iovec iovec[2];
163 while(tp) {pnum++; tp = tp->
next;}
167 snprintf(buff,
sizeof(buff)-1,
"%s%s_%s_%d_%d", LogDir,
172 if ((xfd =
open(buff, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
173 {eDest->Emsg(
"Log", errno,
"open prep log file", buff);
179 iovec[1].iov_base = (
char *)
" ";
180 iovec[1].iov_len = 1;
183 {
if (tp->
next == 0) iovec[1].iov_base = (
char *)
"\n";
184 iovec[0].iov_base = tp->
text;
185 iovec[0].iov_len = strlen(tp->
text);
186 do {rc =
writev(xfd, (
const struct iovec *)iovec, 2);}
187 while(rc < 0 && errno == EINTR);
189 {eDest->Emsg(
"Log", errno,
"write prep log file", buff);
199 strcpy(blink, LogDir);
201 if (symlink((
const char *)buff, (
const char *)blink))
202 {eDest->Emsg(
"Log", errno,
"create symlink to prep log file", buff);
214 char path[MAXPATHLEN+256], buff[MAXPATHLEN+1];
218 if (!LogDir || strlen(reqid) > 255)
return;
222 strcpy(path, (
const char *)LogDir);
223 strcpy(&path[LogDirLen], (
const char *)reqid);
227 if ((rc = readlink((
const char *)path, buff,
sizeof(buff)-1)) < 0)
228 {
if (errno != ENOENT) eDest->Emsg(
"Logdel",errno,
"read symlink",path);
235 if (
unlink((
const char *)buff)
236 && errno != ENOENT) eDest->Emsg(
"Logdel",errno,
"remove",buff);
238 if (
unlink((
const char *)path)
239 && errno != ENOENT) eDest->Emsg(
"Logdel", errno,
"remove", path);
250 char path[MAXPATHLEN+264];
255 if (!LogDir)
return -ENOTSUP;
259 strcpy(path, (
const char *)LogDir);
260 strcpy(path+LogDirLen, reqid);
264 if ((fd =
open((
const char *)path, O_RDONLY)) < 0)
return -errno;
268 if (
fstat(fd, &buf) != 0) {
285 time_t stale = time(0) - scrubkeep;
286 char *up, path[2048], *fn = path+LogDirLen;
296 if (!(prepD =
opendir((
const char *)LogDir)))
297 {eDest->Emsg(
"Scrub", errno,
"open prep log directory", LogDir);
300 strcpy(path, (
const char *)LogDir);
306 {
if (!(up = (
char *) index((
const char *)dp->d_name,
'_')))
continue;
307 strcpy(fn, (
const char *)dp->d_name);
308 if (
stat((
const char *)path, &buf))
continue;
309 if (buf.st_mtime <= stale)
310 {
TRACE(
DEBUG,
"Scrub removed stale prep log " <<path);
311 unlink((
const char *)path);
312 *(fn+(up-dp->d_name)) =
'\0';
313 unlink((
const char *)path);
321 eDest->Emsg(
"List", errno,
"read prep log directory", LogDir);
330{
if (stime > 0) scrubtime = stime;
331 if (keep > 0) scrubkeep = keep;
347 if (
access((
const char *)ldir, X_OK | W_OK | R_OK) ||
stat(ldir, &buf))
349 if ((buf.st_mode & S_IFMT) != S_IFDIR)
return -ENOTDIR;
353 if (LogDir) free(LogDir);
357 if (path[plen-1] !=
'/') path[plen++] =
'/';
362 LogDir = strdup(path);
363 LogDirLen = strlen(LogDir);
XrdOucTrace * XrdXrootdTrace
friend class XrdScheduler
XrdJob(const char *desc="")
void Schedule(XrdJob *jp)
static int List(XrdXrootdPrepArgs &pargs, char *resp, int resplen)
static void Log(XrdXrootdPrepArgs &pargs)
static void Logdel(char *reqid)
static int setParms(int stime, int skeep)
XrdXrootdPrepare(XrdSysError *lp, XrdScheduler *sp, bool nomsg)
static int Open(const char *reqid, int &fsz)