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();
217 if ((ckpFD = XrdSysFD_Open(ckpFN, oFlag, oMode)) < 0
218 ||
XATTR.Set(attrName, srcFN, strlen(srcFN)+1, ckpFN, ckpFD) < 0)
220 if (ckpFD >= 0) {
close(ckpFD); ckpFD = -1;}
228 theHdr.lfnLen = strlen(srcFN) + 1;
229 theHdr.hdrLen = hdrSZ + theHdr.lfnLen;
230 theHdr.fSize =
Stat.st_size;
231 theHdr.mTime =
Stat.st_mtime;
232 memcpy(theHdr.srcUrl,
" file://",
sizeof(theHdr.srcUrl));
233 memset(theHdr.rsvd, 0,
sizeof(theHdr.rsvd));
242 ioV[0].iov_base = &theHdr;
243 ioV[0].iov_len =
sizeof(theHdr);
244 ioV[1].iov_base = (
void *)srcFN;
245 ioV[1].iov_len = theHdr.lfnLen;
246 ckpSize =
sizeof(theHdr) + theHdr.lfnLen;
250 retval =
writev(ckpFD, ioV, 2);
251 if (retval != ckpSize) rc = (retval < 0 ? -errno : -EIO);
252 else if (
fsync(ckpFD)) rc = -errno;
357 if (dlen < 0 || nseg < 0 || ckpFD < 0)
return false;
366 fstore_t Store = {F_ALLOCATEALL, F_PEOFPOSMODE, ckpSize, dlen, 0};
367 if (
fcntl(ckpFD, F_PREALLOCATE, &Store) == -1
368 &&
ftruncate(ckpFD, ckpSize + dlen) == -1)
return false;
370 if (posix_fallocate(ckpFD, ckpSize, dlen))
387 std::vector<XrdOucIOVec> vecIO;
390 char *ckpRec, *ckpEnd;
398 if ((cup.fd = XrdSysFD_Open(ckpFN, O_RDONLY)) < 0)
399 {
if (errno == ENOENT)
return -ENOENT;
400 eWhy =
"open failed";
401 return getSrcLfn(ckpFN, rinfo, cup.fd, errno);
407 {eWhy =
"stat failed";
408 return getSrcLfn(ckpFN, rinfo, cup.fd, errno);
413 if (
Stat.st_size == 0)
return getSrcLfn(ckpFN, rinfo, cup.fd,
ENODATA);
417 if (
Stat.st_size < hdrSZ+1)
418 {eWhy =
"truncated header";
419 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
424 if (!(ckpRec = (
char *)malloc(
Stat.st_size)))
425 return getSrcLfn(ckpFN, rinfo, cup.fd, ENOMEM);
426 rinfo.rBuff = ckpRec;
430 if ((retval =
read(cup.fd, ckpRec,
Stat.st_size)) !=
Stat.st_size)
431 {eWhy =
"read failed";
432 return getSrcLfn(ckpFN, rinfo, cup.fd, (retval < 0 ? errno : EIO));
439 cpHdr &theHdr = *((cpHdr *)ckpRec);
440 if (theHdr.hdrLen >
Stat.st_size
441 || (theHdr.hdrLen - theHdr.lfnLen) != (
int)hdrSZ)
442 {eWhy =
"corrupted header";
443 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
449 {eWhy =
"header checksum mismatch";
450 return getSrcLfn(ckpFN, rinfo, cup.fd, EDOM);
455 rinfo.
srcLFN = ckpRec+hdrSZ;
456 rinfo.
fSize = theHdr.fSize;
457 rinfo.
mTime = theHdr.mTime;
461 ckpEnd = ckpRec +
Stat.st_size;
462 ckpRec = ckpRec + theHdr.hdrLen;
468 aOK =
false; eWhy = 0;
469 while(ckpRec+
sizeof(cpSeg) < ckpEnd)
470 {memcpy(&theSeg, ckpRec, segSZ);
471 if (!theSeg.dataLen && !theSeg.dataOfs && !theSeg.crc32C)
475 char *ckpData = ckpRec + segSZ;
476 if (theSeg.dataLen <= 0 || ckpData + theSeg.dataLen > ckpEnd)
break;
477 int cLen = theSeg.dataLen+
sizeof(cpSeg)-crcSZ;
479 {eWhy =
"data checksum mismatch";
482 ioItem.offset = theSeg.dataOfs;
483 ioItem.size = theSeg.dataLen;
484 ioItem.data = ckpRec + segSZ;
485 rinfo.
DataLen += theSeg.dataLen;
486 vecIO.push_back(ioItem);
487 ckpRec += (segSZ + theSeg.dataLen);
493 if (!aOK && ckpRec != ckpEnd)
494 {
if (!eWhy) eWhy =
"truncated file";
501 if (!vecIO.size())
return 0;
506 int j = vecIO.size() - 1;
507 for (
int i = 0; i < (int)vecIO.size(); i++) ioV[j--] = vecIO[i];
532 struct {cpHdr hdr;
char srcfn[MAXPATHLEN+8];} ckpRec;
534 const char *
eMsg =
"Target unknown; corrupt checkpoint file";
539 if ((n =
XATTR.Get(attrName,ckpRec.srcfn,
sizeof(ckpRec.srcfn)-1,ckpfn)) > 0)
540 {ckpRec.srcfn[n] = 0;
541 return strdup(ckpRec.srcfn);
546 if ((cup.fd = XrdSysFD_Open(ckpfn, O_RDONLY)) < 0)
548 snprintf(buff,
sizeof(buff),
"Target unknown; %s",
XrdSysE2T(errno));
554 if ((n =
read(cup.fd, &ckpRec,
sizeof(ckpRec))) <= (
int)
sizeof(cpHdr))
559 if (ckpRec.hdr.lfnLen <= 1 || ckpRec.hdr.lfnLen > (
int)MAXPATHLEN)
564 ckpRec.srcfn[ckpRec.hdr.lfnLen-1] = 0;
565 return strdup(ckpRec.srcfn);