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 ( void )
inline

Install fatal handler with default options.

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

Install fatal handler with default options.

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

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

◆ printHelp()

void printHelp ( )

Definition at line 3354 of file AtlCoolCopy.cxx.

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

◆ 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)