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/PersistencySvcException.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 2082 of file AtlCoolCopy.cxx.

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

◆ 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 878 of file AtlCoolCopy.cxx.

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

◆ 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 535 of file AtlCoolCopy.cxx.

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

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

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

Definition at line 3465 of file AtlCoolCopy.cxx.

3465  {
3466  int retcode=0;
3467  if (argc<3) {
3468  printHelp();
3469  retcode=1;
3470  } else {
3471  AtlCoolCopy mycopy(argv[1],argv[2]);
3472  retcode=mycopy.setOpts(argc-3,&argv[3]);
3473  if (retcode==999) {
3474  printHelp();
3475  return 0;
3476  }
3477  if (retcode==0) retcode=mycopy.doCopy();
3478  }
3479  if (retcode>0) std::cout << "ERROR AtlCoolCopy.exe fails with exit code " <<
3480  retcode << std::endl;
3481  return retcode;
3482 }

◆ printHelp()

void printHelp ( )

Definition at line 3335 of file AtlCoolCopy.cxx.

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

◆ WriteCallback()

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

Definition at line 65 of file AtlCoolCopy.cxx.

65  {
66  size_t newLength = size * nmemb;
67 
68  try
69  {
70  s->append((char *)contents, newLength);
71  }
72  catch (std::bad_alloc &e)
73  {
74  // handle memory problem
75  return 0;
76  }
77  return newLength;
78 }
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
AtlCoolCopy
Definition: AtlCoolCopy.cxx:81
CheckTagAssociation.localtag
localtag
Definition: CheckTagAssociation.py:19
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CheckTagAssociation.taglist
taglist
Definition: CheckTagAssociation.py:103
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
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:441
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
tags
std::vector< std::string > tags
Definition: hcg.cxx:102
lumiFormat.i
int i
Definition: lumiFormat.py:92
maskDeadModules.run1
run1
Definition: maskDeadModules.py:40
calibdata.exception
exception
Definition: calibdata.py:496
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
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:319
CoraCoolFolderPtr
boost::shared_ptr< CoraCoolFolder > CoraCoolFolderPtr
Definition: CoraCoolTypes.h:15
ReadCellNoiseFromCoolCompare.run2
run2
Definition: ReadCellNoiseFromCoolCompare.py:53
pmontree.code
code
Definition: pmontree.py:443
printHelp
void printHelp()
Definition: AtlCoolCopy.cxx:3335
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
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
CoraCoolObjectIterPtr
boost::shared_ptr< CoraCoolObjectIter > CoraCoolObjectIterPtr
Definition: CoraCoolTypes.h:21
CoraCoolObjectPtr
boost::shared_ptr< CoraCoolObject > CoraCoolObjectPtr
Definition: CoraCoolTypes.h:18
BchCleanup.outtag
outtag
Definition: BchCleanup.py:109
CaloCondBlobAlgs_fillNoiseFromASCII.folder
folder
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:56
python.PyAthena.obj
obj
Definition: PyAthena.py:135