166 ckpSize += dlen + segSZ;
170 theSeg.dataOfs = offset;
171 theSeg.dataLen = dlen;
180 ioV[0].iov_base = &theSeg;
181 ioV[0].iov_len = segSZ;
182 ioV[1].iov_base = (
void *)data;
183 ioV[1].iov_len = dlen;
187 retval =
writev(ckpFD, ioV, 2);
188 if (retval != (
int)(dlen+segSZ))
return (retval < 0 ? -errno : -EIO);
201 static const int oFlag = O_CREAT | O_EXCL | O_WRONLY;
202 static const int oMode = S_IRUSR | S_IWUSR | S_IRGRP;
209 if (ckpFD >= 0 || ckpFN)
return -EEXIST;
213 ckpFN = genCkpPath();
214 if (!ckpFN)
return -ENOMEM;
218 if ((ckpFD = XrdSysFD_Open(ckpFN, oFlag, oMode)) < 0
219 ||
XATTR.Set(attrName, srcFN, strlen(srcFN)+1, ckpFN, ckpFD) < 0)
221 if (ckpFD >= 0) {
close(ckpFD); ckpFD = -1;}
230 theHdr.lfnLen = strlen(srcFN) + 1;
231 theHdr.hdrLen = hdrSZ + theHdr.lfnLen;
232 theHdr.fSize =
Stat.st_size;
233 theHdr.mTime =
Stat.st_mtime;
234 memcpy(theHdr.srcUrl,
" file://",
sizeof(theHdr.srcUrl));
235 memset(theHdr.rsvd, 0,
sizeof(theHdr.rsvd));
244 ioV[0].iov_base = &theHdr;
245 ioV[0].iov_len =
sizeof(theHdr);
246 ioV[1].iov_base = (
void *)srcFN;
247 ioV[1].iov_len = theHdr.lfnLen;
248 ckpSize =
sizeof(theHdr) + theHdr.lfnLen;
252 retval =
writev(ckpFD, ioV, 2);
253 if (retval != ckpSize) rc = (retval < 0 ? -errno : -EIO);
254 else if (
fsync(ckpFD)) rc = -errno;
359 if (dlen < 0 || nseg < 0 || ckpFD < 0)
return false;
368 fstore_t Store = {F_ALLOCATEALL, F_PEOFPOSMODE, ckpSize, dlen, 0};
369 if (fcntl(ckpFD, F_PREALLOCATE, &Store) == -1
370 &&
ftruncate(ckpFD, ckpSize + dlen) == -1)
return false;
372 if (posix_fallocate(ckpFD, ckpSize, dlen))
389 std::vector<XrdOucIOVec> vecIO;
392 char *ckpRec, *ckpEnd;
400 if ((cup.fd = XrdSysFD_Open(ckpFN, O_RDONLY)) < 0)
401 {
if (errno == ENOENT)
return -ENOENT;
402 eWhy =
"open failed";
403 return getSrcLfn(ckpFN, rinfo, cup.fd, errno);
409 {eWhy =
"stat failed";
410 return getSrcLfn(ckpFN, rinfo, cup.fd, errno);
415 if (
Stat.st_size == 0)
return getSrcLfn(ckpFN, rinfo, cup.fd,
ENODATA);
419 if (
Stat.st_size < hdrSZ+1)
420 {eWhy =
"truncated header";
421 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
426 if (!(ckpRec = (
char *)malloc(
Stat.st_size)))
427 return getSrcLfn(ckpFN, rinfo, cup.fd, ENOMEM);
428 rinfo.rBuff = ckpRec;
432 if ((retval =
read(cup.fd, ckpRec,
Stat.st_size)) !=
Stat.st_size)
433 {eWhy =
"read failed";
434 return getSrcLfn(ckpFN, rinfo, cup.fd, (retval < 0 ? errno : EIO));
441 cpHdr &theHdr = *((cpHdr *)ckpRec);
442 if (theHdr.hdrLen >
Stat.st_size
443 || (theHdr.hdrLen - theHdr.lfnLen) != (
int)hdrSZ)
444 {eWhy =
"corrupted header";
445 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
451 {eWhy =
"header checksum mismatch";
452 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
457 rinfo.
srcLFN = ckpRec+hdrSZ;
458 rinfo.
fSize = theHdr.fSize;
459 rinfo.
mTime = theHdr.mTime;
463 ckpEnd = ckpRec +
Stat.st_size;
464 ckpRec = ckpRec + theHdr.hdrLen;
470 aOK =
false; eWhy = 0;
471 while(ckpRec+
sizeof(cpSeg) < ckpEnd)
472 {memcpy(&theSeg, ckpRec, segSZ);
473 if (!theSeg.dataLen && !theSeg.dataOfs && !theSeg.crc32C)
477 char *ckpData = ckpRec + segSZ;
478 if (theSeg.dataLen <= 0 || ckpData + theSeg.dataLen > ckpEnd)
break;
479 int cLen = theSeg.dataLen+
sizeof(cpSeg)-crcSZ;
481 {eWhy =
"data checksum mismatch";
484 ioItem.offset = theSeg.dataOfs;
485 ioItem.size = theSeg.dataLen;
486 ioItem.data = ckpRec + segSZ;
487 rinfo.
DataLen += theSeg.dataLen;
488 vecIO.push_back(ioItem);
489 ckpRec += (segSZ + theSeg.dataLen);
495 if (!aOK && ckpRec != ckpEnd)
496 {
if (!eWhy) eWhy =
"truncated file";
503 if (!vecIO.size())
return 0;
508 int j = vecIO.size() - 1;
509 for (
int i = 0; i < (int)vecIO.size(); i++) ioV[j--] = vecIO[i];
534 struct {cpHdr hdr;
char srcfn[MAXPATHLEN+8];} ckpRec;
536 const char *
eMsg =
"Target unknown; corrupt checkpoint file";
541 if ((n =
XATTR.Get(attrName,ckpRec.srcfn,
sizeof(ckpRec.srcfn)-1,ckpfn)) > 0)
542 {ckpRec.srcfn[n] = 0;
543 return strdup(ckpRec.srcfn);
548 if ((cup.fd = XrdSysFD_Open(ckpfn, O_RDONLY)) < 0)
550 snprintf(buff,
sizeof(buff),
"Target unknown; %s",
XrdSysE2T(errno));
556 if ((n =
read(cup.fd, &ckpRec,
sizeof(ckpRec))) <= (
int)
sizeof(cpHdr))
561 if (ckpRec.hdr.lfnLen <= 1 || ckpRec.hdr.lfnLen > (
int)MAXPATHLEN)
566 ckpRec.srcfn[ckpRec.hdr.lfnLen-1] = 0;
567 return strdup(ckpRec.srcfn);