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 "PersistencySvc/IFileCatalog.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 2094 of file AtlCoolCopy.cxx.

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

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

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

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

◆ printHelp()

void printHelp ( )

Definition at line 3353 of file AtlCoolCopy.cxx.

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

◆ WriteCallback()

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

Definition at line 61 of file AtlCoolCopy.cxx.

61 {
62 size_t newLength = size * nmemb;
63
64 try
65 {
66 s->append((char *)contents, newLength);
67 }
68 catch (std::bad_alloc &e)
69 {
70 // handle memory problem
71 return 0;
72 }
73 return newLength;
74}
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)