Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-10-01 22:41:10

0001 #include "Utilities/StorageFactory/interface/StorageMaker.h"
0002 #include "Utilities/StorageFactory/interface/StorageMakerFactory.h"
0003 #include "Utilities/StorageFactory/interface/StorageFactory.h"
0004 #include "Utilities/DCacheAdaptor/interface/DCacheFile.h"
0005 #include "FWCore/Utilities/interface/Exception.h"
0006 #include <unistd.h>
0007 #include <dcap.h>
0008 
0009 namespace edm::storage {
0010   class DCacheStorageMaker : public StorageMaker {
0011     /** Return appropriate path for use with dcap library.  If the path is in the
0012       URL form ([gsi]dcap://host:port/path), return the full URL as it is.  If
0013       the path is /pnfs form (dcap:/pnfs/path), return only the path part, unless
0014       the protocol is 'gsidcap', in which case return the whole thing.  */
0015     static std::string normalise(const std::string &proto, const std::string &path) {
0016       size_t p = path.find("/pnfs");
0017       if (p < 3)
0018         return (proto == "gsidcap") ? proto + ':' + path.substr(p) : path.substr(p);
0019 
0020       // remove multiple "/"
0021       p = path.find_first_not_of('/');
0022 
0023       // it's url, return the full thing
0024       return proto + "://" + path.substr(p);
0025     }
0026 
0027   public:
0028     /** Open a storage object for the given URL (protocol + path), using the
0029       @a mode bits.  No temporary files are downloaded.  */
0030     std::unique_ptr<Storage> open(const std::string &proto,
0031                                   const std::string &path,
0032                                   int mode,
0033                                   AuxSettings const &aux) const override {
0034       setTimeout(aux.timeout);
0035       const StorageFactory *f = StorageFactory::get();
0036       StorageFactory::ReadHint readHint = f->readHint();
0037       StorageFactory::CacheHint cacheHint = f->cacheHint();
0038 
0039       if (readHint != StorageFactory::READ_HINT_UNBUFFERED || cacheHint == StorageFactory::CACHE_HINT_STORAGE)
0040         mode &= ~IOFlags::OpenUnbuffered;
0041       else
0042         mode |= IOFlags::OpenUnbuffered;
0043 
0044       auto file = std::make_unique<DCacheFile>(normalise(proto, path), mode);
0045       return f->wrapNonLocalFile(std::move(file), proto, std::string(), mode);
0046     }
0047 
0048     void stagein(const std::string &proto, const std::string &path, const AuxSettings &aux) const override {
0049       setTimeout(aux.timeout);
0050       std::string npath = normalise(proto, path);
0051       if (dc_stage(npath.c_str(), 0, nullptr) != 0) {
0052         cms::Exception ex("FileStageInError");
0053         ex << "Cannot stage in file '" << npath << "', error was: " << dc_strerror(dc_errno)
0054            << " (dc_errno=" << dc_errno << ")";
0055         ex.addContext("Calling DCacheStorageMaker::stagein()");
0056         throw ex;
0057       }
0058     }
0059 
0060     bool check(const std::string &proto,
0061                const std::string &path,
0062                const AuxSettings &aux,
0063                IOOffset *size = nullptr) const override {
0064       setTimeout(aux.timeout);
0065       std::string testpath(normalise(proto, path));
0066       if (dc_access(testpath.c_str(), R_OK) != 0)
0067         return false;
0068 
0069       if (size) {
0070         struct stat64 buf;
0071         if (dc_stat64(testpath.c_str(), &buf) != 0)
0072           return false;
0073 
0074         *size = buf.st_size;
0075       }
0076 
0077       return true;
0078     }
0079 
0080   private:
0081     void setTimeout(unsigned int timeout) const {
0082       if (timeout != 0)
0083         dc_setOpenTimeout(timeout);
0084     }
0085   };
0086 }  // namespace edm::storage
0087 
0088 using namespace edm::storage;
0089 DEFINE_EDM_PLUGIN(StorageMakerFactory, DCacheStorageMaker, "dcache");
0090 DEFINE_EDM_PLUGIN(StorageMakerFactory, DCacheStorageMaker, "dcap");
0091 DEFINE_EDM_PLUGIN(StorageMakerFactory, DCacheStorageMaker, "gsidcap");