ATLAS Offline Software
Classes | Functions
AtlCoolCopy.cxx File Reference
#include <algorithm>
#include <cmath>
#include <ctime>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
#include <curl/curl.h>
#include "CoolKernel/DatabaseId.h"
#include "CoolKernel/Exception.h"
#include "CoolKernel/IDatabaseSvc.h"
#include "CoolKernel/IDatabase.h"
#include "CoolKernel/IFolder.h"
#include "CoolKernel/FolderSpecification.h"
#include "CoolKernel/IFolderSet.h"
#include "CoolKernel/IObject.h"
#include "CoolKernel/IObjectIterator.h"
#include "CoolKernel/IRecordIterator.h"
#include "CoolApplication/Application.h"
#include "CoralBase/AttributeListException.h"
#include "FileCatalog/IFileCatalog.h"
#include "PersistencySvc/IDatabase.h"
#include "PersistencySvc/ISession.h"
#include "PersistencySvc/ITransaction.h"
#include "PersistencySvc/SimpleUtilityBase.h"
#include "RelationalAccess/ConnectionService.h"
#include "RelationalAccess/IConnectionServiceConfiguration.h"
#include "RelationalAccess/ISessionProxy.h"
#include "RelationalAccess/ITransaction.h"
#include "RelationalAccess/ISchema.h"
#include "RelationalAccess/ITable.h"
#include "RelationalAccess/IQuery.h"
#include "RelationalAccess/ICursor.h"
#include "CoraCool/CoraCoolDatabase.h"
#include "CoraCool/CoraCoolFolder.h"
#include "CoraCool/CoraCoolObjectIter.h"
#include "CoraCool/CoraCoolObject.h"
#include "CxxUtils/checker_macros.h"
#include "PoolMapElement.h"
#include "ReplicaSorter.h"
#include "CoolTagInfo.h"
#include "TFile.h"
#include "TTree.h"
#include "TH1.h"
#include "TObjString.h"

Go to the source code of this file.

Classes

class  AtlCoolCopy
 

Functions

size_t WriteCallback (void *contents, size_t size, size_t nmemb, std::string *s)
 
void printHelp ()
 
int AtlCoolCopy::copyFolder ATLAS_NOT_THREAD_SAFE (const std::string &folder, const std::vector< std::string > &taglist)
 
int AtlCoolCopy::copyIOVs ATLAS_NOT_THREAD_SAFE (const std::string &folder, const std::string &destfolder, const cool::IFolderPtr &sourcefl, const CoraCoolFolderPtr &sourceflc, const cool::IFolderPtr &destfl, const CoraCoolFolderPtr &destflc, const std::string &sourcetag, const std::string &desttag, const cool::ValidityKey since, const cool::ValidityKey until, bool timestamp, bool checkrefs, bool iscora, const cool::PayloadMode::Mode paymode, bool created)
 
int AtlCoolCopy::doCopy ATLAS_NOT_THREAD_SAFE ()
 Install fatal handler with default options. More...
 
int main ATLAS_NOT_THREAD_SAFE (int argc, const char *argv[])
 

Function Documentation

◆ ATLAS_NOT_THREAD_SAFE() [1/4]

int AtlCoolCopy::doCopy ATLAS_NOT_THREAD_SAFE ( )
inline

Install fatal handler with default options.

This is meant to be easy to call from python via ctypes.

Definition at line 2092 of file AtlCoolCopy.cxx.

2092  {
2093  if (isOpen()) {
2094  int retcode=0;
2095  // execute copy for all defined folders
2096  for (std::vector<std::string>::const_iterator ifolder=
2097  m_folderlist.begin();ifolder!=m_folderlist.end();++ifolder) {
2098  int code=copyFolder(*ifolder,m_tags);
2099  if (code>retcode) retcode=code;
2100  }
2101  if (!m_hiparent.empty()) {
2102  // fill in any hierarchical tags for parent folders
2103  int code=tagParents();
2104  if (code>retcode) retcode=code;
2105  }
2106  if (m_copytaginfo) {
2107  // write information (tag description, lock status) to dest tags
2108  int code=writeTagInfo();
2109  if (code>retcode) retcode=code;
2110  }
2111  if (m_checkrefs) {
2112  int code=0;
2113  if (m_poolcat.empty()) {
2114  code=listPoolRefs();
2115  if (!m_checkoutputfile.empty()) filePoolRefs();
2116  } else {
2117  code=resolvePoolRefs();
2118  }
2119  if (code>retcode) retcode=code;
2120  }
2121  if (p_rootfile) {
2122  p_rootfile->Write();
2123  delete p_rootfile;
2124  }
2125  return retcode;
2126  } else {
2127  return 10;
2128  }
2129 }

◆ ATLAS_NOT_THREAD_SAFE() [2/4]

int AtlCoolCopy::copyIOVs ATLAS_NOT_THREAD_SAFE ( const std::string &  folder,
const std::string &  destfolder,
const cool::IFolderPtr &  sourcefl,
const CoraCoolFolderPtr sourceflc,
const cool::IFolderPtr &  destfl,
const CoraCoolFolderPtr destflc,
const std::string &  sourcetag,
const std::string &  desttag,
const cool::ValidityKey  since,
const cool::ValidityKey  until,
bool  timestamp,
bool  checkrefs,
bool  iscora,
const cool::PayloadMode::Mode  paymode,
bool  created 
)

Definition at line 877 of file AtlCoolCopy.cxx.

885  {
886 
887  std::cout << "Copying tag " << sourcetag << " of folder " << folder <<
888  " to destination tag " << desttag << std::endl;
889  cool::FolderVersioning::Mode vermode=sourcefl->versioningMode();
890  cool::FolderVersioning::Mode dvermode=destfl->versioningMode();
891  // check for online mode
892  int updatemode=getUpdateMode(destfl->description(),desttag);
893  std::vector<std::string> dtaglist=destfl->listTags();
894  // if online mode, must have --getonline and either -truncate or -alliov
895  // only if destination DB is oracle
896  if (updatemode==1 && m_destdb.find("oracle")!=std::string::npos &&
897  (!m_getonline || (!m_truncate && !m_alliov))) {
898  if (m_ignoremode) {
899  std::cout << "Folder is online (UPD1) mode but IGNORING PROTECTION"
900  << std::endl;
901  } else {
902  if(find(dtaglist.begin(),dtaglist.end(),desttag)!=dtaglist.end()) {
903  std::cout << "Folder is online mode (UPD1) and tag already exist - -getonline and -truncate or -alliov options MUST be used" << std::endl;
904  return 35;
905  }
906  else {
907  std::cout << "Folder is online mode (UPD1), new tag will be created" << std::endl;
908  }
909 
910  }
911  }
912  // if UPD4 mode, must have -getbulk and either -truncate or -alliov
913  if (updatemode==4 && m_destdb.find("oracle")!=std::string::npos &&
914  (!m_getbulk || (!m_truncate && !m_alliov))) {
915  if (m_ignoremode) {
916  std::cout << "Folder is bulkreco (UPD4) mode but IGNORING PROTECTION"
917  << std::endl;
918  } else {
919  if(find(dtaglist.begin(),dtaglist.end(),desttag)!=dtaglist.end()) {
920  std::cout << "Folder is bulkreco mode (UPD4) - -getbulk and -truncate or -alliov options MUST be used" << std::endl;
921  return 35;
922  } else {
923  std::cout << "Folder is bulkreco mode (UPD4), new tag will be created" << std::endl;
924  }
925 
926  }
927  }
928 
929  // if destination tags are being checked, check if this tag already
930  // exists in destination folder, if so skip copy
931  // also skip if tag is HEAD, and folder was not newly created
932  if (m_checkdesttag) {
933  if (find(dtaglist.begin(),dtaglist.end(),desttag)!=dtaglist.end()
934  || (desttag=="HEAD" && !created)) {
935  std::cout << "Destination tag " << desttag <<
936  " already exists in folder " << folder << " - skip copy" << std::endl;
937  return 0;
938  }
939  }
940  bool relock=false; // tag must be relocked afterwards
941  bool prot=false; //update is protected, irrespective of if tag must be locked
942  if ((m_applock || (updatemode==1 && m_getonline) || updatemode==2 ||
943  (updatemode==4 && m_getbulk)) &&
944  dvermode==cool::FolderVersioning::MULTI_VERSION) {
945  // check if the destination tag exists and is locked
946  std::vector<std::string> dtaglist=destfl->listTags();
947  for (std::vector<std::string>::const_iterator itr=dtaglist.begin();
948  itr!=dtaglist.end();++itr) {
949  if (desttag==*itr) {
950  // tag exists - must protect it unless ignoremode
951  prot=!m_ignoremode;
952  // check lock status
953  if (destfl->tagLockStatus(desttag)==cool::HvsTagLock::LOCKED) {
954  std::cout << "Unlocking destination tag " << desttag <<
955  " for append or UPDx access" << std::endl;
956  if (m_applocksv) {
957  std::cout << "Appending according to SV folder rules" << std::endl;
958  if (updatemode!=3) {
959  std::cout <<
960  "ERROR: Only allowed for UPD3 mode tags" << std::endl;
961  return 36;
962  }
963  }
964  destfl->setTagLockStatus(desttag,cool::HvsTagLock::UNLOCKED);
965  relock=true;
966  }
967  }
968  }
969  }
970  int nobj=0;
971  int nbuf=0;
972  int nskip=0;
973  int nbad=0;
974  // set up tag to be used at point of insertion
975  std::string localtag="";
976  if (dvermode==cool::FolderVersioning::MULTI_VERSION &&
977  desttag!="HEAD" && m_usertags) localtag=desttag;
978  // now loop over IOVs - separate for CoraCool and COOL
979  try {
980  if (iscora) {
981  // branch for CoraCool
982  sourceflc->setPrefetchAll(false);
983  CoraCoolObjectIterPtr sourceitr;
984  if (vermode==cool::FolderVersioning::SINGLE_VERSION) {
985  sourceitr=sourceflc->browseObjects(since,until,m_chansel);
986  } else {
987  sourceitr=sourceflc->browseObjects(since,until,m_chansel,sourcetag);
988  }
989  // keep track of new FKs of inserted objects
990  std::map<int,int> insertkeymap;
991  unsigned int nref=0;
992  while (sourceitr->hasNext()) {
993  CoraCoolObjectPtr obj=sourceitr->next();
994  // check object should not be skipped as spreading outside select-IOV
995  if (m_skipout &&
996  (obj->since()<m_srunemin || obj->until()>m_srunemax)) {
997  ++nskip;
998  continue;
999  }
1000  // check object should not be skipped as excluded channel
1001  if (!m_excludechans.empty()) {
1002  if (find(m_excludechans.begin(),m_excludechans.end(),
1003  obj->channelId())!=m_excludechans.end()) {
1004  ++nskip;
1005  continue;
1006  }
1007  }
1008  if (nbuf==0) {
1009  if (m_debug) std::cout <<
1010  "Setup new CoraCool storage buffer at object " << nobj << std::endl;
1011  destflc->setupStorageBuffer();
1012  }
1013  cool::ValidityKey newsince,newuntil;
1014  adjustIOVs(obj->since(),obj->until(),since,until,newsince,newuntil,
1015  timestamp);
1016  // skip negative/zero IOV lengths
1017  if (newsince>=newuntil) {
1018  std::cout << "WARNING: Skipping IOV with since " << newsince <<
1019  ">= until" << newuntil << std::endl;
1020  ++nbad;
1021  continue;
1022  }
1023  // find the old FK, check if we have already inserted this
1024  // in which case a reference can be added
1025  int oldfk=0;
1026  std::map<int,int>::const_iterator ikey=insertkeymap.end();
1027  bool foundkey=false;
1028  // ensure returned data is not of zero size - if so cannot extract
1029  // and remember the FK
1030  if (obj->size()>0) {
1031  oldfk=sourceflc->getAttrKey(
1032  (*obj->begin())[sourceflc->coralFKey()]);
1033  ikey=insertkeymap.find(oldfk);
1034  foundkey=true;
1035  }
1036  if (ikey==insertkeymap.end()) {
1037  int newfk=
1038  destflc->storeObject(newsince,newuntil,obj->begin(),obj->end(),
1039  obj->channelId(),localtag,
1040  (!m_userupdatehead && !localtag.empty()));
1041  if (foundkey) insertkeymap[oldfk]=newfk;
1042  } else {
1043  destflc->referenceObject(newsince,newuntil,ikey->second,
1044  obj->channelId(),localtag,
1045  (!m_userupdatehead && !localtag.empty()));
1046  ++nref;
1047  }
1048  ++nbuf;
1049  // flush buffer every m_bufsize objects
1050  if (nbuf==m_bufsize) {
1051  if (m_debug) std::cout << "Flush buffer after " << nobj << "," <<
1052  nbuf << " objects " << std::endl;
1053  // note CoraCool requires explicit re-setup of buffer after a flush
1054  destflc->flushStorageBuffer();
1055  destflc->setupStorageBuffer();
1056  nbuf=0;
1057  }
1058  ++nobj;
1059  }
1060  sourceitr->close();
1061  if (nref>0) std::cout << "Reference-to-existing used for " << nref
1062  << " payload objects" << std::endl;
1063  if (nbuf>0) {
1064  if (m_debug) std::cout << "Final buffer flush at " << nobj <<
1065  "," << nbuf << std::endl;
1066  destflc->flushStorageBuffer();
1067  }
1068  } else {
1069  // branch for pure COOL objects
1070  cool::IObjectIteratorPtr sourceitr;
1071  if (vermode==cool::FolderVersioning::SINGLE_VERSION) {
1072  sourceitr=sourcefl->browseObjects(since,until,m_chansel);
1073  } else {
1074  sourceitr=sourcefl->browseObjects(since,until,m_chansel,sourcetag);
1075  }
1076  while (sourceitr->goToNext()) {
1077  const cool::IObject& obj=sourceitr->currentRef();
1078  // check object should not be skipped as spreading outside select-IOV
1079  if (m_skipout && (obj.since()<m_srunemin || obj.until()>m_srunemax)) {
1080  ++nskip;
1081  continue;
1082  }
1083  // check object should not be skipped as excluded channel
1084  if (!m_excludechans.empty()) {
1085  if (find(m_excludechans.begin(),m_excludechans.end(),
1086  obj.channelId())!=m_excludechans.end()) {
1087  ++nskip;
1088  continue;
1089  }
1090  }
1091  if (nbuf==0) {
1092  if (m_debug) std::cout << "Setup new storage buffer at object " <<
1093  nobj << std::endl;
1094  destfl->setupStorageBuffer();
1095  }
1096  cool::ValidityKey newsince;
1097  cool::ValidityKey newuntil;
1098  adjustIOVs(obj.since(),obj.until(),since,until,newsince,newuntil,
1099  timestamp);
1100  // skip negative/zero IOV lengths
1101  if (newsince>=newuntil) {
1102  std::cout << "WARNING: Skipping IOV with since " << newsince <<
1103  ">= until" << newuntil << std::endl;
1104  ++nbad;
1105  continue;
1106  }
1107  if (checkrefs) checkRef(obj.payload(),folder,sourcetag);
1108  if (prot) {
1109  // check existing data in destination DB to ensure no clash
1110  if (m_applocksv) {
1111  // appendlockedsv mode - all IOV ends must be infinite
1112  // and new since must be greater than old since
1113  if (newuntil!=cool::ValidityKeyMax) {
1114  std::cout << "New IOVs must have until=cool::ValidityKeyMax" << std::endl;
1115  throw cool::Exception("Illegal insert over locked IOV",
1116  "AtlCoolCopy");
1117  }
1118  cool::IObjectIteratorPtr checkitr=destfl->browseObjects(newsince,
1119  newuntil,obj.channelId(),desttag);
1120  while (checkitr->goToNext()) {
1121  const cool::IObject& checkobj=checkitr->currentRef();
1122  if (checkobj.since()>=newsince) {
1123  std::cout << "ERROR:: Attempt to insert SV overlapping IOV whilst appending to locked tag" << std::endl;
1124  throw cool::Exception("Illegal insert over locked IOV",
1125  "AtlCoolCopy");
1126  }
1127  if (checkobj.until()!=cool::ValidityKeyMax) {
1128  std::cout << "Existing IOVs must have until=cool::ValidityKeyMax" << std::endl;
1129  throw cool::Exception("Illegal insert over locked IOV",
1130  "AtlCoolCopy");
1131  }
1132  }
1133  checkitr->close();
1134  } else if (m_applock) {
1135  // appendlocked mode - just make sure no objects in this IOV
1136  const unsigned int nexist=
1137  destfl->countObjects(newsince,newuntil,obj.channelId(),desttag);
1138  if (nexist>0) {
1139  std::cout << "ERROR: Attempt to insert IOV over " << nexist <<
1140  " objects whilst appending to locked tag" << std::endl;
1141  throw cool::Exception("Illegal insert over locked IOV",
1142  "AtlCoolCopy");
1143  }
1144  } else if (updatemode==2) {
1145  // UPD2 tag - make sure run is on list of runs open for update
1146  // only for run/lumi based folders
1147  if (timestamp)
1148  throw cool::Exception(
1149  "Attempt to insert into locked UPD2 tag with timestamp format",
1150  "AtlCoolCopy");
1151  unsigned int run1=newsince >> 32;
1152  unsigned int run2=(newuntil-1) >> 32;
1153  for (unsigned int irun=run1;irun<=run2;++irun) {
1154  if (!std::binary_search(m_runlist.begin(),m_runlist.end(),irun))
1155  {
1156  std::cout << "Run " << irun << " from range [" << run1 << ","
1157  << run2 << "] not found in runfile list" << std::endl;
1158  throw cool::Exception("Illegal insert over locked IOV",
1159  "AtlCoolCopy");
1160  }
1161  }
1162  }
1163  // updatemode==1 will fall through, but no checks are done here
1164  }
1165  if (paymode==cool::PayloadMode::VECTORPAYLOAD) {
1166  // cool vector payload object copy
1167  cool::IRecordIterator& pitr=obj.payloadIterator();
1168  const cool::IRecordVectorPtr vptr=pitr.fetchAllAsVector();
1169  destfl->storeObject(newsince,newuntil,
1170  *vptr,obj.channelId(),localtag,
1171  (!m_userupdatehead && !localtag.empty()));
1172  nbuf+=vptr->size();
1173  pitr.close();
1174  } else {
1175  // standard COOL object copy
1176  destfl->storeObject(newsince,newuntil,
1177  obj.payload(),obj.channelId(),localtag,
1178  (!m_userupdatehead && !localtag.empty()));
1179  ++nbuf;
1180  }
1181  // flush buffer every m_bufsize objects
1182  if (nbuf>=m_bufsize) {
1183  if (m_debug) std::cout << "Flush buffer after " << nobj << "," <<
1184  nbuf << " objects " << std::endl;
1185  destfl->flushStorageBuffer();
1186  nbuf=0;
1187  }
1188  ++nobj;
1189  }
1190  // finished with the iterator
1191  sourceitr->close();
1192  if (nbuf>0) {
1193  if (m_debug) std::cout << "Final buffer flush at " << nobj <<
1194  "," << nbuf << std::endl;
1195  destfl->flushStorageBuffer();
1196  } // end of COOL-specific part
1197  }
1198  std::cout << "Folder copied with " << nobj << " objects" << std::endl;
1199  if (nskip>0) std::cout << nskip <<
1200  " objects were skipped extending outside IOV selection or excluded channel"
1201  << std::endl;
1202  if (nbad>0) std::cout << nbad <<
1203  " objects were skipped having zero or negative IOV lengths" << std::endl;
1204  }
1205  // exceptions thrown from insert loop (both COOL or CORACOOL)
1206  catch (cool::Exception& e) {
1207  std::cout << "Exception thrown from copy loop: " << e.what() <<
1208  std::endl;
1209  if (relock) {
1210  std::cout << "Relocking destination tag " << desttag << std::endl;
1211  destfl->setTagLockStatus(desttag,cool::HvsTagLock::LOCKED);
1212  }
1213  return 31;
1214  }
1215  // check if tag needs to be relocked
1216  if (relock) {
1217  std::cout << "Relocking destination tag " << desttag << std::endl;
1218  destfl->setTagLockStatus(desttag,cool::HvsTagLock::LOCKED);
1219  }
1220 
1221  if (dvermode==cool::FolderVersioning::MULTI_VERSION && desttag!="HEAD") {
1222  if (!m_usertags) {
1223  // apply HEAD style tagging
1224  std::cout << "Tag folder with HEAD-style tagging for tag: " << desttag
1225  << std::endl;
1226  try {
1227  destfl->tagCurrentHead(desttag,sourcefl->tagDescription(sourcetag));
1228  }
1229  catch (cool::Exception& e) {
1230  std::cout << "Exception thrown in HEAD-style folder-tag: " <<
1231  e.what() << std::endl;
1232  return 32;
1233  }
1234  }
1235  // record information about this tag for later
1236  if (m_copytaginfo) m_cooltagmap.insert(
1237  CoolTagMap::value_type(desttag,CoolTagInfo(m_sourceDbPtr,folder,
1238  destfolder,sourcetag,desttag,m_taglabel)));
1239  // check if any hierarchical tags reference the just-copied tag
1240  if (!m_hitagmap.empty()) {
1241  for (HiTagMap::const_iterator imap=m_hitagmap.begin();
1242  imap!=m_hitagmap.end();++imap) {
1243  try {
1244  if (sourcefl->findTagRelation(imap->first)==sourcetag) {
1245  std::cout << "Create hierarchical tag between " << desttag <<
1246  " and " << imap->first << " in folder " << imap->second <<
1247  std::endl;
1248  // first check this relation has not already been created
1249  try {
1250  std::string etag=destfl->resolveTag(imap->first);
1251  if (etag==desttag) {
1252  std::cout << "This relation has already been created" << std::endl;
1253  } else {
1254  std::cout << "ERROR: Tag in parent already related to " <<
1255  desttag << std::endl;
1256  }
1257  }
1258  catch (cool::Exception& e ) {
1259  // only do creation if does not already exist - via exception
1260  try {
1261  destfl->createTagRelation(imap->first,desttag);
1262  // check if this implicates a new parent folder
1263  // to be checked for further tags up the tree
1264  if (find(m_hiparent.begin(),m_hiparent.end(),imap->second)==
1265  m_hiparent.end()) m_hiparent.push_back(imap->second);
1266  // store the original tag information to transfer
1267  // properties later
1268  if (m_copytaginfo &&
1269  m_cooltagmap.find(imap->first)==m_cooltagmap.end())
1270  m_cooltagmap.insert(CoolTagMap::value_type(imap->first,
1271  CoolTagInfo(m_sourceDbPtr,imap->second,imap->second,
1272  imap->first,imap->first)));
1273  }
1274  catch (cool::Exception& e) {
1275  std::cout << "Cool exception " << e.what() <<
1276  "thrown in hierarchical tag creation" << std::endl;
1277  return 34;
1278  }
1279  }
1280  }
1281  }
1282  catch (cool::Exception& e) {
1283  }
1284  }
1285  }
1286  }
1287  return 0;
1288 }

◆ ATLAS_NOT_THREAD_SAFE() [3/4]

int AtlCoolCopy::copyFolder ATLAS_NOT_THREAD_SAFE ( const std::string &  folder,
const std::vector< std::string > &  taglist 
)

Definition at line 534 of file AtlCoolCopy.cxx.

535  {
536  // get source folder
537  cool::IFolderPtr sourcefl,destfl;
538  CoraCoolFolderPtr sourceflc,destflc;
539  try {
540  sourcefl=m_sourceDbPtr->getFolder(folder);
541  }
542  catch (cool::Exception& e) {
543  std::cout << "Could not get source folder: " << folder << std::endl;
544  return 20;
545  }
546  const std::string& sourcedesc=sourcefl->description();
547  // check if folder should be skipped from replication
548  if (m_skiprep && sourcedesc.find("<norep/>")!=std::string::npos) {
549  std::cout << "Folder " << folder <<
550  " skipped due to <norep/> metadata" << std::endl;
551  return 0;
552  }
553  const bool iscora=(m_coracool &&
554  sourcedesc.find("<coracool")!=std::string::npos);
555  if (iscora) {
556  // activate CoraCool and get source folder pointer
557  openCoraCool();
558  sourceflc=m_sourceCoraPtr->getFolder(folder);
559  }
560  // setup the channel-range
561  setChannelRange(sourcefl);
562 
563  cool::FolderVersioning::Mode vermode=sourcefl->versioningMode();
564  cool::FolderVersioning::Mode dvermode=vermode;
565  if (m_forcesingle) {
566  dvermode=cool::FolderVersioning::SINGLE_VERSION;
567  std::cout << "Forcing destination folder to singleversion" << std::endl;
568  }
569  if (m_forcemulti) {
570  dvermode=cool::FolderVersioning::MULTI_VERSION;
571  std::cout << "Forcing destination folder to multiversion" << std::endl;
572  }
573  // setup type of folder (payload mode, inline, separate, or vector)
574  const cool::PayloadMode::Mode spaymode=
575  sourcefl->folderSpecification().payloadMode();
576  cool::PayloadMode::Mode dpaymode=spaymode;
577 
578  // set name for destination folder
579  std::string destfolder=folder;
580  if (!m_outfolder.empty()) {
581  destfolder=m_outfolder;
582  std::cout << "Destination folder will be renamed to " << destfolder <<
583  std::endl;
584  }
585 
586 // get destination folder, try to create if not there (and not verifying!)
587  bool created=false;
588  if (!m_nocopy && !m_root && !m_analyse) {
589  if (!m_destDbPtr->existsFolder(destfolder) && !m_verify) {
590  std::cout << "Creating folder " << destfolder << " payload-type " <<
591  dpaymode << " on destination" << std::endl;
592  created=true;
593  std::string metadata=sourcedesc;
594  if (m_forcerune || m_forcetime) {
595  std::string newmeta=m_forcerune ? "run-lumi" : "time";
596  std::string::size_type p1,p2;
597  p1=metadata.find("<timeStamp>");
598  p2=metadata.find("</timeStamp>");
599  if (p1!=std::string::npos && p2!=std::string::npos) {
600  metadata.replace(0,p2,"<timeStamp>"+newmeta);
601  std::cout << "Forced destination folder to " << newmeta << " : "
602  << metadata << std::endl;
603  } else {
604  std::cout <<
605  "ERROR: Could not parse metadata string to force timestamp type"
606  << std::endl;
607  }
608  }
609  // force separate or inline payload, but not if input is vector
610  if (m_forcepay && spaymode!=cool::PayloadMode::VECTORPAYLOAD)
611  dpaymode=cool::PayloadMode::SEPARATEPAYLOAD;
612  if (m_forcenopay && spaymode!=cool::PayloadMode::VECTORPAYLOAD)
613  dpaymode=cool::PayloadMode::INLINEPAYLOAD;
614 
615  try {
616  if (iscora) {
617  destflc=m_destCoraPtr->createFolder(destfolder,
618  sourceflc->coralTableName(),
619  sourceflc->fkSpecification(),
620  sourceflc->payloadSpecification(),
621  sourceflc->coralFKey(),
622  sourceflc->coralPKey(),
623  metadata,dvermode,true);
624  std::cout << "Created CoraCool folder" << std::endl;
625  destfl=m_destDbPtr->getFolder(destfolder);
626  } else {
627  destfl=m_destDbPtr->createFolder(destfolder,
628  cool::FolderSpecification(dvermode,
629  sourcefl->payloadSpecification(),dpaymode),
630  metadata,true);
631  }
632  }
633  catch (cool::Exception&e ) {
634  std::cout << "Create folder failed - aborting" << std::endl;
635  return 30;
636  }
637  }
638  // now get the pointer to destination folder if needed
639  // note both COOL and CoraCool pointers are set if needed
640  try {
641  if (iscora) destflc=m_destCoraPtr->getFolder(destfolder);
642  destfl=m_destDbPtr->getFolder(destfolder);
643  }
644  catch (cool::Exception& e) {
645  std::cout << "Could not get destination folder: " << destfolder
646  << std::endl;
647  return 21;
648  }
649  // check payload specifications of folders are the same
650  const cool::IRecordSpecification& sourcespec=
651  sourcefl->payloadSpecification();
652  const cool::IRecordSpecification& destspec=
653  destfl->payloadSpecification();
654  if (!(sourcespec==destspec)) {
655  bool badspec=false;
656  if (m_ignorespec) {
657  // specifications differ - check names are same
658  std::cout <<
659  "WARNING Source and destination folder specifications differ" <<
660  std::endl;
661  for (unsigned int i=0;i<sourcespec.size();++i) {
662  const std::string& sname=sourcespec[i].name();
663  if (!destspec.exists(sname)) {
664  std::cout << "ERROR: Field " << sname << " absent from destination"
665  << std::endl;
666  badspec=true;
667  }
668  }
669  } else {
670  badspec=true;
671  }
672  if (badspec) {
673  std::cout <<
674  "ERROR Source and destination folder specifications differ"
675  << std::endl;
676  return 22;
677  }
678  }
679  // check folder descriptions are the same - just print WARNING if not
680  const std::string& destdesc=destfl->description();
681  if (sourcedesc!=destdesc) {
682  std::cout << "WARNING: Source and destination folder descriptions (meta-data) differ" << std::endl;
683  std::cout << "Source folder: " << sourcedesc << std::endl;
684  std::cout << "Destn folder: " << destdesc << std::endl;
685  }
686  // check payload modes are same - print warning if not
687  const cool::PayloadMode::Mode dpaymode=
688  destfl->folderSpecification().payloadMode();
689  if (spaymode!=dpaymode) {
690  std::cout << "WARNING: Source (" << spaymode << ") and destination (" <<
691  dpaymode << " folder payload modes differ" << std::endl;
692  }
693 
694  // check/set channels table if requested
695  if (!m_nochannel) {
696  if (!checkChannels(folder,sourcefl,destfl,created)) return 23;
697  }
698  }
699  // if only copying structures, stop here
700  if (m_nodata) return 0;
701  // extract folder/range information
702  std::cout << "Start to process folder: " << folder;
703  // check for timestamp XML
704  bool timestamp=(sourcefl->description().find("<timeStamp>time")!=
705  std::string::npos);
706  cool::ValidityKey since,until;
707  if (timestamp) {
708  since=m_timemin;
709  until=m_timemax;
710  std::cout << " (timestamp)" << std::endl;
711  } else {
712  since=m_runemin;
713  until=m_runemax;
714  std::cout << " (run/lumi)" << std::endl;
715  }
716  if (m_alliov || m_truncate)
717  std::cout << "Output IOVs will be modified" << std::endl;
718  if (m_skipout)
719  std::cout << "IOVs extending outside selection range will be skipped"
720  << std::endl;
721 
722  bool checkrefs=false;
723  const std::string name0=sourcefl->payloadSpecification()[0].name();
724  if (m_checkrefs && (name0=="PoolRef" || name0=="fileGUID")) {
725  checkrefs=true;
726  std::cout << "Check POOL references in folder " << folder << std::endl;
727  }
728  // if nocopy, and checking POOL references, and folder is not a POOL ref one
729  // can skip the data access
730  if (m_checkrefs && m_nocopy && !checkrefs) return 0;
731 
732  // check for <fullrep/> metadata indicating copy all tags if -skiprep option
733  bool copyall=
734  (m_skiprep && (sourcedesc.find("<fullrep/>")!=std::string::npos));
735  if (copyall) std::cout <<
736  "All tags in folder will be copied due to <fullrep/> metadata" << std::endl;
737 
738  // set up true list of tags to copy
739  std::vector<std::string> tags;
740  if (vermode==cool::FolderVersioning::SINGLE_VERSION) {
741  std::cout << "Single version folder" << std::endl;
742  tags.emplace_back("HEAD");
743  } else {
744  std::cout << "Multi version folder: consider tags [ ";
745  // get list of tags in this node which are requested
746  const std::vector<std::string> foldertags=sourcefl->listTags();
747  for (std::vector<std::string>::const_iterator itag=foldertags.begin();
748  itag!=foldertags.end();++itag) {
749  bool copyit=copyall;
750  // if input taglist is empty, take all tags in folder
751  if (taglist.empty() ||
752  find(taglist.begin(),taglist.end(),*itag)!=taglist.end())
753  copyit=true;
754  for (std::vector<std::string>::const_iterator imtag=m_magic.begin();
755  imtag!=m_magic.end();++imtag) {
756  if (itag->find(*imtag)!=std::string::npos) copyit=true;
757  }
758  if (copyit) {
759  tags.push_back(*itag);
760  std::cout << *itag << " ";
761  }
762  }
763  // if no tags were found, or doing inclusive hierarchical tag copying
764  // try resolving input tags hierarchically
765  if (tags.empty() || m_hitag) {
766  for (std::vector<std::string>::const_iterator itag=taglist.begin();
767  itag!=taglist.end();++itag) {
768  try {
769  std::string htag=sourcefl->resolveTag(*itag);
770  if (find(tags.begin(),tags.end(),htag)==tags.end()) {
771  std::cout << *itag << "=" << htag << " ";
772  tags.push_back(htag);
773  }
774  }
775  // ignore exceptions indicating tag not defined here
776  // note std::exception rather than COOL exception to cover case
777  // when trying to resolve a leaf tag in the '/' folder, which
778  // throws a coral AttributeException
779  catch (std::exception& e) { }
780  }
781  }
782  std::cout << "]" << std::endl;
783  // if still no tags were found, or forced HEAD tag copying, or no
784  // tags in the folder at all (=MV folder being used as SV), add HEAD
785  if (((tags.empty() || m_includehead) && !m_excludehead) ||
786  foldertags.empty())
787  tags.emplace_back("HEAD");
788  }
789 
790  sourcefl->setPrefetchAll(false);
791  for (std::vector<std::string>::const_iterator itag=tags.begin();
792  itag!=tags.end();++itag) {
793  std::string outtag=*itag;
794  if (!m_outtag.empty()) outtag=m_outtag;
795  int retcode;
796  // verify or copy folder
797  if (m_verify) {
798  retcode=verifyIOVs(folder,sourcefl,sourceflc,destfl,destflc,
799  *itag,since,until,checkrefs,iscora,spaymode);
800  } else if (m_nocopy) {
801  retcode=nocopyIOVs(folder,sourcefl,*itag,since,until,checkrefs);
802  } else if (m_root) {
803  retcode=rootIOVs(folder,sourcefl,*itag,since,until,timestamp);
804  } else if (m_analyse) {
805  retcode=analyseIOVs(folder,sourcefl,*itag,since,until,timestamp);
806  } else {
807  retcode=copyIOVs(folder,destfolder,sourcefl,sourceflc,destfl,destflc,
808  *itag,outtag,since,until,timestamp,checkrefs,iscora,
809  spaymode,created);
810  }
811  if (retcode!=0) {
812  std::cout << "ERROR operation failed for folder " << folder << " tag " <<
813  *itag << std::endl;
814  return retcode;
815  }
816  }
817  return 0;
818 }

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

int main ATLAS_NOT_THREAD_SAFE ( int  argc,
const char *  argv[] 
)

Definition at line 3475 of file AtlCoolCopy.cxx.

3475  {
3476  int retcode=0;
3477  if (argc<3) {
3478  printHelp();
3479  retcode=1;
3480  } else {
3481  AtlCoolCopy mycopy(argv[1],argv[2]);
3482  retcode=mycopy.setOpts(argc-3,&argv[3]);
3483  if (retcode==999) {
3484  printHelp();
3485  return 0;
3486  }
3487  if (retcode==0) retcode=mycopy.doCopy();
3488  }
3489  if (retcode>0) std::cout << "ERROR AtlCoolCopy.exe fails with exit code " <<
3490  retcode << std::endl;
3491  return retcode;
3492 }

◆ printHelp()

void printHelp ( )

Definition at line 3345 of file AtlCoolCopy.cxx.

3345  {
3346  std::cout << "usage: AtlCoolCopy.exe <sourceCoolDB> <destinationCoolDB> { <options> }" << std::endl;
3347  std::cout << "Options are (see doc/mainpage.h for more):" << std::endl <<
3348  "-a, -alliov : set IOVs on destination to [ValidityKeyMin, ValidityKeyMax]" << std::endl <<" or following settings of -nrls,-nrlu,-nts,-ntu" <<
3349  std::endl <<
3350  "-ag, -addguid <guid> : Add GUID to list accessed for POOL checks" <<
3351  std::endl <<
3352  "-alf, -addlfn <LFN> : Add LFN to list accessed for POOL checks" <<
3353  std::endl <<
3354  "-al, -appendlocked : Allow locked tags to be updated if no overlap" <<
3355  std::endl <<
3356  "-alsv, -appendlockedsv : Allow locked tag update for openended IOVs" <<
3357  std::endl <<
3358  "-ana, -analyse <delta_t>: produce analysis ROOT file (filename = dest DB argument)" << std::endl <<
3359 "-bs, -buffersize <size> : set size of bulkstorage output buf to <size> objs"
3360  << std::endl <<
3361  "-c, -create : create destination DB if not already existing"
3362  << std::endl <<
3363  "-cd, -checkdest : Check destination DB and skip already existing tags"
3364  << std::endl <<
3365  "-ch, -channel : restrict selection to given channel or range specified as c1:c2" << std::endl <<
3366  "-ch1, -channel1 : specify start of a range of channels" << std::endl <<
3367  "-ch2, -channel2 : specify end of a range of channels" << std::endl <<
3368  "-cf, -checkfiles : check POOL files can be opened and have correct GUID"
3369  << std::endl <<
3370  "-co, -checkoutput <file> : write POOL file check output on file"
3371  << std::endl << "-cti, -copytaginfo : Copy tag descriptions"
3372  << std::endl << "-ctl, -copytaglock : Copy tag locked status and descriptions"
3373  << std::endl << "-cr, -checkrefs : check POOL references"
3374  << std::endl << "-d, -debug : produce debug output" << std::endl;
3375  std::cout <<
3376  "-ds, -dataset : output register.sh for creating DQ2 datasets "
3377  << std::endl <<
3378  "-ec, -excludechannel : exclude given channel from copy" << std::endl <<
3379  "-eh, -excludehead : exclude HEAD tag even if no tags found in MV folders"
3380  << std::endl <<
3381  "-ih, -includehead : include HEAD as well as any tags in MV folders" <<
3382  std::endl <<
3383  "-e, -exclude <pattern> : exclude folders" << std::endl <<
3384  "-f, -folder <pattern> : include folders" << std::endl <<
3385  "-fs, -forcesingle : force destination folder to be singleversion"
3386  << std::endl <<
3387  "-fm, -forcemulti : force destination folder to be multiversion"
3388  << std::endl <<
3389  "-frl, -forcerunlumi : force destination folder to be run/LB indexed"
3390  << std::endl <<
3391  "-ftm, -forcetime : force destination folder to be timestamp indexed"
3392  << std::endl <<
3393  "-fp, -forcepayload : Force destn folders to be created with payload tbl" << std::endl <<
3394  "-fnp, -forcenopayload : Force destn folders to be created without payload tbl" << std::endl <<
3395  "-forcerecreate : delete and recreate destination database" << std::endl;
3396  std::cout << "-ht, -headtag : Use HEAD-style tagging"
3397  << std::endl <<
3398  "-go, -getonline : Set minimum run number (-rls setting) to next ONLINE run"
3399  << std::endl <<
3400  "-gb, -getbulk : Set minimum run number (-rls setting) to next bulk reco run"
3401  << std::endl <<
3402  "-gt, -gettime : Extract timestamp information for given run number range"
3403  << std::endl <<
3404  "-h, -help : print help and exit" << std::endl <<
3405  "-hi, -hitag : Copy hierrchical tags inclusively" << std::endl <<
3406  "-ignoremode <pwd> : Ignore UPDx mode protection (experts only)"
3407  << std::endl <<
3408  "-is, -ignorespec : Ignore differences in folder spec if names are all equal" << std::endl <<
3409  "-lo, -lockedonly : Only copy locked/partially-locked top-level tags"
3410  << std::endl <<
3411  "-nc, -nocopy : Do not actually copy, just read source DB" << std::endl <<
3412  "-nch, -nochannel : Do not check or copy channel information" << std::endl
3413 << "-ncr, -noclobroot: Do not copy CLOB data into ROOT files" << std::endl
3414 << "-noc, -nocoracool : Do not copy Coracool structure payloads " << std::endl <<
3415  "-nd, -nodata : Copy only folder structures, not data" << std::endl <<
3416  "-nh, -nohitag : Do not follow hierarchical tag relations" << std::endl <<
3417 "-mc, -mergecat <catfile> : specify POOL file catalogue for new dataset making"
3418  << std::endl;
3419  std::cout << "-of, -outfolder <folder> : rename folder on output"
3420  << std::endl <<
3421  "-onr, -onlinerun : Retrieve run number from online server (not replica)" <<std::endl <<
3422  "-ot, -outtag : " << "Rename tag on output" << std::endl;
3423  std::cout <<
3424  "-pa, -poolall : Output all POOL files (incl good) when checking files"
3425  << std::endl <<
3426 "-pc, -poolcat <catfile> : specify POOL file catalogue for ref checking"
3427  << std::endl <<
3428  "-pf, -parfile <file> : Read additional options/parameters from file" <<
3429  std::endl <<
3430 "-pt, -prunetags : Copy only hierarchical tags descending from specified toptags"
3431  << std::endl <<
3432 "-rdo, -readoracle : force data to be read from Oracle, using dbreplica.config"
3433  << std::endl <<
3434  "-sl, -seal <val>: Set SEAL (hence COOL/POOL) output level to <val>"
3435  << std::endl <<
3436  "-sr, -skiprep : Skip folders having <norep/> folder metadata tag" <<
3437  std::endl <<
3438  "-t, -tag <tag> : Copy multiversion data with tag <tag>" << std::endl <<
3439  "-mt, -magic <tag> : Include magic tags involving the given pattern " << std::endl <<
3440 "-tr, -truncate : Set destination IOVs outside query interval to query interval"
3441  << std::endl <<
3442 "-tl, -taglabel : Specify tag description to enter in destination DB"
3443  << std::endl <<
3444  "-uht, -userheadtag : Also copy user tag data to the HEAD" << std::endl <<
3445  "-v, -verify : Verify data present on destination rather than copying" <<
3446  std::endl <<
3447  "-ro, -root : Produce ROOT output file instead of copying to COOL"
3448  << std::endl <<
3449  "-zn, -zeronull : Zero NULLs in ROOT file instead of skipping them" <<
3450  std::endl <<
3451  "-rls, -runlumisince <run> <LB> : Set minimum IOV interval" << std::endl <<
3452  "-rlu, -runlumiuntil <run> <LB> : Set maximum IOV interval" << std::endl <<
3453  "-rs, -runsince <run> : Set minimum IOV interval" << std::endl <<
3454  "-ru, -rununtil <run> : Set maximum IOV interval" << std::endl <<
3455  "-r, -run <run> : Copy only run <run>" << std::endl <<
3456 "-srls, -skiprunlumisince <run> <LB> : Set minimum IOV for skipping IOV in copy"
3457  << std::endl <<
3458 "-srlu, -skiprunlumiuntil <run> <LB> : Set maximum IOV for skipping IOV in copy"
3459  << std::endl <<
3460  "-tdb, -timedb <dbconn> : Set database connection for time information" <<
3461  "-ts, -timesince <time> : Set minimum IOV interval (UTC SECONDs or UTC YYYY-MM-DD:hh:mm:ss)" <<
3462  std::endl <<
3463  "-tu, -timeuntil <time> : Set maximum IOV interval (UTC SECONDs or UTC YYYY-MM-DD:hh:mm:ss)" <<
3464  std::endl;
3465  std::cout <<
3466  "-nrls, -newrunlumisince <run> <LB> : Set minimum of output IOV interval (use with -alliov)" << std::endl <<
3467  "-nrlu, -newrunlumiuntil <run> <LB> : Set maximum of output IOV interval (use with --aliov)" << std::endl <<
3468  "-nts, -newtimesince <time> : Set minimum of outputIOV interval (UTC SECONDs or UTC YYYY-MM-DD:hh:mm:ss) (use with --alliov)" <<
3469  std::endl <<
3470  "-ntu, -newtimeuntil <time> : Set maximum of output IOV interval (UTC SECONDs or UTC YYYY-MM-DD:hh:mm:ss) (use with --alliov)" <<
3471  std::endl;
3472  std::cout << "See http://twiki.cern.ch/twiki/bin/view/Atlas/AtlCoolCopy for more details" << std::endl;
3473 }

◆ WriteCallback()

size_t WriteCallback ( void *  contents,
size_t  size,
size_t  nmemb,
std::string *  s 
)

Definition at line 64 of file AtlCoolCopy.cxx.

64  {
65  size_t newLength = size * nmemb;
66 
67  try
68  {
69  s->append((char *)contents, newLength);
70  }
71  catch (std::bad_alloc &e)
72  {
73  // handle memory problem
74  return 0;
75  }
76  return newLength;
77 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
AtlCoolCopy
Definition: AtlCoolCopy.cxx:80
CheckTagAssociation.localtag
localtag
Definition: CheckTagAssociation.py:19
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
CheckTagAssociation.taglist
taglist
Definition: CheckTagAssociation.py:103
dq_defect_copy_defect_database.since
def since
Definition: dq_defect_copy_defect_database.py:54
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
dq_defect_copy_defect_database.until
def until
Definition: dq_defect_copy_defect_database.py:55
python.TileCalibTools.copyFolder
def copyFolder(dbr, dbw, folder, tagr, tagw, chanNum, pointInTime1, pointInTime2)
Definition: TileCalibTools.py:446
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
histSizes.code
code
Definition: histSizes.py:129
tags
std::vector< std::string > tags
Definition: hcg.cxx:102
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
maskDeadModules.run1
run1
Definition: maskDeadModules.py:40
calibdata.exception
exception
Definition: calibdata.py:495
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:19
contents
void contents(std::vector< std::string > &keys, TDirectory *td, const std::string &directory, const std::string &pattern, const std::string &path)
Definition: computils.cxx:321
CoraCoolFolderPtr
boost::shared_ptr< CoraCoolFolder > CoraCoolFolderPtr
Definition: CoraCoolTypes.h:15
ReadCellNoiseFromCoolCompare.run2
run2
Definition: ReadCellNoiseFromCoolCompare.py:53
printHelp
void printHelp()
Definition: AtlCoolCopy.cxx:3345
EventContainers::Mode
Mode
Definition: IdentifiableContainerBase.h:13
mc.nskip
nskip
Definition: mc.PhPy8EG_Hto4l_NNLOPS_nnlo_30_ggH125_ZZ4l.py:41
CoolTagInfo
Definition: CoolTagInfo.h:16
TileSynchronizeBch.copyall
copyall
Definition: TileSynchronizeBch.py:47
CoraCoolObjectIterPtr
boost::shared_ptr< CoraCoolObjectIter > CoraCoolObjectIterPtr
Definition: CoraCoolTypes.h:21
CoraCoolObjectPtr
boost::shared_ptr< CoraCoolObject > CoraCoolObjectPtr
Definition: CoraCoolTypes.h:18
makeDTCalibBlob_pickPhase.outtag
string outtag
Definition: makeDTCalibBlob_pickPhase.py:286
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
CaloCondBlobAlgs_fillNoiseFromASCII.folder
folder
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:55
python.PyAthena.obj
obj
Definition: PyAthena.py:132