47 #define DSM_ONE_GB (1073741824)
50 TString TDataSetManager::fgCommonDataSetTag =
"COMMON";
51 TList *TDataSetManager::fgDataSetSrvMaps = 0;
53 ClassImp(TDataSetManager);
59 TDataSetManager::TDataSetManager(
const char *group,
const char *user,
62 fUser(user), fCommonUser(), fCommonGroup(),
63 fGroupQuota(), fGroupUsed(),
64 fUserUsed(), fNTouchedFiles(0), fNOpenedFiles(0),
65 fNDisappearedFiles(0), fMTimeGroupConfig(-1)
73 UserGroup_t *pw = gSystem->GetUserInfo();
80 fGroupQuota.SetOwner();
81 fGroupUsed.SetOwner();
84 fCommonUser =
"COMMON";
85 fCommonGroup =
"COMMON";
89 fNDisappearedFiles = -1;
90 fMTimeGroupConfig = -1;
92 fAvgFileSize = 50000000;
95 ParseInitOpts(options);
97 if (!fUser.IsNull() && !fGroup.IsNull()) {
101 if (!TestBit(TDataSetManager::kIsSandbox))
102 fBase.SetUri(TString(Form(
"/%s/%s/", fGroup.Data(), fUser.Data())));
107 TString srvmaps(gEnv->GetValue(
"DataSet.SrvMaps",
""));
108 TString srvmapsenv(gSystem->Getenv(
"DATASETSRVMAPS"));
109 if (!(srvmapsenv.IsNull())) {
110 if (srvmapsenv.BeginsWith(
"+")) {
111 if (!(srvmaps.IsNull())) srvmaps +=
",";
112 srvmaps += srvmapsenv(1,srvmapsenv.Length());
114 srvmaps = srvmapsenv;
117 if (!(srvmaps.IsNull()) && !(fgDataSetSrvMaps = ParseDataSetSrvMaps(srvmaps)))
118 Warning(
"TDataSetManager",
"problems parsing DataSet.SrvMaps input info (%s)"
119 " - ignoring", srvmaps.Data());
122 ReadGroupConfig(gEnv->GetValue(
"Proof.GroupFile",
""));
128 TDataSetManager::~TDataSetManager()
131 fGroupQuota.DeleteAll();
132 fGroupUsed.DeleteAll();
133 fUserUsed.DeleteAll();
150 void TDataSetManager::ParseInitOpts(
const char *opts)
153 ResetBit(TDataSetManager::kCheckQuota);
154 SetBit(TDataSetManager::kAllowRegister);
155 SetBit(TDataSetManager::kAllowVerify);
156 SetBit(TDataSetManager::kTrustInfo);
157 ResetBit(TDataSetManager::kIsSandbox);
158 ResetBit(TDataSetManager::kUseCache);
159 ResetBit(TDataSetManager::kDoNotUseCache);
161 if (opts && strlen(opts) > 0) {
164 Int_t ip = opt.Index(
"opt:");
165 if (ip != kNPOS) opt.Remove(0, ip + 4);
167 if (ip != kNPOS) opt.Remove(ip);
169 if (opt.Contains(
"Cq:") && !opt.Contains(
"-Cq:"))
170 SetBit(TDataSetManager::kCheckQuota);
171 if (opt.Contains(
"-Ar:"))
172 ResetBit(TDataSetManager::kAllowRegister);
173 if (opt.Contains(
"-Av:"))
174 ResetBit(TDataSetManager::kAllowVerify);
175 if (opt.Contains(
"-Ti:"))
176 ResetBit(TDataSetManager::kTrustInfo);
177 if (opt.Contains(
"Sb:") && !opt.Contains(
"-Sb:"))
178 SetBit(TDataSetManager::kIsSandbox);
179 if (opt.Contains(
"Ca:"))
180 SetBit(TDataSetManager::kUseCache);
181 if (opt.Contains(
"-Ca:"))
182 SetBit(TDataSetManager::kDoNotUseCache);
186 if (TestBit(TDataSetManager::kAllowVerify)) {
188 SetBit(TDataSetManager::kAllowRegister);
191 if (TestBit(TDataSetManager::kUseCache) && TestBit(TDataSetManager::kDoNotUseCache))
192 ResetBit(TDataSetManager::kDoNotUseCache);
207 Bool_t TDataSetManager::ReadGroupConfig(
const char *cf)
211 if (!cf || (strlen(cf) <= 0) || !strcmp(cf, fGroupConfigFile.Data())) {
213 if (fGroupConfigFile.IsNull()) {
215 Info(
"ReadGroupConfig",
"path to config file undefined - nothing to do");
219 if (gSystem->GetPathInfo(fGroupConfigFile, st)) {
220 Error(
"ReadGroupConfig",
"could not stat %s", fGroupConfigFile.Data());
223 if (st.fMtime <= fMTimeGroupConfig) {
225 Info(
"ReadGroupConfig",
"file has not changed - do nothing");
231 if (cf && (strlen(cf) > 0)) {
233 if (gSystem->GetPathInfo(cf, st)) {
234 Error(
"ReadGroupConfig",
"could not stat %s", cf);
237 if (gSystem->AccessPathName(cf, kReadPermission)) {
238 Error(
"ReadGroupConfig",
"cannot read %s", cf);
242 fGroupConfigFile = cf;
243 fMTimeGroupConfig = st.fMtime;
247 Info(
"ReadGroupConfig",
"reading group config from %s", cf);
253 Error(
"ReadGroupConfig",
"could not open config file %s", cf);
258 TString tmpCommonUser;
266 if (line[0] ==
'#')
continue;
270 if (!line.Tokenize(key, from,
" "))
273 if (key ==
"property") {
276 if (!line.Tokenize(grp, from,
" ")) {
278 Info(
"ReadGroupConfig",
"incomplete line: '%s'", line.Data());
283 if (!line.Tokenize(type, from,
" "))
285 if (type ==
"diskquota") {
288 if (!line.Tokenize(sdq, from,
" "))
291 if (sdq.IsDigit()) sdq +=
"G";
292 Long64_t quota = ToBytes(sdq);
294 fGroupQuota.Add(
new TObjString(grp),
295 new TParameter<Long64_t> (
"group quota", quota));
297 Warning(
"ReadGroupConfig",
298 "problems parsing string: wrong or unsupported suffix? %s",
301 }
else if (type ==
"commonuser") {
304 if (!line.Tokenize(comusr, from,
" "))
309 }
else if (key ==
"dataset") {
312 if (!line.Tokenize(type, from,
" ")) {
314 Info(
"ReadGroupConfig",
"incomplete line: '%s'", line.Data());
317 if (type ==
"commonuser") {
320 if (!line.Tokenize(comusr, from,
" "))
322 fCommonUser = comusr;
323 }
else if (type ==
"commongroup") {
326 if (!line.Tokenize(comgrp, from,
" "))
328 fCommonGroup = comgrp;
329 }
else if (type ==
"diskquota") {
332 if (!line.Tokenize(on, from,
" "))
335 SetBit(TDataSetManager::kCheckQuota);
336 }
else if (on ==
"off") {
337 ResetBit(TDataSetManager::kCheckQuota);
341 }
else if (key ==
"averagefilesize") {
345 if (!line.Tokenize(avgsize, from,
" ")) {
347 Info(
"ReadGroupConfig",
"incomplete line: '%s'", line.Data());
350 Long64_t avgsz = ToBytes(avgsize);
352 fAvgFileSize = avgsz;
354 Warning(
"ReadGroupConfig",
355 "problems parsing string: wrong or unsupported suffix? %s",
358 }
else if (key ==
"include") {
362 if (!line.Tokenize(subfn, from,
" ")) {
364 Info(
"ReadGroupConfig",
"incomplete line: '%s'", line.Data());
368 if (gSystem->AccessPathName(subfn, kReadPermission)) {
369 Error(
"ReadGroupConfig",
"request to parse file '%s' which is not readable",
373 if (!ReadGroupConfig(subfn))
374 Error(
"ReadGroupConfig",
"problems parsing include file '%s'", subfn.Data());
388 Long64_t TDataSetManager::ToBytes(
const char *size)
393 if (!size || strlen(size) <= 0)
return lsize;
399 const char *unit[5] = {
"k",
"M",
"G",
"T",
"P"};
403 if (s.EndsWith(unit[jj], TString::kIgnoreCase)) {
404 s.Remove(s.Length()-1);
413 lsize = s.Atoi() * fact;
422 TFileCollection *TDataSetManager::GetDataSet(
const char *,
const char *)
424 AbstractMethod(
"GetDataSet");
425 return (TFileCollection *)0;
431 Bool_t TDataSetManager::RemoveDataSet(
const char *)
433 AbstractMethod(
"RemoveDataSet");
440 Bool_t TDataSetManager::ExistsDataSet(
const char *)
442 AbstractMethod(
"ExistsDataSet");
465 TMap *TDataSetManager::GetDataSets(
const char *, UInt_t)
467 AbstractMethod(
"GetDataSets");
498 Int_t TDataSetManager::ScanDataSet(
const char *uri,
const char *opts)
502 if (opts && strlen(opts) > 0) {
504 if (strstr(opts,
"allfiles:") || strchr(opts,
'A'))
506 else if (strstr(opts,
"staged:") || strchr(opts,
'D'))
509 if (strstr(opts,
"open:") || strchr(opts,
'O'))
511 if (strstr(opts,
"touch:") || strchr(opts,
'T'))
513 if (strstr(opts,
"nostagedcheck:") || strchr(opts,
'I'))
516 if (strstr(opts,
"noaction:") || strchr(opts,
'N'))
518 if (strstr(opts,
"locateonly:") || strchr(opts,
'L'))
520 if (strstr(opts,
"stageonly:") || strchr(opts,
'S'))
523 if (strstr(opts,
"verbose:") || strchr(opts,
'V'))
527 o = kReopen | kDebug;
531 return ScanDataSet(uri, o);
540 Int_t TDataSetManager::ScanDataSet(
const char *, UInt_t)
542 AbstractMethod(
"ScanDataSet");
551 void TDataSetManager::GetQuota(
const char *group,
const char *user,
552 const char *dsName, TFileCollection *dataset)
555 Info(
"GetQuota",
"processing dataset %s %s %s", group, user, dsName);
557 if (dataset->GetTotalSize() > 0) {
558 TParameter<Long64_t> *size =
559 dynamic_cast<TParameter<Long64_t>*
> (fGroupUsed.GetValue(group));
561 size =
new TParameter<Long64_t> (
"group used", 0);
562 fGroupUsed.Add(
new TObjString(group), size);
565 size->SetVal(size->GetVal() + dataset->GetTotalSize());
567 TMap *userMap =
dynamic_cast<TMap*
> (fUserUsed.GetValue(group));
570 fUserUsed.Add(
new TObjString(group), userMap);
573 size =
dynamic_cast<TParameter<Long64_t>*
> (userMap->GetValue(user));
575 size =
new TParameter<Long64_t> (
"user used", 0);
576 userMap->Add(
new TObjString(user), size);
579 size->SetVal(size->GetVal() + dataset->GetTotalSize());
586 void TDataSetManager::ShowQuota(
const char *opt)
590 TMap *groupQuotaMap = GetGroupQuotaMap();
591 TMap *userUsedMap = GetUserUsedMap();
592 if (!groupQuotaMap || !userUsedMap)
595 Bool_t noInfo = kTRUE;
596 TIter iter(groupQuotaMap);
597 TObjString *group = 0;
598 while ((group = dynamic_cast<TObjString*> (iter.Next()))) {
600 Long64_t groupQuota = GetGroupQuota(group->String());
601 Long64_t groupUsed = GetGroupUsed(group->String());
603 Printf(
" +++ Group %s uses %.1f GB out of %.1f GB", group->String().Data(),
604 (Float_t) groupUsed / DSM_ONE_GB,
605 (Float_t) groupQuota / DSM_ONE_GB);
608 if (opt && !TString(opt).Contains(
"U", TString::kIgnoreCase))
611 TMap *userMap =
dynamic_cast<TMap*
> (userUsedMap->GetValue(group->String()));
615 TIter iter2(userMap);
616 TObjString *user = 0;
617 while ((user = dynamic_cast<TObjString*> (iter2.Next()))) {
618 TParameter<Long64_t> *size2 =
619 dynamic_cast<TParameter<Long64_t>*
> (userMap->GetValue(user->String().Data()));
623 Printf(
" +++ User %s uses %.1f GB", user->String().Data(),
624 (Float_t) size2->GetVal() / DSM_ONE_GB);
627 Printf(
"------------------------------------------------------");
631 Printf(
" +++ Quota check enabled but no quota info available +++ ");
639 void TDataSetManager::PrintUsedSpace()
641 Info(
"PrintUsedSpace",
"listing used space");
643 TIter iter(&fUserUsed);
644 TObjString *group = 0;
645 while ((group = dynamic_cast<TObjString*> (iter.Next()))) {
646 TMap *userMap =
dynamic_cast<TMap*
> (fUserUsed.GetValue(group->String()));
648 TParameter<Long64_t> *size =
649 dynamic_cast<TParameter<Long64_t>*
> (fGroupUsed.GetValue(group->String()));
651 if (userMap && size) {
652 Printf(
"Group %s: %lld B = %.2f GB", group->String().Data(), size->GetVal(),
653 (Float_t) size->GetVal() / DSM_ONE_GB);
655 TIter iter2(userMap);
656 TObjString *user = 0;
657 while ((user = dynamic_cast<TObjString*> (iter2.Next()))) {
658 TParameter<Long64_t> *size2 =
659 dynamic_cast<TParameter<Long64_t>*
> (userMap->GetValue(user->String().Data()));
661 Printf(
" User %s: %lld B = %.2f GB", user->String().Data(), size2->GetVal(),
662 (Float_t) size2->GetVal() / DSM_ONE_GB);
665 Printf(
"------------------------------------------------------");
674 void TDataSetManager::MonitorUsedSpace(TVirtualMonitoringWriter *monitoring)
676 Info(
"MonitorUsedSpace",
"sending used space to monitoring server");
678 TIter iter(&fUserUsed);
679 TObjString *group = 0;
680 while ((group = dynamic_cast<TObjString*> (iter.Next()))) {
681 TMap *userMap =
dynamic_cast<TMap*
> (fUserUsed.GetValue(group->String()));
682 TParameter<Long64_t> *size =
683 dynamic_cast<TParameter<Long64_t>*
> (fGroupUsed.GetValue(group->String()));
685 if (!userMap || !size)
688 TList *list =
new TList;
690 list->Add(
new TParameter<Long64_t>(
"_TOTAL_", size->GetVal()));
691 Long64_t groupQuota = GetGroupQuota(group->String());
692 if (groupQuota != -1)
693 list->Add(
new TParameter<Long64_t>(
"_QUOTA_", groupQuota));
695 TIter iter2(userMap);
696 TObjString *user = 0;
697 while ((user = dynamic_cast<TObjString*> (iter2.Next()))) {
698 TParameter<Long64_t> *size2 =
699 dynamic_cast<TParameter<Long64_t>*
> (userMap->GetValue(user->String().Data()));
702 list->Add(
new TParameter<Long64_t>(user->String().Data(), size2->GetVal()));
705 if (!monitoring->SendParameters(list, group->String()))
706 Warning(
"MonitorUsedSpace",
"problems sending monitoring parameters");
715 Long64_t TDataSetManager::GetGroupUsed(
const char *group)
717 if (fgCommonDataSetTag == group)
718 group = fCommonGroup;
720 TParameter<Long64_t> *size =
721 dynamic_cast<TParameter<Long64_t>*
> (fGroupUsed.GetValue(group));
724 Info(
"GetGroupUsed",
"group %s not found", group);
728 return size->GetVal();
735 Long64_t TDataSetManager::GetGroupQuota(
const char *group)
737 if (fgCommonDataSetTag == group)
738 group = fCommonGroup;
740 TParameter<Long64_t> *value =
741 dynamic_cast<TParameter<Long64_t>*
> (fGroupQuota.GetValue(group));
744 Info(
"GetGroupQuota",
"group %s not found", group);
747 return value->GetVal();
753 void TDataSetManager::UpdateUsedSpace()
755 AbstractMethod(
"UpdateUsedSpace");
762 Int_t TDataSetManager::RegisterDataSet(
const char *,
763 TFileCollection *,
const char *)
765 AbstractMethod(
"RegisterDataSet");
774 Int_t TDataSetManager::NotifyUpdate(
const char * ,
780 AbstractMethod(
"NotifyUpdate");
787 Int_t TDataSetManager::ClearCache(
const char * )
789 AbstractMethod(
"ClearCache");
796 Int_t TDataSetManager::ShowCache(
const char * )
798 AbstractMethod(
"ShowCache");
806 TString TDataSetManager::CreateUri(
const char *dsGroup,
const char *dsUser,
807 const char *dsName,
const char *dsObjPath)
811 if (dsGroup && strlen(dsGroup) > 0) {
812 if (dsUser && strlen(dsUser) > 0) {
813 uri += Form(
"/%s/%s/", dsGroup, dsUser);
815 uri += Form(
"/%s/*/", dsGroup);
817 }
else if (dsUser && strlen(dsUser) > 0) {
818 uri += Form(
"%s/", dsUser);
820 if (dsName && strlen(dsName) > 0)
822 if (dsObjPath && strlen(dsObjPath) > 0)
823 uri += Form(
"#%s", dsObjPath);
843 Bool_t TDataSetManager::ParseUri(
const char *uri,
844 TString *dsGroup, TString *dsUser,
845 TString *dsName, TString *dsTree,
846 Bool_t onlyCurrent, Bool_t wildcards)
852 if ((uristr.Index(
'=') >= 0) && (uristr.Index(
';') >= 0)) {
858 "Dataset URI looks like a virtual URI, treating it as such. "
859 "No group and user will be parsed!");
861 TPMERegexp reVirtualUri(
"^([^#]+)(#(.*))?$");
862 Int_t nm = reVirtualUri.Match(uristr);
865 if (dsGroup) *dsGroup =
"";
866 if (dsUser) *dsUser =
"";
867 if (dsName) *dsName = reVirtualUri[1];
869 if (nm == 4) *dsTree = reVirtualUri[3];
880 if (wildcards && uristr.Length() > 0) {
881 pc = uristr.CountChar(
'/');
882 Bool_t endsl = uristr.EndsWith(
"/") ? kTRUE : kFALSE;
883 Bool_t beginsl = uristr.BeginsWith(
"/") ? kTRUE : kFALSE;
885 if (pc == 1) uristr +=
"/*/";
886 if (pc == 2 && endsl) uristr +=
"*/";
887 if (pc == 2 && !endsl) uristr +=
"/";
892 TUri resolved = TUri::Transform(uristr, fBase);
893 if (resolved.HasQuery())
894 Info (
"ParseUri",
"URI query part <%s> ignored", resolved.GetQuery().Data());
896 TString path(resolved.GetPath());
898 if ((pc = path.CountChar(
'/')) != 3) {
899 if (!TestBit(TDataSetManager::kIsSandbox)) {
900 Error (
"ParseUri",
"illegal dataset path: '%s'", uri);
902 }
else if (pc >= 0 && pc < 3) {
907 }
else if (pc == 1) {
908 sls.Form(
"/%s/", fGroup.Data());
909 }
else if (pc == 0) {
910 sls.Form(
"/%s/%s/", fGroup.Data(), fUser.Data());
916 Info(
"ParseUri",
"path: '%s'", path.Data());
920 TString group, user, name;
921 if (path.Tokenize(group, from,
"/")) {
922 if (path.Tokenize(user, from,
"/")) {
923 if (!path.Tokenize(name, from,
"/"))
924 if (gDebug > 0) Info(
"ParseUri",
"'name' missing");
926 if (gDebug > 0) Info(
"ParseUri",
"'user' missing");
929 if (gDebug > 1) Info(
"ParseUri",
"'group' missing");
933 TString tree = resolved.GetFragment();
934 if (tree.EndsWith(
"/"))
935 tree.Remove(tree.Length()-1);
938 Info(
"ParseUri",
"group: '%s', user: '%s', dsname:'%s', seg: '%s'",
939 group.Data(), user.Data(), name.Data(), tree.Data());
942 if ((user ==
"*" || group ==
"*") && !wildcards) {
943 Error (
"ParseUri",
"no wildcards allowed for user/group in this context (uri: '%s')", uri);
948 if (name.IsNull() && !wildcards) {
949 Error (
"ParseUri",
"DataSet name is empty");
954 TPRegexp wcExp (wildcards ?
"^(?:[A-Za-z0-9-*_.]*|[*])$" :
"^[A-Za-z0-9-_.]*$");
957 if (!wcExp.Match(group)) {
958 Error(
"ParseUri",
"illegal characters in group (uri: '%s', group: '%s')", uri, group.Data());
962 if (!wcExp.Match(user)) {
963 Error(
"ParseUri",
"illegal characters in user (uri: '%s', user: '%s')", uri, user.Data());
968 if (!wcExp.Match(name)) {
969 Error(
"ParseUri",
"illegal characters in name (uri: '%s', name: '%s')", uri, name.Data());
973 if (tree.Contains(TRegexp(
"[^A-Za-z0-9-/_]"))) {
974 Error(
"ParseUri",
"Illegal characters in subdir/object name (uri: '%s', obj: '%s')", uri, tree.Data());
979 if (onlyCurrent && (group.CompareTo(fGroup) || user.CompareTo(fUser))) {
980 Error(
"ParseUri",
"only datasets from your group/user allowed");
1007 TMap *TDataSetManager::GetSubDataSets(
const char *ds,
const char *exclude)
1009 TMap *map = (TMap *)0;
1011 if (!ds || strlen(ds) <= 0) {
1012 Info(
"GetDataSets",
"dataset name undefined!");
1017 TFileCollection *fc = GetDataSet(ds);
1019 Info(
"GetDataSets",
"could not retrieve the dataset '%s'", ds);
1024 if (!(map = fc->GetFilesPerServer(exclude))) {
1026 Info(
"GetDataSets",
"could not get map for '%s'", ds);
1044 void TDataSetManager::PrintDataSet(TFileCollection *fc, Int_t popt)
1049 Int_t u = popt - 10 * f;
1052 if (fc->GetTitle() && (strlen(fc->GetTitle()) > 0)) {
1053 Printf(
"+++ Dumping: %s: ", fc->GetTitle());
1055 Printf(
"+++ Dumping: %s: ", fc->GetName());
1057 Printf(
"%s", fc->ExportInfo(
"+++ Summary:", 1)->GetName());
1059 Printf(
"+++ Files:");
1061 TIter nxfi(fc->GetList());
1063 while ((fi = (TFileInfo *)nxfi())) {
1065 Printf(
"+++ %5d. %s", ++nf, fi->GetCurrentUrl()->GetUrl());
1067 Printf(
"+++ %5d. %s", ++nf, fi->GetCurrentUrl()->GetFile());
1099 void TDataSetManager::ShowDataSets(
const char *uri,
const char *opt)
1101 TFileCollection *fc = 0;
1104 if (o.Contains(
"full:")) {
1105 o.ReplaceAll(
"full:",
"");
1108 if (o.BeginsWith(
"server:")) {
1109 o.ReplaceAll(
"server:",
"");
1112 while ((o.Tokenize(srv, from,
","))) {
1113 fc = GetDataSet(uri, srv.Data());
1114 PrintDataSet(fc, popt);
1117 }
else if (o.BeginsWith(
"servers")) {
1118 o.ReplaceAll(
"servers",
"");
1119 if (o.BeginsWith(
":exclude:"))
1120 o.ReplaceAll(
":exclude:",
"");
1123 TMap *dsmap = GetSubDataSets(uri, o.Data());
1127 while ((k = nxk()) && (fc = (TFileCollection *) dsmap->GetValue(k))) {
1128 PrintDataSet(fc, popt);
1133 TString u(uri), grp, usr, dsn;
1135 if (u ==
"" || u ==
"*" || u ==
"/*" || u ==
"/*/" || u ==
"/*/*") u =
"/*/*/";
1136 if (!ParseUri(u.Data(), &grp, &usr, &dsn, 0, kFALSE, kTRUE))
1137 Warning(
"ShowDataSets",
"problems parsing URI '%s'", uri);
1139 UInt_t xopt = (UInt_t)(TDataSetManager::kPrint);
1140 if (o.Contains(
"forcescan:")) xopt |= (UInt_t)(TDataSetManager::kForceScan);
1141 if (o.Contains(
"noheader:")) xopt |= (UInt_t)(TDataSetManager::kNoHeaderPrint);
1142 if (o.Contains(
"noupdate:")) xopt |= (UInt_t)(TDataSetManager::kNoCacheUpdate);
1143 if (o.Contains(
"refresh:")) xopt |= (UInt_t)(TDataSetManager::kRefreshLs);
1144 if (!u.IsNull() && !u.Contains(
"*") && !grp.IsNull() && !usr.IsNull() && !dsn.IsNull()) {
1145 if (ExistsDataSet(uri)) {
1149 GetDataSets(u.Data(), xopt);
1150 }
else if ((fc = GetDataSet(uri))) {
1152 PrintDataSet(fc, 10 + popt);
1158 TRegexp reg(grp, kTRUE), reu(usr, kTRUE);
1159 if (u.Index(reg) == kNPOS) grp =
"*";
1160 if (u.Index(reu) == kNPOS) usr =
"*";
1162 u.Form(
"/%s/%s/%s", grp.Data(), usr.Data(), dsn.Data());
1164 GetDataSets(u.Data(), xopt);
1225 Int_t TDataSetManager::ScanDataSet(TFileCollection *dataset,
1226 Int_t fopt, Int_t sopt, Int_t ropt, Bool_t dbg,
1227 Int_t *touched, Int_t *opened, Int_t *disappeared,
1228 TList *flist, Long64_t avgsz,
const char *mss,
1229 Int_t maxfiles,
const char *stageopts)
1232 if (maxfiles > -1 && dbg)
1233 ::Info(
"TDataSetManager::ScanDataSet",
"processing a maximum of %d files", maxfiles);
1236 Bool_t checkstg = (fopt >= 100 || fopt < -1) ? kFALSE : kTRUE;
1239 Bool_t noaction = (sopt == -1) ? kTRUE : kFALSE;
1241 Bool_t locateonly = (sopt == 1) ? kTRUE : kFALSE;
1242 Bool_t stageonly = (sopt == 2) ? kTRUE : kFALSE;
1245 Bool_t doall = (ropt == 0) ? kTRUE : kFALSE;
1246 Bool_t getlistonly = (ropt == 1) ? kTRUE : kFALSE;
1247 Bool_t scanlist = (ropt == 2) ? kTRUE : kFALSE;
1249 if (scanlist && !flist) {
1250 ::Error(
"TDataSetManager::ScanDataSet",
"input list is mandatory for option 'scan file list'");
1256 Int_t fdisappeared = 0;
1258 Bool_t bchanged_ds = kFALSE;
1260 TList *newStagedFiles = 0;
1261 TFileInfo *fileInfo = 0;
1262 TFileStager *stager = 0;
1263 Bool_t createStager = kFALSE;
1265 if (doall || getlistonly) {
1268 newStagedFiles = (!doall && getlistonly && flist) ? flist :
new TList;
1269 if (newStagedFiles != flist) newStagedFiles->SetOwner(kFALSE);
1271 stager = (mss && strlen(mss) > 0) ? TFileStager::Open(mss) : 0;
1272 createStager = (stager) ? kFALSE : kTRUE;
1274 Bool_t bchanged_fi = kFALSE;
1275 Bool_t btouched = kFALSE;
1276 Bool_t bdisappeared = kFALSE;
1280 TIter iter(dataset->GetList());
1281 while ((fileInfo = (TFileInfo *) iter())) {
1284 gSystem->DispatchOneEvent(kTRUE);
1286 bchanged_fi = kFALSE;
1288 bdisappeared = kFALSE;
1289 Bool_t newlystaged = CheckStagedStatus(fileInfo, fopt, maxfiles, newStagedFiles->GetEntries(),
1290 stager, createStager, dbg, bchanged_fi, btouched,
1293 if (bchanged_fi) bchanged_ds = kTRUE;
1294 if (btouched) ftouched++;
1295 if (bdisappeared) fdisappeared++;
1298 if (dbg && (ftouched+fdisappeared) % 100 == 0)
1299 ::Info(
"TDataSetManager::ScanDataSet",
"opening %d: file: %s",
1300 ftouched + fdisappeared, fileInfo->GetCurrentUrl()->GetUrl());
1303 if (!noaction && newlystaged) newStagedFiles->Add(fileInfo);
1309 if (dbg && newStagedFiles->GetEntries() > 0)
1310 ::Info(
"TDataSetManager::ScanDataSet",
" %d files appear to be newly staged",
1311 newStagedFiles->GetEntries());
1312 if (!flist) SafeDelete(newStagedFiles);
1313 return ((bchanged_ds) ? 2 : 1);
1317 if (!noaction && (doall || scanlist)) {
1320 newStagedFiles = (!doall && scanlist && flist) ? flist : newStagedFiles;
1321 if (newStagedFiles != flist) newStagedFiles->SetOwner(kFALSE);
1324 if (dbg && newStagedFiles->GetEntries() > 0)
1325 ::Info(
"TDataSetManager::ScanDataSet",
"opening %d files that appear to be newly staged",
1326 newStagedFiles->GetEntries());
1329 if (locateonly || stageonly) {
1330 stager = (mss && strlen(mss) > 0) ? TFileStager::Open(mss) : 0;
1331 createStager = (stager) ? kFALSE : kTRUE;
1335 Int_t fqnot = (newStagedFiles->GetSize() > 10) ? newStagedFiles->GetSize() / 10 : 1;
1336 if (fqnot > 100) fqnot = 100;
1338 Bool_t bchanged_fi = kFALSE;
1339 Bool_t bopened = kFALSE;
1340 TIter iter(newStagedFiles);
1341 while ((fileInfo = (TFileInfo *) iter())) {
1343 if (dbg && (count%fqnot == 0))
1344 ::Info(
"TDataSetManager::ScanDataSet",
"processing %d.'new' file: %s",
1345 count, fileInfo->GetCurrentUrl()->GetUrl());
1349 gSystem->DispatchOneEvent(kTRUE);
1350 bchanged_fi = kFALSE;
1353 ProcessFile(fileInfo, sopt, checkstg, doall, stager, createStager,
1354 stageopts, dbg, bchanged_fi, bopened);
1356 bchanged_ds |= bchanged_fi;
1357 if (bopened) fopened++;
1359 if (newStagedFiles != flist) SafeDelete(newStagedFiles);
1361 dataset->RemoveDuplicates();
1362 dataset->Update(avgsz);
1365 Int_t result = (bchanged_ds) ? 2 : 1;
1366 if (result > 0 && dbg)
1367 ::Info(
"TDataSetManager::ScanDataSet",
"%d files 'new'; %d files touched;"
1368 " %d files disappeared", fopened, ftouched, fdisappeared);
1371 if (touched) *touched = ftouched;
1372 if (opened) *opened = fopened;
1373 if (disappeared) *disappeared = fdisappeared;
1376 gSystem->DispatchOneEvent(kTRUE);
1415 Bool_t TDataSetManager::CheckStagedStatus(TFileInfo *fileInfo, Int_t fopt, Int_t maxfiles,
1416 Int_t newstagedfiles, TFileStager* stager,
1417 Bool_t createStager, Bool_t dbg, Bool_t& changed,
1418 Bool_t& touched, Bool_t& disappeared)
1421 Bool_t allf = (fopt == -1) ? kTRUE : kFALSE;
1422 Bool_t checkstg = (fopt >= 100 || fopt < -1) ? kFALSE : kTRUE;
1423 if (fopt >= 0) fopt %= 100;
1424 Bool_t nonstgf = (fopt >= 0 && fopt < 10) ? kTRUE : kFALSE;
1425 Bool_t reopen = (fopt >= 1 && fopt < 10) ? kTRUE : kFALSE;
1426 Bool_t touch = (fopt >= 2 && fopt < 10) ? kTRUE : kFALSE;
1427 Bool_t stgf = (fopt == 10) ? kTRUE : kFALSE;
1431 disappeared = kFALSE;
1438 fileInfo->ResetUrl();
1439 if (!fileInfo->GetCurrentUrl()) {
1440 ::Error(
"TDataSetManager::CheckStagedStatus",
"GetCurrentUrl() returned 0 for %s",
1441 fileInfo->GetFirstUrl()->GetUrl());
1445 if (nonstgf && fileInfo->TestBit(TFileInfo::kStaged)) {
1448 if (fileInfo->TestBit(TFileInfo::kCorrupted))
return kFALSE;
1451 if (!reopen)
return kFALSE;
1455 TUrl *curl = fileInfo->GetCurrentUrl();
1456 const char *furl = curl->GetUrl();
1458 if (TDataSetManager::CheckDataSetSrvMaps(curl, urlmod) && !(urlmod.IsNull()))
1459 furl = urlmod.Data();
1464 TString uopt(url.GetOptions());
1465 uopt +=
"filetype=raw&mxredir=2";
1466 url.SetOptions(uopt.Data());
1467 TFile *file = TFile::Open(url.GetUrl());
1472 if (file->ReadBuffer(&tmpChar, 1))
1473 ::Warning(
"TDataSetManager::CheckStagedStatus",
"problems reading 1 byte from open file");
1481 if (dbg) ::Info(
"TDataSetManager::CheckStagedStatus",
"file %s disappeared", url.GetUrl());
1482 fileInfo->ResetBit(TFileInfo::kStaged);
1483 disappeared = kTRUE;
1487 if (fileInfo->GetNUrls() > 1)
1488 fileInfo->RemoveUrl(curl->GetUrl());
1492 }
else if (stgf && !(fileInfo->TestBit(TFileInfo::kStaged))) {
1499 if (maxfiles > 0 && newstagedfiles >= maxfiles)
1506 TUrl *curl = fileInfo->GetCurrentUrl();
1507 const char *furl = curl->GetUrl();
1509 Bool_t mapped = kFALSE;
1510 if (TDataSetManager::CheckDataSetSrvMaps(curl, urlmod) && !(urlmod.IsNull())) {
1511 furl = urlmod.Data();
1518 stager = createStager ? TFileStager::Open(url.GetUrl()) : stager;
1520 Bool_t result = kFALSE;
1522 result = stager->IsStaged(url.GetUrl());
1524 ::Info(
"TDataSetManager::CheckStagedStatus",
"IsStaged: %s: %d", url.GetUrl(), result);
1528 ::Warning(
"TDataSetManager::CheckStagedStatus",
1529 "could not get stager instance for '%s'", url.GetUrl());
1534 if (fileInfo->TestBit(TFileInfo::kStaged)) {
1536 fileInfo->ResetBit(TFileInfo::kStaged);
1541 if (!(fileInfo->TestBit(TFileInfo::kStaged))) {
1543 fileInfo->SetBit(TFileInfo::kStaged);
1550 url.SetOptions(curl->GetOptions());
1551 url.SetAnchor(curl->GetAnchor());
1552 fileInfo->AddUrl(url.GetUrl(), kTRUE);
1561 void TDataSetManager::ProcessFile(TFileInfo *fileInfo, Int_t sopt, Bool_t checkstg, Bool_t doall,
1562 TFileStager* stager, Bool_t createStager,
const char *stageopts,
1563 Bool_t dbg, Bool_t& changed, Bool_t& opened)
1567 Bool_t fullproc = (sopt == 0) ? kTRUE : kFALSE;
1568 Bool_t locateonly = (sopt == 1) ? kTRUE : kFALSE;
1569 Bool_t stageonly = (sopt == 2) ? kTRUE : kFALSE;
1577 TUrl *curl = fileInfo->GetCurrentUrl();
1578 const char *furl = curl->GetUrl();
1581 if (TDataSetManager::CheckDataSetSrvMaps(curl, urlmod) && !(urlmod.IsNull())) {
1582 furl = urlmod.Data();
1590 if (!stager || (stager && !stager->Matches(url.GetUrl()))) {
1592 if (!(stager = TFileStager::Open(url.GetUrl())) || !(stager->IsValid())) {
1593 ::Error(
"TDataSetManager::ProcessFile",
1594 "could not get valid stager instance for '%s'", url.GetUrl());
1602 if (stager && stager->Locate(url.GetUrl(), eurl) == 0) {
1603 TString opts(curl->GetOptions());
1604 TString anch(curl->GetAnchor());
1608 curl->SetOptions(opts);
1609 curl->SetAnchor(anch);
1615 ::Error(
"TDataSetManager::ProcessFile",
"could not locate %s", url.GetUrl());
1618 }
else if (stageonly) {
1620 if (stager && !(stager->IsStaged(url.GetUrl()))) {
1621 if (!(stager->Stage(url.GetUrl(), stageopts))) {
1623 ::Error(
"TDataSetManager::ProcessFile",
1624 "problems issuing stage request for %s", url.GetUrl());
1627 }
else if (fullproc) {
1631 Bool_t doscan = kTRUE;
1634 if ((doall && fileInfo->TestBit(TFileInfo::kStaged)) ||
1635 (stager && stager->IsStaged(url.GetUrl()))) doscan = kTRUE;
1638 if ((rc = TDataSetManager::ScanFile(fileInfo, dbg)) < -1)
return;
1640 }
else if (stager) {
1641 ::Warning(
"TDataSetManager::ProcessFile",
1642 "required file '%s' does not look as being online (staged)", url.GetUrl());
1655 Int_t TDataSetManager::ScanFile(TFileInfo *fileinfo, Bool_t dbg)
1660 ::Error(
"TDataSetManager::ScanFile",
"undefined input (!)");
1664 TUrl *url = fileinfo->GetCurrentUrl();
1667 Bool_t anchor = kFALSE;
1670 Int_t timeout = gEnv->GetValue(
"DataSet.ScanFile.OpenTimeout", -1);
1672 if (timeout > 0) fileopt.Form(
"TIMEOUT=%d", timeout);
1678 const char *furl = url->GetUrl();
1680 if (TDataSetManager::CheckDataSetSrvMaps(url, urlmod) && !(urlmod.IsNull()))
1681 furl = urlmod.Data();
1682 if (strlen(url->GetAnchor()) > 0) {
1685 TUrl urlNoAnchor(furl);
1686 urlNoAnchor.SetAnchor(
"");
1687 TString unaopts = urlNoAnchor.GetOptions();
1688 if (!unaopts.IsNull()) {
1689 unaopts +=
"&filetype=raw";
1691 unaopts =
"filetype=raw";
1693 urlNoAnchor.SetOptions(unaopts);
1695 if (!(file = TFile::Open(urlNoAnchor.GetUrl(), fileopt)))
return rc;
1698 if (file->GetSize() > 0) fileinfo->SetSize(file->GetSize());
1699 fileinfo->SetBit(TFileInfo::kStaged);
1701 fileinfo->SetUUID(file->GetUUID().AsString());
1704 if (file->GetEndpointUrl()) {
1706 TUrl eurl(*(file->GetEndpointUrl()));
1708 if (strcmp(eurl.GetProtocol(),
"file") ||
1709 !strcmp(eurl.GetProtocol(), url->GetProtocol())) {
1711 eurl.SetOptions(url->GetOptions());
1712 eurl.SetAnchor(url->GetAnchor());
1715 if (!strcmp(eurl.GetHost(),
"localhost") || !strcmp(eurl.GetHost(),
"127.0.0.1") ||
1716 !strcmp(eurl.GetHost(),
"localhost.localdomain")) {
1717 eurl.SetHost(TUrl(gSystem->HostName()).GetHostFQDN());
1720 if (strcmp(eurl.GetUrl(), url->GetUrl()))
1721 fileinfo->AddUrl(eurl.GetUrl(), kTRUE);
1723 if (gDebug > 0) ::Info(
"TDataSetManager::ScanFile",
"added URL %s", eurl.GetUrl());
1726 ::Warning(
"TDataSetManager::ScanFile",
"end-point URL undefined for file %s", file->GetName());
1737 Int_t oldLevel = gErrorIgnoreLevel;
1738 gErrorIgnoreLevel = kError+1;
1741 if (!(file = TFile::Open(url->GetUrl(), fileopt))) {
1743 if (dbg) ::Info(
"TDataSetManager::ScanFile",
"marking %s as corrupt", url->GetUrl());
1744 fileinfo->SetBit(TFileInfo::kCorrupted);
1746 gErrorIgnoreLevel = oldLevel;
1748 }
else if (!anchor) {
1750 if (file->GetSize() > 0) fileinfo->SetSize(file->GetSize());
1751 fileinfo->SetBit(TFileInfo::kStaged);
1754 TUrl eurl(*(file->GetEndpointUrl()));
1756 if (strcmp(eurl.GetProtocol(),
"file") ||
1757 !strcmp(eurl.GetProtocol(), url->GetProtocol())) {
1759 eurl.SetOptions(url->GetOptions());
1760 eurl.SetAnchor(url->GetAnchor());
1763 if (!strcmp(eurl.GetHost(),
"localhost") || !strcmp(eurl.GetHost(),
"127.0.0.1") ||
1764 !strcmp(eurl.GetHost(),
"localhost.localdomain")) {
1765 eurl.SetHost(TUrl(gSystem->HostName()).GetHostFQDN());
1768 if (strcmp(eurl.GetUrl(), url->GetUrl()))
1769 fileinfo->AddUrl(eurl.GetUrl(), kTRUE);
1771 if (gDebug > 0) ::Info(
"TDataSetManager::ScanFile",
"added URL %s", eurl.GetUrl());
1773 fileinfo->SetUUID(file->GetUUID().AsString());
1779 if ((rc = TDataSetManager::FillMetaData(fileinfo, file,
"/")) != 0) {
1780 ::Error(
"TDataSetManager::ScanFile",
1781 "problems processing the directory tree in looking for metainfo");
1782 fileinfo->SetBit(TFileInfo::kCorrupted);
1786 gErrorIgnoreLevel = oldLevel;
1802 Int_t TDataSetManager::FillMetaData(TFileInfo *fi, TDirectory *d,
const char *rdir)
1805 if (!fi || !d || !rdir) {
1806 ::Error(
"TDataSetManager::FillMetaData",
1807 "some inputs are invalid (fi:%p,d:%p,r:%s)", fi, d, rdir);
1811 if (d->GetListOfKeys()) {
1812 TIter nxk(d->GetListOfKeys());
1814 while ((k = dynamic_cast<TKey *> (nxk()))) {
1816 if (TClass::GetClass(k->GetClassName())->InheritsFrom(TDirectory::Class())) {
1818 TDirectory *sd = (TDirectory *) d->Get(k->GetName());
1820 ::Error(
"TDataSetManager::FillMetaData",
"cannot get sub-directory '%s'", k->GetName());
1823 if (TDataSetManager::FillMetaData(fi, sd, TString::Format(
"%s%s/", rdir, k->GetName())) != 0) {
1824 ::Error(
"TDataSetManager::FillMetaData",
"problems processing sub-directory '%s'", k->GetName());
1830 if (!TClass::GetClass(k->GetClassName())->InheritsFrom(TTree::Class()))
continue;
1833 ks.Form(
"%s%s", rdir, k->GetName());
1835 TFileInfoMeta *md = fi->GetMetaData(ks);
1838 md =
new TFileInfoMeta(ks, k->GetClassName());
1839 fi->AddMetaData(md);
1841 ::Info(
"TDataSetManager::FillMetaData",
"created meta data for tree %s", ks.Data());
1844 TTree *t =
dynamic_cast<TTree *
> (d->Get(k->GetName()));
1846 if (t->GetEntries() >= 0) {
1847 md->SetEntries(t->GetEntries());
1848 if (t->GetTotBytes() >= 0)
1849 md->SetTotBytes(t->GetTotBytes());
1850 if (t->GetZipBytes() >= 0)
1851 md->SetZipBytes(t->GetZipBytes());
1854 ::Error(
"TDataSetManager::FillMetaData",
"could not get tree '%s'", k->GetName());
1868 TList *TDataSetManager::ParseDataSetSrvMaps(
const TString &srvmaps)
1870 TList *srvmapslist = 0;
1871 if (srvmaps.IsNull()) {
1872 ::Warning(
"TDataSetManager::ParseDataSetSrvMaps",
1873 "called with an empty string! - nothing to do");
1876 TString srvmap, sf, st;
1877 Int_t from = 0, from1 = 0;
1878 while (srvmaps.Tokenize(srvmap, from,
" ")) {
1880 if (srvmap.Contains(
"|")) {
1882 if (srvmap.Tokenize(sf, from1,
"|"))
1883 if (srvmap.Tokenize(st, from1,
"|")) { }
1888 ::Warning(
"TDataSetManager::ParseDataSetSrvMaps",
1889 "parsing DataSet.SrvMaps: target must be defined"
1890 " (token: %s) - ignoring", srvmap.Data());
1892 }
else if (!(st.EndsWith(
"/"))) {
1898 if (!(sf.IsNull()) && sf.Contains(
"*")) {
1900 if (!(sf.BeginsWith(u->GetProtocol()))) u->SetProtocol(
"root");
1901 sp.Form(
":%d", u->GetPort());
1902 if (!(sf.Contains(sp))) u->SetPort(1094);
1903 if (!TString(u->GetHost()).Contains(
"*")) SafeDelete(u);
1905 if (!srvmapslist) srvmapslist =
new TList;
1907 srvmapslist->Add(
new TPair(u,
new TObjString(st)));
1909 srvmapslist->Add(
new TPair(
new TObjString(sf),
new TObjString(st)));
1913 if (srvmapslist) srvmapslist->SetOwner(kTRUE);
1920 TList *TDataSetManager::GetDataSetSrvMaps()
1922 return fgDataSetSrvMaps;
1931 Bool_t TDataSetManager::CheckDataSetSrvMaps(TUrl *furl, TString &file1, TList *srvmaplist)
1933 Bool_t replaced = kFALSE;
1934 if (!furl)
return replaced;
1936 const char *file = furl->GetUrl();
1937 TList *mlist = (srvmaplist) ? srvmaplist : fgDataSetSrvMaps;
1938 if (mlist && mlist->GetSize() > 0) {
1941 while ((pr = (TPair *) nxm())) {
1942 Bool_t replace = kFALSE;
1944 TUrl *u =
dynamic_cast<TUrl *
>(pr->Key());
1946 if (!strcmp(u->GetProtocol(), furl->GetProtocol())) {
1948 if (!strcmp(u->GetProtocol(),
"file")) {
1949 TRegexp re(u->GetFileAndOptions(), kTRUE);
1950 if (re.Index(furl->GetFileAndOptions(), &len) == 0) replace = kTRUE;
1952 if (u->GetPort() == furl->GetPort()) {
1953 TRegexp re(u->GetHost(), kTRUE);
1954 if (re.Index(furl->GetHost(), &len) == 0) replace = kTRUE;
1959 TObjString *os =
dynamic_cast<TObjString *
>(pr->Key());
1961 if (os->GetString().IsNull() ||
1962 !strncmp(file, os->GetName(), os->GetString().Length())) replace = kTRUE;
1966 TObjString *ost =
dynamic_cast<TObjString *
>(pr->Value());
1968 file1.Form(
"%s%s", ost->GetName(), furl->GetFileAndOptions());
1982 void TDataSetManager::SetScanCounters(Int_t t, Int_t o, Int_t d)
1984 fNTouchedFiles = (t > -1) ? t : fNTouchedFiles;
1985 fNOpenedFiles = (o > -1) ? o : fNOpenedFiles;
1986 fNDisappearedFiles = (d > -1) ? d : fNDisappearedFiles;