ATLAS Offline Software
Loading...
Searching...
No Matches
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 "GaudiUtils/IFileCatalog.h"
#include "GaudiUtils/IFileCatalogMgr.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/Bootstrap.h"
#include "StorageSvc/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.
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 2099 of file AtlCoolCopy.cxx.

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

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

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

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

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

◆ ATLAS_NOT_THREAD_SAFE() [4/4]

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

Definition at line 3482 of file AtlCoolCopy.cxx.

3482 {
3483 int retcode=0;
3484 if (argc<3) {
3485 printHelp();
3486 retcode=1;
3487 } else {
3488 AtlCoolCopy mycopy(argv[1],argv[2]);
3489 retcode=mycopy.setOpts(argc-3,&argv[3]);
3490 if (retcode==999) {
3491 printHelp();
3492 return 0;
3493 }
3494 if (retcode==0) retcode=mycopy.doCopy();
3495 }
3496 if (retcode>0) std::cout << "ERROR AtlCoolCopy.exe fails with exit code " <<
3497 retcode << std::endl;
3498 return retcode;
3499}
void printHelp()

◆ printHelp()

void printHelp ( )

Definition at line 3352 of file AtlCoolCopy.cxx.

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

◆ 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}
size_t size() const
Number of registered mappings.
void contents(std::vector< std::string > &keys, TDirectory *td, const std::string &directory, const std::string &pattern, const std::string &path)