40 #include <sys/param.h>
42 #include <sys/types.h>
92 std::set<std::string> bkpScopes;
103 BkpUtilPath = strdup(
"XrdOssArc_BkpUtils");
104 BkpUtilName = BkpUtilPath;
112 ArchiverPath= strdup(
"XrdOssArc_Archiver");
113 ArchiverName= ArchiverPath;
116 MssComPath = strdup(
"XrdOssArc_MssCom");
117 MssComName = MssComPath;
121 arcvPathLFN = strdup(
"/archive/");
122 arcvPathLEN = strlen(arcvPathLFN);
123 bkupPathLFN = strdup(
"/backup/");
124 bkupPathLEN = strlen(bkupPathLFN);
125 dsetPathLFN = strdup(
"/dataset/");
129 if ((atmp = getenv(
"XRDADMINPATH")))
130 {std::string as = atmp;
131 if (as.back() !=
'/') as.append(
"/");
132 as.append(
"OssArc/");
133 admnPath = strdup(as.c_str());
137 srcData = strdup(
"");
138 stagePath = strdup(
"/tmp/stage");
139 tapePath = strdup(
"/TapeBuffer");
140 tapePathLEN = strlen(tapePath);
141 utilsPath = strdup(
"/usr/local/etc");
145 metaBKP =
"arcBackup";
146 metaIDX =
"arcIndex";
151 manCKS = strdup(
"adler32");
160 arFName = strdup(
"Archive.zip");
161 arfSfx = strdup(
".zip");
171 if (getenv(
"XRDOSSARC_DEBUG") || getenv(
"XRDDEBUG"))
180 const char* addP,
char*& destP,
int mode)
182 char lclPath[MAXPATHLEN];
187 if ((rc = GenLocalPath(baseP, lclPath,
sizeof(lclPath))))
188 {
Elog.
Emsg(
"Config", rc,
"configure", what);
194 std::string tmpStr(lclPath);
198 while(tmpStr.back() ==
'/') tmpStr.pop_back();
202 if (addP) tmpStr.append(addP);
206 char* modStr = strdup(tmpStr.c_str());
213 {std::string msgT(
"create ");
215 Elog.
Emsg(
"Config", rc, msgT.c_str(), tmpStr.c_str());
239 if (!ConfigXeq(cfn, parms,
envP))
return false;
248 if (dstRSE && srcRSE)
251 DEBUG(
"exporting XRDOSSARC_DSTRSE="<<dstRSE);
253 DEBUG(
"exporting XRDOSSARC_SRCRSE="<<srcRSE);
257 needBKP = strdup(tmp.c_str());
260 doneBKP = strdup(tmp.c_str());
262 Elog.
Say(
"Config mistake: required 'rsedcl' directive not specified!");
278 snprintf(buff,
sizeof(buff),
"%lld %lld %lld %d", arcSZ_Want,
279 arcSZ_MinV, arcSZ_MaxV, (
int)arcSZ_Skip);
287 if (rc) {
Elog.
Emsg(
"Config", rc,
"create admin path", admnPath);
290 else if (!Usable(admnPath,
"admin path",
false)) NoGo =
true;
295 if (!stopPath) stopPath = admnPath;
296 else {std::string ss = stopPath;
297 if (ss.back() !=
'/')
300 stopPath = strdup(ss.c_str());
307 {
Elog.
Emsg(
"Config",
"Unable to determine the stopfile path!");
310 if (!Usable(stopPath,
"stopfile path",
false)) NoGo =
true;
324 if (!Usable(tapePath,
"tape buffer path",
false)) NoGo =
true;
325 tapePathLEN = strlen(tapePath);
331 if (bkpFSt < 30) bkpFSt = 30;
333 if (!
fsMon.
Init(tapePath, bkpMinF, bkpFSt)) NoGo =
true;
340 {
Elog.
Emsg(
"Config", errno,
"use srcdata path", srcData);
347 if (!
BuildPath(
"dataset backup arena", dsetPathLFN,
"/4bkp/",
348 dsetRepoPFN, S_IRWXU|S_IRGRP|S_IXGRP))
355 ConfigPath(&BkpUtilPath, utilsPath);
356 if (BkpUtilProg->Setup(BkpUtilPath)) NoGo =
true;
357 else {
const char* rslash = rindex(BkpUtilPath,
'/');
358 BkpUtilName = (rslash ? rslash+1 : BkpUtilPath);
364 ConfigPath(&MssComPath, utilsPath);
365 if (MssComProg->Setup(MssComPath)) NoGo =
true;
366 else {
const char* rslash = rindex(MssComPath,
'/');
367 MssComName = (rslash ? rslash+1 : MssComPath);
374 DEBUG(
"Exporting XRDOSSARC_MSSCMD="<<MssComCmd);
378 DEBUG(
"exporting XRDOSSARC_MSSROOT="<<MssComRoot);
379 }
else MssComRoot = strdup(
"");
385 ConfigPath(&PrepArcPath, utilsPath);
386 if (PrepArcProg->Setup(PrepArcPath)) NoGo =
true;
387 else {
const char* rslash = rindex(PrepArcPath,
'/');
388 PrepArcName = (rslash ? rslash+1 : PrepArcPath);
390 }
else PrepArcProg = 0;
396 ConfigPath(&PostArcPath, utilsPath);
397 if (PostArcProg->Setup(PostArcPath)) NoGo =
true;
398 else {
const char* rslash = rindex(PostArcPath,
'/');
399 PostArcName = (rslash ? rslash+1 : PostArcPath);
403 PostArcName = PostArcPath = strdup(
"");
409 ConfigPath(&ArchiverPath, utilsPath);
410 if (ArchiverProg->Setup(ArchiverPath)) NoGo =
true;
411 else {
const char* rslash = rindex(ArchiverPath,
'/');
412 ArchiverName = (rslash ? rslash+1 : ArchiverPath);
418 {
if (ArchiverSave) free(ArchiverSave);
419 ArchiverSave = strdup(
"");
421 if (!ArchiverSave) ArchiverSave = MssComPath;
422 else ConfigPath(&ArchiverSave, utilsPath);
423 DEBUG(
"Archiver remote copycmd="<<ArchiverSave);
428 DEBUG(
"Running "<<BkpUtilName<<
" addkey "<<metaBKP<<
' '<<metaIDX);
429 if (BkpUtilProg->Run(
"addkey", metaBKP, metaIDX))
430 Elog.
Emsg(
"Config",
"Unable to create/verify metadata keys; continuing...");
434 std::vector<XrdOssArcBackup*> bkpVec;
436 if (bkpScopes.empty())
437 {
Elog.
Emsg(
"Config",
"No backup scopes specified!"); NoGo =
true;
440 for (
auto it = bkpScopes.begin(); it != bkpScopes.end(); ++it)
444 Elog.
Emsg(
"Config",
"Unable to start backing up scope",
447 }
else bkpVec.push_back(bkpP);
457 for (
auto it = bkpVec.begin(); it != bkpVec.end(); it++)
458 {
Elog.
Say(
"Config process: scheduling backup for scope ",
473 void XrdOssArcConfig::ConfigPath(
char** pDest,
const char* pRoot)
477 if ((*pDest)[0] !=
'/')
478 {std::string tmp(pRoot);
479 if (tmp.back() !=
'/') tmp +=
'/';
482 *pDest = strdup(tmp.c_str());
490 bool XrdOssArcConfig::ConfigProc(
const char* drctv)
495 if (!strcmp(drctv,
"arcsize"))
return xqArcsz();
496 else if (!strcmp(drctv,
"backup"))
return xqBkup();
497 else if (!strcmp(drctv,
"manifest"))
return xqManf();
498 else if (!strcmp(drctv,
"msscmd"))
499 return xqGrab(
"msscmd", MssComCmd, Conf->LastLine());
500 else if (!strcmp(drctv,
"paths"))
return xqPaths();
501 else if (!strcmp(drctv,
"rsedcl"))
return xqRse();
502 else if (!strcmp(drctv,
"rucio"))
return xqRucio();
503 else if (!strcmp(drctv,
"stage"))
return xqStage();
504 else if (!strcmp(drctv,
"trace"))
return xqTrace();
505 else if (!strcmp(drctv,
"utils"))
return xqUtils();
506 else Conf->MsgfW(
"ignoring unknown directive '%s'", drctv);
516 bool XrdOssArcConfig::ConfigXeq(
const char* cfName,
const char* parms,
527 return (rc < 0 ?
false :
true);
537 while(Cfile.GetLine())
538 {
if ((token = Cfile.GetToken()))
539 {
if (!strncmp(token,
"ossarc.", 7)) token += 7;
540 NoGo |= !ConfigProc(token);
553 int XrdOssArcConfig::GenLocalPath(
const char* dsn,
char* buff,
int bSZ)
560 {
Elog.
Emsg(
"Archive", rc,
"generate local path for", dsn);
570 bool XrdOssArcConfig::MissArg(
const char* what)
572 Conf->MsgfE(
"%s not specified.", what);
580 bool XrdOssArcConfig::Usable(
const char* path,
const char* what,
bool useOss)
586 else if ((rc =
stat(path, &
Stat))) rc = errno;
590 snprintf(buff,
sizeof(buff),
"use %s", what);
591 Elog.
Emsg(
"Config", rc, buff, path);
597 if (!S_ISDIR(
Stat.st_mode))
598 {
Elog.
Emsg(
"Config", what, path,
"is not a directory!");
604 if ( ((
Stat.st_mode & S_IWOTH) == 0)
605 && ((
Stat.st_mode & S_IWUSR) != 0 && (
Stat.st_uid != geteuid()))
606 && ((
Stat.st_mode & S_IWGRP) != 0 && (
Stat.st_uid != getegid())))
607 {
Elog.
Emsg(
"Config", what, path,
"is not writable!");
613 if ( ( (
Stat.st_mode & S_IXOTH) == 0)
614 && ( (
Stat.st_mode & S_IXUSR) != 0 && (
Stat.st_uid != geteuid()))
615 && ( (
Stat.st_mode & S_IXGRP) != 0 && (
Stat.st_uid != getegid())))
616 {
Elog.
Emsg(
"Config", what, path,
"is not searchable!");
635 long long minV,
long long maxV)
642 {Conf->
MsgE(what,
"value not specified!");
return false;}
657 bool XrdOssArcConfig::xqArcsz()
659 static const long long MinV = 104857600LL;
660 static const long long MaxV = 500*1073741824LL;
663 long long tVal, minVal = 0, maxVal = 0;
667 if (!getVal(Conf,
"arcsize target", tVal, MinV, MaxV))
return false;
672 {
if (!strcmp(token,
"range"))
673 {
if (!getVal(Conf,
"arcsize range minimum", minVal, MinV, MaxV))
675 if (!getVal(Conf,
"arcsize range maximum", maxVal, MinV, MaxV))
678 {Conf->
MsgE(
"arcsize range minimum is greater than maximum!");
681 if (tVal < minVal || tVal > maxVal)
682 {Conf->
MsgE(
"arcsize target value out of specified range!");
685 }
else if (!strcmp(token,
"skip"))
688 Conf->
MsgE(
"Invalid arcsize option -", token);
719 bool XrdOssArcConfig::xqBkup()
721 static const int isN = 0;
722 static const int isT = 1;
723 static const int isPS = 2;
724 static const int isM = 3;
726 struct bkpopts {
const char *opname;
int* oploc;
int minv;
int isX;}
729 {
"check", &stopChk, 5, isT},
730 {
"fscan", &bkpFSt, 30, isT},
731 {
"max", &bkpMax, 1, isN},
732 {
"minfree", 0, 1, isPS},
734 {
"poll", &bkpPoll, 60, isT},
735 {
"scope", 0, -1, isN}
737 int numopts =
sizeof(bkpopt)/
sizeof(
struct bkpopts);
744 {Conf->
MsgfE(
"no backup arguments specified!");
return false;}
748 do{
for (i = 0; i < numopts; i++)
749 {
if (!strcmp(token, bkpopt[i].opname))
750 {
if (bkpopt[i].minv == -1)
return xqBkupScope();
751 int* val = bkpopt[i].oploc;
752 int minv = bkpopt[i].minv;
754 if (!(tval = Conf->
GetToken()) || !(*tval))
755 {Conf->
MsgE(
"backup", token,
"value not specified!");
759 if (bkpopt[i].isX == isM)
760 {
if (!strcmp(
"remote", tval)) bkpLocal =
false;
761 else if (!strcmp(
"local", tval)) bkpLocal =
true;
762 else {Conf->
MsgfE(
"Invalid backup mode '%s'.", token);
768 if (bkpopt[i].isX == isPS)
769 {
if (!xqBkupPS(tval))
return false;
773 if (bkpopt[i].isX == isT)
789 {Conf->
MsgfE(
"Unknown backup option '%s'.", token);
return false;}
791 }
while((token = Conf->
GetToken()));
802 bool XrdOssArcConfig::xqBkupPS(
char* tval)
804 int n = strlen(tval);
808 if (tval[n-1] ==
'%')
830 bool XrdOssArcConfig::xqBkupScope()
834 if (!scope || !(*scope))
835 {Conf->
MsgfE(
"backup scope not specified!");
return false;}
837 do{
auto rslt = bkpScopes.insert(std::string(scope));
839 Conf->
MsgW(
"backup scope", scope,
"previously specified.");
841 }
while(scope && *scope);
850 bool XrdOssArcConfig::xqGrab(
const char* what,
char*& theDest,
857 if ((tP = index(theLine,
' ')))
while(*tP ==
' ') tP++;
859 {Conf->
MsgfE(
"%s argument not specified!", what);
865 if (theDest) free(theDest);
866 theDest = strdup(tP);
877 bool XrdOssArcConfig::xqManf()
883 {Conf->
MsgfE(
"No manifest parameters specified!");
889 do {
if (!strcmp(
"cksum", token)) tDest = &manCKS;
890 else {Conf->
MsgfE(
"Unknown manifest parameter '%s'; ignored.", token);
894 {Conf->
MsgfE(
"%s argument not specified!", token);
897 if (*tDest) free(*tDest);
898 *tDest = strdup(targ);
899 }
while((token = Conf->
GetToken()));
914 bool XrdOssArcConfig::xqPaths()
922 {
if (!strcmp(
"backing", token)) pDest = &tapePath;
923 else if (!strcmp(
"mssfs", token)) pDest = &MssComRoot;
924 else if (!strcmp(
"mssroot", token)) pDest = &MssComRoot;
925 else if (!strcmp(
"srcdata", token)) pDest = &srcData;
926 else if (!strcmp(
"staging", token)) pDest = &stagePath;
927 else if (!strcmp(
"stopfile", token)) pDest = &stopPath;
928 else if (!strcmp(
"utils", token)) pDest = &utilsPath;
929 else {Conf->
MsgfE(
"Unknown path type '%s'; ignored.", token);
934 {Conf->
MsgfE(
"%s path not specified!", token);
941 {Conf->
MsgfE(
"%s path is not absolute!", token);
945 if (*pDest) free(*pDest);
946 *pDest = strdup(ploc);
951 if (!pDest) {Conf->
MsgfE(
"no 'path' arguments specified!");
return false;}
964 bool XrdOssArcConfig::xqRse()
971 {Conf->
MsgfE(
"source rse name not specified!");
return false;}
975 if (srcRSE) free(srcRSE);
976 srcRSE = strdup(token);
981 {Conf->
MsgfE(
"destination rse name not specified!");
return false;}
985 if (dstRSE) free(dstRSE);
986 dstRSE = strdup(token);
999 bool XrdOssArcConfig::xqRucio()
1007 {Conf->
MsgfE(
"rucio parameter not specified!");
return false;}
1011 do{
if (!strcmp(token,
"maxitems"))
1016 Conf->
MsgfE(
"Invalid rucio parameter, '%s'!", token);
1019 }
while((token = Conf->
GetToken()));
1025 else Conf->
MsgfE(
"rucio %s parameter value not specified.", token);
1041 bool XrdOssArcConfig::xqStage()
1043 static const int minStg = 1, maxStg = 100, minPoll = 5, maxPoll = 100;
1050 {Conf->
MsgfE(
"No stage parameters specified");
1057 {
if (!strcmp(val,
"max"))
1058 {
if (!(val = Conf->
GetToken()))
return MissArg(
"'max' value");
1061 if (rc) {Conf->
EchoLine();
return false;}
1064 else if (!strcmp(val,
"poll"))
1065 {
if (!(val = Conf->
GetToken()))
return MissArg(
"'poll' value");
1068 if (rc) {Conf->
EchoLine();
return false;}
1071 else {Conf->
MsgE(
"unknown option -", val);
1085 bool XrdOssArcConfig::xqTrace()
1088 struct traceopts {
const char *opname;
unsigned int opval;} tropts[] =
1096 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
1099 {Conf->
MsgE(
"no trace options specified");
1103 {
if (!strcmp(val,
"off")) trval = 0;
1104 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
1105 for (i = 0; i < numopts; i++)
1106 {
if (!strcmp(val, tropts[i].opname))
1108 if (tropts[i].opval) trval &= ~tropts[i].opval;
1110 else if (tropts[i].opval) trval |= tropts[i].opval;
1116 Conf->
MsgfW(
"ignoring invalid trace option '%s'", val);
1132 bool XrdOssArcConfig::xqUtils()
1140 {
if (!strcmp(
"archiver", token)) uDest = &ArchiverPath;
1141 else if (!strcmp(
"bkputils", token)) uDest = &BkpUtilPath;
1142 else if (!strcmp(
"msscom", token)) uDest = &MssComPath;
1143 else if (!strcmp(
"postarc", token)) uDest = &PostArcPath;
1144 else if (!strcmp(
"preparc", token)) uDest = &PrepArcPath;
1145 else if (!strcmp(
"saver", token)) uDest = &ArchiverSave;
1146 else {Conf->
MsgfW(
"Unknown util '%s'; ignored.", token);
1151 {Conf->
MsgfE(
"utils %s value not specified!", token);
1154 if (*uDest) free(*uDest);
1155 *uDest = strdup(uloc);
1160 if (!uDest) {Conf->
MsgE(
"no 'utils' arguments specified!");
return false;}
XRootDStatus BuildPath(std::string &newPath, Env *env, const std::string &path)
static void StartWorkers(int maxw)
bool BuildPath(const char *what, const char *baseP, const char *addP, char *&destP, int mode=0)
bool Configure(const char *cfn, const char *parms, XrdOucEnv *envP)
bool Init(const char *path, long long fVal, int fsupdt)
virtual int Lfn2Pfn(const char *Path, char *buff, int blen)
virtual int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *envP=0)=0
static int Export(const char *Var, const char *Val)
char * GetToken(char **rest=0, int lowcase=0)
void MsgfW(const char *fmt,...)
void MsgW(const char *txt1, const char *txt2=0, const char *txt3=0, const char *txt4=0, const char *txt5=0, const char *txt6=0)
void MsgfE(const char *fmt,...)
void MsgE(const char *txt1, const char *txt2=0, const char *txt3=0, const char *txt4=0, const char *txt5=0, const char *txt6=0)
@ full_lines
Complete lines.
static int makePath(char *path, mode_t mode, bool reset=false)
static int a2sp(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
void Schedule(XrdJob *jp)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
thread_local XrdOucECMsg ecMsg
XrdSysTrace ArcTrace("OssArc")
XrdSysError Elog(0, "OssArc_")