]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliRawEvent.cxx
close TAliEn result handle after OpenDir().
[u/mrichter/AliRoot.git] / RAW / AliRawEvent.cxx
index d844bcaf4dee1e6a5a3aeac1093fb20d9926eb8e..5e5efd58610aaf0f3660f494f999d2150f990f2e 100644 (file)
@@ -62,25 +62,25 @@ const Int_t kMDC = 5;
 
 // Fixed file system locations for the different DB's
 #ifdef USE_RDM
-const char *kFifo       = "/tmp/alimdc.fifo";
-const char *kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
-const char *kTagDBFS    = "/tmp/mdc1/tags";
-const char *kRunDBFS    = "/tmp/mdc1/meta";
-const char *kRFIOFS     = "rfio:/castor/cern.ch/user/r/rdm";
-const char *kCastorFS   = "castor:/castor/cern.ch/user/r/rdm";
-const char *kRootdFS    = "root://localhost//tmp/mdc1";
-const char *kAlienHost  = "alien://aliens7.cern.ch:15000/?direct";
-const char *kAlienDir   = "/alice_mdc/DC";
+const char* const kFifo       = "/tmp/alimdc.fifo";
+const char* const kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
+const char* const kTagDBFS    = "/tmp/mdc1/tags";
+const char* const kRunDBFS    = "/tmp/mdc1/meta";
+const char* const kRFIOFS     = "rfio:/castor/cern.ch/user/r/rdm";
+const char* const kCastorFS   = "castor:/castor/cern.ch/user/r/rdm";
+const char* const kRootdFS    = "root://localhost//tmp/mdc1";
+const char* const kAlienHost  = "alien://aliens7.cern.ch:15000/?direct";
+const char* const kAlienDir   = "/alice_mdc/DC";
 #else
-const char *kFifo       = "/tmp/alimdc.fifo";
-const char *kRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
-const char *kTagDBFS    = "/data1/mdc/tags";
-const char *kRunDBFS    = "/data1/mdc/meta";
-const char *kRFIOFS     = "rfio:/castor/cern.ch/lcg/dc5";
-const char *kCastorFS   = "castor:/castor/cern.ch/lcg/dc5";
-const char *kRootdFS    = "root://localhost//tmp/mdc1";
-const char *kAlienHost  = "alien://aliens7.cern.ch:15000/?direct";
-const char *kAlienDir   = "/alice_mdc/DC";
+const char* const kFifo       = "/tmp/alimdc.fifo";
+const char* const kRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
+const char* const kTagDBFS    = "/data1/mdc/tags";
+const char* const kRunDBFS    = "/data1/mdc/meta";
+const char* const kRFIOFS     = "rfio:/castor/cern.ch/lcg/dc5";
+const char* const kCastorFS   = "castor:/castor/cern.ch/lcg/dc5";
+const char* const kRootdFS    = "root://localhost//tmp/mdc1";
+const char* const kAlienHost  = "alien://aliens7.cern.ch:15000/?direct";
+const char* const kAlienDir   = "/alice_mdc/DC";
 #endif
 
 // Maximum size of tag db files
@@ -201,12 +201,23 @@ AliRawEvent::AliRawEvent()
    // raw data object, otherwise a private copy will be made.
 
    fNSubEvents = 0;
-   fEvtHdr     = new AliRawEventHeader;
+   fEvtHdr     = 0;
    fEqpHdr     = 0;
    fRawData    = 0;
    fSubEvents  = 0;
 }
 
+//______________________________________________________________________________
+AliRawEventHeader *AliRawEvent::GetHeader()
+{
+   // Get event header part of AliRawEvent.
+
+   if (!fEvtHdr)
+      fEvtHdr = new AliRawEventHeader;
+
+   return fEvtHdr;
+}
+
 //______________________________________________________________________________
 AliRawEquipmentHeader *AliRawEvent::GetEquipmentHeader()
 {
@@ -377,7 +388,7 @@ void AliStats::WriteToDB(AliRawDB *rawdb)
    ds->cd();
 
    // Write stats also in the bookkeeping RunDB
-   AliRunDB *rundb = new AliRunDB;
+   AliRunDB *rundb = new AliRunDB(kTRUE);
    rundb->Update(this);
    rundb->UpdateRDBMS(this);
    rundb->UpdateAliEn(this);
@@ -408,7 +419,7 @@ AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
 }
 
 //______________________________________________________________________________
-Bool_t AliRawDB::FSHasSpace(const char *fs)
+Bool_t AliRawDB::FSHasSpace(const char *fs) const
 {
    // Check for at least fMaxSize bytes of free space on the file system.
    // If the space is not available return kFALSE, kTRUE otherwise.
@@ -430,7 +441,7 @@ Bool_t AliRawDB::FSHasSpace(const char *fs)
 }
 
 //______________________________________________________________________________
-const char *AliRawDB::GetFileName()
+const char *AliRawDB::GetFileName() const
 {
    // Return filename based on hostname and date and time. This will make
    // each file unique. Also makes sure (via FSHasSpace()) that there is
@@ -476,14 +487,34 @@ Bool_t AliRawDB::Create()
 {
    // Create a new raw DB.
 
+   const Int_t kMaxRetry = 200;
+   const Int_t kMaxSleep = 1;      // seconds
+   const Int_t kMaxSleepLong = 10; // seconds
+   Int_t retry = 0;
+
 again:
+   if (gAliMDC && gAliMDC->StopLoop())
+      return kFALSE;
+
    const char *fname = GetFileName();
-   if (!fname) return kFALSE;
+   if (!fname) {
+      Error("Create", "error getting raw DB file name");
+      return kFALSE;
+   }
+
+   retry++;
 
-   fRawDB = TFile::Open(fname, "RECREATE",
-                        Form("ALICE MDC%d raw DB", kMDC), fCompress);
+   fRawDB = TFile::Open(fname, GetOpenOption(),
+                        Form("ALICE MDC%d raw DB", kMDC), fCompress,
+                        GetNetopt());
    if (!fRawDB) {
-      Error("Create", "did not find right plugin to open file");
+      if (retry < kMaxRetry) {
+         Warning("Create", "failure to open file, sleeping %d %s before retrying...",
+                 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
+         gSystem->Sleep(kMaxSleep*1000);
+         goto again;
+      }
+      Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
       return kFALSE;
    }
    if (fRawDB->IsZombie()) {
@@ -492,12 +523,22 @@ again:
           fRawDB->GetErrno() == 1027) {     // SESYSERR
          fRawDB->ResetErrno();
          delete fRawDB;
-         Warning("Create", "file is zombie, sleeping 10 seconds before retrying...");
-         gSystem->Sleep(10000);   // sleep 10 seconds before retrying
+         Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
+                 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
+         gSystem->Sleep(kMaxSleepLong*1000);   // sleep 10 seconds before retrying
          goto again;
       }
-      Error("Create", "error opening raw DB");
+      Error("Create", "file %s is zombie", fname);
+      fRawDB->ResetErrno();
+      delete fRawDB;
       fRawDB = 0;
+      if (retry < kMaxRetry) {
+         Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
+                 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
+         gSystem->Sleep(kMaxSleep*1000);
+         goto again;
+      }
+      Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
       return kFALSE;
    }
 
@@ -602,7 +643,7 @@ AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress)
 }
 
 //______________________________________________________________________________
-const char *AliRawRFIODB::GetFileName()
+const char *AliRawRFIODB::GetFileName() const
 {
    // Return filename based on hostname and date and time. This will make
    // each file unique. Also the directory will be made unique for each
@@ -694,7 +735,7 @@ AliRawCastorDB::AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compr
 }
 
 //______________________________________________________________________________
-const char *AliRawCastorDB::GetFileName()
+const char *AliRawCastorDB::GetFileName() const
 {
    // Return filename based on hostname and date and time. This will make
    // each file unique. Also the directory will be made unique for each
@@ -777,7 +818,7 @@ AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compres
 }
 
 //______________________________________________________________________________
-const char *AliRawRootdDB::GetFileName()
+const char *AliRawRootdDB::GetFileName() const
 {
    // Return filename based on hostname and date and time. This will make
    // each file unique. Also the directory will be made unique for each
@@ -857,7 +898,7 @@ AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
 }
 
 //______________________________________________________________________________
-const char *AliRawNullDB::GetFileName()
+const char *AliRawNullDB::GetFileName() const
 {
    // Return /dev/null as filename.
 
@@ -968,7 +1009,7 @@ Float_t AliTagDB::GetCompressionFactor() const
 }
 
 //______________________________________________________________________________
-const char *AliTagDB::GetFileName()
+const char *AliTagDB::GetFileName() const
 {
    // Return filename based on hostname and date and time. This will make
    // each file unique. The tags will be stored in the /data1/tags directory.
@@ -1006,7 +1047,7 @@ AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) :
 }
 
 //______________________________________________________________________________
-const char *AliTagNullDB::GetFileName()
+const char *AliTagNullDB::GetFileName() const
 {
    // Return /dev/null as filename.
 
@@ -1034,10 +1075,14 @@ void AliTagNullDB::Close()
 
 
 //______________________________________________________________________________
-AliRunDB::AliRunDB()
+AliRunDB::AliRunDB(Bool_t noLocalDB)
 {
    // Open run database, and get or create tree.
 
+   fRunDB = 0;
+
+   if (noLocalDB) return;
+
    // Get hostname
    char hostname[64], filename[64];
    const char *fs = kRunDBFS;
@@ -1064,6 +1109,8 @@ void AliRunDB::Update(AliStats *stats)
 {
    // Add stats object to database.
 
+   if (!stats || !fRunDB) return;
+
    TDirectory *ds = gDirectory;
    fRunDB->cd();
 
@@ -1087,6 +1134,8 @@ void AliRunDB::UpdateRDBMS(AliStats *stats)
 {
    // Add stats object to central MySQL DB.
 
+   if (!stats) return;
+
    char sql[4096];
    char bt[25], et[25];
 
@@ -1127,16 +1176,39 @@ void AliRunDB::UpdateAliEn(AliStats *stats)
 {
    // Record file in AliEn catalog.
 
+   if (!stats) return;
+
    TGrid *g = TGrid::Connect(kAlienHost, "");
 
    TString lfn = kAlienDir;
+   TDatime dt;
+
+   // make a subdirectory for each day
+   lfn += "/adc-";
+   lfn += dt.GetDate();
+
+   // check if directory exists, if not create it
+   Grid_ResultHandle_t res;
+   if (!(res = g->OpenDir(lfn))) {
+      // directory does not exist, create it
+      if (g->Mkdir(lfn, kTRUE) == -1) {
+         Error("UpdateAliEn", "cannot create directory %s", lfn.Data());
+         lfn = kAlienDir;
+      }
+   }
+   if (res) g->CloseResult(res);
+
    lfn += "/";
    lfn += gSystem->BaseName(stats->GetFileName());
 
-   //printf("AliEn: AddFile(%s, %s, %d)\n", lfn.Data(), stats->GetFileName(),
-   //       (int)stats->GetFileSize());
+   Int_t result = g->AddFile(lfn, stats->GetFileName(),
+                            (int)stats->GetFileSize());
 
-   g->AddFile(lfn, stats->GetFileName(), (int)stats->GetFileSize());
+   if (result == -1) {
+      Error("UpdateAliEn", "error adding file to AliEn catalog");
+      printf("AliEn: AddFile(%s, %s, %d)\n", lfn.Data(), stats->GetFileName(),
+             (int)stats->GetFileSize());
+   }
 
    delete g;
 }
@@ -1146,17 +1218,24 @@ void AliRunDB::Close()
 {
    // Close run database.
 
-   fRunDB->Close();
+   if (fRunDB) fRunDB->Close();
    delete fRunDB;
 }
 
 //----------------- Use SIGUSR1 to interupt endless loop -----------------------
 class AliMDCInterruptHandler : public TSignalHandler {
-private:
-   AliMDC *fMDC;   // alimdc to signal
 public:
    AliMDCInterruptHandler(AliMDC *mdc) : TSignalHandler(kSigUser1, kFALSE), fMDC(mdc) { }
-   Bool_t Notify() { fMDC->SetStopLoop(); return kTRUE; }
+   Bool_t Notify() {
+      Info("Notify", "received a SIGUSR1 signal");
+      fMDC->SetStopLoop();
+      return kTRUE;
+   }
+private:
+   AliMDC *fMDC;   // alimdc to signal
+
+   AliMDCInterruptHandler(const AliMDCInterruptHandler &);
+   void operator=(const AliMDCInterruptHandler &);
 };
 
 //______________________________________________________________________________
@@ -1297,7 +1376,8 @@ Int_t AliMDC::Run()
 
    // Process input stream
 #ifdef USE_EB
-   while (!ebEor()) {
+   Int_t eorFlag = 0;
+   while (!(eorFlag = ebEor())) {
       struct iovec *ebvec;
       if ((ebvec = ebGetNextEvent()) == (void *)-1) {
          Error("Run", "error getting next event (%s)", ebGetLastError());
@@ -1328,10 +1408,12 @@ Int_t AliMDC::Run()
          }
          return 1;
       }
+      ALIDEBUG(3)
+         header.Dump();
 
       // If we were in looping mode stop directly after a SIGUSR1 signal
       if (StopLoop()) {
-         Info("Run", "SIGUSR1, processed %d events", fNumEvents);
+         Info("Run", "Stopping loop, processed %d events", fNumEvents);
          break;
       }
 
@@ -1371,6 +1453,12 @@ Int_t AliMDC::Run()
       // If there is less data for this event than the next sub-event
       // header, something is wrong. Skip to next event...
       if (toRead < header.HeaderSize()) {
+        ALIDEBUG(1) {
+            Warning("Run",
+                   "header size (%d) exceeds number of bytes to read (%d)\n",
+                   header.HeaderSize(), toRead);
+           header.Dump();
+         }
          if ((status = DumpEvent(toRead)) != toRead) {
             if (status == 0)
                break;
@@ -1381,8 +1469,8 @@ Int_t AliMDC::Run()
       }
 
       // Loop over all sub-events... (LDCs)
+      Int_t nsub = 1;
       while (toRead > 0) {
-         Int_t nsub = 1;
 #ifdef USE_EB
          ebdata = (char *)ebvec[nsub].iov_base;
 #endif
@@ -1402,6 +1490,9 @@ Int_t AliMDC::Run()
             return 1;
          }
 
+         ALIDEBUG(3)
+            subHeader.Dump();
+
          toRead -= subHeader.HeaderSize();
 
 #ifdef USE_EB
@@ -1433,6 +1524,11 @@ Int_t AliMDC::Run()
 
          // Make sure raw data less than left over bytes for current event
          if (rawSize > toRead) {
+            ALIDEBUG(1) {
+               Warning("Run", "raw data size (%d) exceeds number of bytes "
+                      "to read (%d)\n", rawSize, toRead);
+              subHeader.Dump();
+            }
             if ((status = DumpEvent(toRead)) != toRead) {
                if (status == 0)
                   break;
@@ -1494,13 +1590,16 @@ Int_t AliMDC::Run()
       if (rawdb->FileFull()) {
 
          printf("Written raw DB at a rate of %.1f MB/s\n",
-                Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+                rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
 
-         // Write stats object to raw db, run db and MySQL
+         // Write stats object to raw db, run db, MySQL and AliEn
          stats->WriteToDB(rawdb);
          delete stats;
 
-         if (!rawdb->NextFile()) return 1;
+         if (!rawdb->NextFile()) {
+            Error("Run", "error opening next raw data file");
+            return 1;
+         }
 
          printf("Filling raw DB %s\n", rawdb->GetDBName());
          stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
@@ -1531,7 +1630,7 @@ Int_t AliMDC::Run()
    }
 
    printf("Written raw DB at a rate of %.1f MB/s\n",
-          Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+          rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
 
    // Write stats to raw db and run db and delete stats object
    stats->WriteToDB(rawdb);
@@ -1554,6 +1653,13 @@ Int_t AliMDC::Run()
    }
 #endif
 
+#ifdef USE_EB
+   // Print eor flag
+   if (eorFlag) {
+      Info("Run", "event builder reported end of run (%d)", eorFlag);
+   }
+#endif
+
    return 0;
 }