74extern XrdScheduler*
schedP;
76extern XrdSysError
Elog;
92std::set<std::string> bkpScopes;
129 if ((atmp = getenv(
"XRDADMINPATH")))
130 {std::string as = atmp;
131 if (as.back() !=
'/') as.append(
"/");
132 as.append(
"OssArc/");
151 manCKS = strdup(
"adler32");
160 arFName = strdup(
"Archive.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;
262 Elog.Say(
"Config mistake: required 'rsedcl' directive not specified!");
278 snprintf(buff,
sizeof(buff),
"%lld %lld %lld %d",
arcSZ_Want,
287 if (rc) {
Elog.Emsg(
"Config", rc,
"create admin path",
admnPath);
290 else if (!Usable(
admnPath,
"admin path",
false)) NoGo =
true;
297 if (ss.back() !=
'/')
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;
340 {
Elog.Emsg(
"Config", errno,
"use srcdata path",
srcData);
357 else {
const char* rslash = rindex(
BkpUtilPath,
'/');
366 else {
const char* rslash = rindex(
MssComPath,
'/');
387 else {
const char* rslash = rindex(
PrepArcPath,
'/');
398 else {
const char* rslash = rindex(
PostArcPath,
'/');
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 ",
460 schedP->Schedule(*it, time(0)+3);
473void 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());
490bool 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);
516bool XrdOssArcConfig::ConfigXeq(
const char* cfName,
const char* parms,
519 XrdOucGatherConf Cfile(
"ossarc.", &
Elog);
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);
553int XrdOssArcConfig::GenLocalPath(
const char* dsn,
char* buff,
int bSZ)
560 {
Elog.
Emsg(
"Archive", rc,
"generate local path for", dsn);
570bool XrdOssArcConfig::MissArg(
const char* what)
572 Conf->MsgfE(
"%s not specified.", what);
580bool 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;}
657bool 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;
671 while((token = Conf->GetToken()))
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);
719bool 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;}
730 {
"fscan", &
bkpFSt, 30, isT},
732 {
"minfree", 0, 1, isPS},
735 {
"scope", 0, -1, isN}
737 int numopts =
sizeof(bkpopt)/
sizeof(
struct bkpopts);
743 if (!(token = Conf->GetToken()))
744 {Conf->MsgfE(
"no backup arguments specified!");
return false;}
748do{
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()));
802bool XrdOssArcConfig::xqBkupPS(
char* tval)
804 int n = strlen(tval);
808 if (tval[n-1] ==
'%')
830bool XrdOssArcConfig::xqBkupScope()
832 char* scope = Conf->GetToken();
834 if (!scope || !(*scope))
835 {Conf->MsgfE(
"backup scope not specified!");
return false;}
837do{
auto rslt = bkpScopes.insert(std::string(scope));
839 Conf->MsgW(
"backup scope", scope,
"previously specified.");
840 scope = Conf->GetToken();
841 }
while(scope && *scope);
850bool 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);
877bool XrdOssArcConfig::xqManf()
882 if (!(token = Conf->GetToken()))
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);
893 if (!(targ = Conf->GetToken()))
894 {Conf->MsgfE(
"%s argument not specified!", token);
897 if (*tDest) free(*tDest);
898 *tDest = strdup(targ);
899 }
while((token = Conf->GetToken()));
914bool XrdOssArcConfig::xqPaths()
921 while((token = Conf->GetToken()))
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);
930 if (!Conf->GetToken())
break;
933 if (!(ploc = Conf->GetToken()))
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;}
964bool XrdOssArcConfig::xqRse()
970 if (!(token = Conf->GetToken()))
971 {Conf->MsgfE(
"source rse name not specified!");
return false;}
980 if (!(token = Conf->GetToken()))
981 {Conf->MsgfE(
"destination rse name not specified!");
return false;}
999bool XrdOssArcConfig::xqRucio()
1006 if (!(token = Conf->GetToken()))
1007 {Conf->MsgfE(
"rucio parameter not specified!");
return false;}
1011do{
if (!strcmp(token,
"maxitems"))
1012 {
if (!(val = Conf->GetToken())
1016 Conf->MsgfE(
"Invalid rucio parameter, '%s'!", token);
1019 }
while((token = Conf->GetToken()));
1024 {
if (val) Conf->EchoLine();
1025 else Conf->MsgfE(
"rucio %s parameter value not specified.", token);
1041bool XrdOssArcConfig::xqStage()
1043 static const int minStg = 1, maxStg = 100, minPoll = 5, maxPoll = 100;
1049 if (!(val = Conf->GetToken()))
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);
1074 }
while((val = Conf->GetToken()));
1085bool XrdOssArcConfig::xqTrace()
1088 struct traceopts {
const char *opname;
unsigned int opval;} tropts[] =
1096 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
1098 if (!(val = Conf->GetToken()))
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);
1118 val = Conf->GetToken();
1132bool XrdOssArcConfig::xqUtils()
1139 while((token = Conf->GetToken()))
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);
1147 if (!Conf->GetToken())
break;
1150 if (!(uloc = Conf->GetToken()))
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;}
static void StartWorkers(int maxw)
bool BuildPath(const char *what, const char *baseP, const char *addP, char *&destP, int mode=0)
XrdOssArcStopMon * stopMon
XrdOucProg * ArchiverProg
const char * ArchiverName
bool Configure(const char *cfn, const char *parms, XrdOucEnv *envP)
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 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)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysTrace ArcTrace("OssArc")
XrdSysError Elog(0, "OssArc_")