37 #include <sys/param.h>
38 #include <sys/types.h>
64 int XrdFrcCID::Add(
const char *iName,
const char *cName, time_t addT, pid_t Pid)
72 if (!(cP = Find(iName)))
73 {First =
new cidEnt(First, iName, cName, addT, Pid);
74 if (!strcmp(iName,
"anon")) Dflt = First;
81 if (cP->addT >= addT)
return 0;
85 if (strcmp(cP->cName, cName))
87 cP->cName = strdup(cName);
88 cP->cNLen = strlen(cName);
91 if (cP->Pid != Pid) {cP->Pid = Pid; ckp = 1;}
101 XrdFrcCID::cidEnt *XrdFrcCID::Find(
const char *iName)
107 if (!iName || !(*iName))
return Dflt;
113 while(cP && strcmp(iName, cP->iName)) cP = cP->Next;
131 if (!(cP = Find(iName))) {*buff = 0;
return 0;}
135 strlcpy(buff, cP->cName, blen);
147 if (!(cP = Find(iName)))
return 0;
151 if (vName && evP) evP->
Put(vName, cP->cName);
163 char Path[1024], *lP, *Pfn;
164 int cidFD, n, NoGo = 0;
170 if (
Path[n-1] !=
'/')
Path[n++] =
'/';
172 strcpy(Pfn,
"CIDS.new"); cidFN2 = strdup(
Path);
173 strcpy(Pfn,
"CIDS"); cidFN = strdup(
Path);
177 if ( (cidFD =
open(cidFN, O_RDONLY, 0)) < 0)
178 {
if (errno == ENOENT)
return 0;
179 Say.
Emsg(
"Init", errno,
"open cluster chkpnt file", cidFN);
186 while((lP = cidFile.
GetLine()))
188 {
DEBUG(
"Recovering cid entry: " <<lP);
189 NoGo |= Init(cidFile);
194 if (NoGo)
Say.
Emsg(
"Init",
"Errors processing chkpnt file", cidFN);
196 NoGo =
Say.
Emsg(
"Init", n,
"read cluster chkpnt file", cidFN);
209 char *iP, *cP, *tP, *uP;
216 {
Say.
Emsg(
"Init",
"Missing cluster instance name.");
return 1;}
218 {
Say.
Emsg(
"Init",
"Missing cluster name for", iP);
return 1;}
220 {
Say.
Emsg(
"Init",
"Missing timestamp for", iP);
return 1;}
221 addT =
static_cast<time_t
>(strtoll(tP, &uP, 10));
223 {
Say.
Emsg(
"Init",
"Invalid timestamp for", iP);
return 1;}
225 {
Say.
Emsg(
"Init",
"Missing process id for", iP);
return 1;}
226 Pid =
static_cast<pid_t
>(strtol(tP, &uP, 10));
228 {
Say.
Emsg(
"Init",
"Invalid process id for", iP);
return 1;}
232 if (Pid && kill(Pid, 0) < 0 && errno == ESRCH)
233 {
DEBUG(
"Process " <<Pid <<
" not found for instance " <<iP);
239 First =
new cidEnt(First, iP, cP, addT, Pid);
240 if (!strcmp(iP,
"anon")) Dflt = First;
255 if ((cP = Find(iName))) cP->useCnt = 1;
262 int XrdFrcCID::Update()
265 static char buff[40];
266 static const int Mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
267 static struct iovec
iov[] = {{0,0}, {(
char *)
" ", 1},
270 static const int iovn =
sizeof(
iov)/
sizeof(
struct iovec);
272 cidEnt *cP = First, *cPP = 0, *cPN;
277 if ((cidFD = XrdSysFD_Open(cidFN2, O_RDWR|O_CREAT,
Mode)) < 0)
278 {
Say.
Emsg(
"Init",errno,
"open",cidFN2);
284 bzero(&lock_args,
sizeof(lock_args));
285 lock_args.l_type = F_WRLCK;
286 do {rc =
fcntl(cidFD,F_SETLKW,&lock_args);}
while(rc < 0 && errno == EINTR);
288 {
Say.
Emsg(
"Update", errno,
"lock", cidFN2);
296 {
Say.
Emsg(
"Update", errno,
"truncate", cidFN2);
304 {
if (!(cP->Pid) && !(cP->useCnt) && strcmp(cP->iName,
"anon"))
305 {
DEBUG(
"Removing dead instance " <<cP->iName);
306 if (cPP) cPN = cPP->Next = cP->Next;
307 else cPN = First = cP->Next;
312 iov[0].iov_base = cP->iName;
iov[0].iov_len = cP->iNLen;
313 iov[2].iov_base = cP->cName;
iov[2].iov_len = cP->cNLen;
314 iov[3].iov_len = sprintf(buff,
" %ld %d",
315 static_cast<long>(cP->addT),
316 static_cast<int> (cP->Pid)) + 1;
318 {
Say.
Emsg(
"Update", errno,
"writing", cidFN2);
322 cPP = cP; cP = cP->Next;
327 if (
rename(cidFN2, cidFN) < 0)
328 {
Say.
Emsg(
"Update", errno,
"rename", cidFN2);
int ftruncate(int fildes, off_t offset)
int open(const char *path, int oflag,...)
int fcntl(int fd, int cmd,...)
int rename(const char *oldpath, const char *newpath)
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt)
int Add(const char *iName, const char *cName, time_t addT, pid_t Pid)
int Get(const char *iName, char *buff, int blen)
int Init(const char *qPath)
void Ref(const char *iName)
void Put(const char *varname, const char *value)
int Attach(int FileDescriptor, int bsz=2047)
char * GetToken(int lowcase=0)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)