//------------------------------------------------------------------------------ //! @file FmdHandler.hh //! @author Abhishek Lekshmanan - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2021 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #pragma once #include "fst/Namespace.hh" #include "common/Fmd.hh" #include "common/FileId.hh" #include "common/LayoutId.hh" #include //! Forward declaration namespace eos { class QdbContactDetails; } namespace qclient { class QClient; } EOSFSTNAMESPACE_BEGIN class FmdHandler: public eos::common::LogId { public: //---------------------------------------------------------------------------- //! Reset the disk info related to the encoded Fmd object //! //! @param input a string that can serialize to FmdProtobuf object //! //! @return string value after resetting info or an empty string if //! serialization fails //---------------------------------------------------------------------------- static std::string ResetFmdDiskInfo(const std::string& input); //---------------------------------------------------------------------------- //! Reset the mgm info related to the encoded Fmd object //! //! @param input a string that can serialize to FmdProtobuf object //! //! @return string value after resetting info or an empty string if //! serialization fails //---------------------------------------------------------------------------- static std::string ResetFmdMgmInfo(const std::string& input); //---------------------------------------------------------------------------- //! Move given file to orphans directory and also set its extended attribute //! to reflect the original path to the file. //! //! @param fpath file to move //---------------------------------------------------------------------------- static void MoveToOrphans(const std::string& fpath); //---------------------------------------------------------------------------- //! Constructor //---------------------------------------------------------------------------- FmdHandler() = default; //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~FmdHandler() = default; //---------------------------------------------------------------------------- //! Check if entry has a file checksum error //! //! @param lpath file local path //! @param fsid file system identifier //! //! @return true if file has checksum error, otherwise false //---------------------------------------------------------------------------- virtual bool FileHasXsError(const std::string& lpath, eos::common::FileSystem::fsid_t fsid); // Meta data handling functions //---------------------------------------------------------------------------- //! Return/create an Fmd struct for the given file/filesystem from the local //! database //! //! @param fid file id //! @param fsid filesystem id //! @param force_retrieve get object even in the presence of inconsistencies //! @param do_create if true create a non-existing Fmd if needed //! @param uid user id of the caller //! @param gid group id of the caller //! @param layoutid layout id used to store during creation //! //! @return pointer to Fmd struct if successful, otherwise nullptr //---------------------------------------------------------------------------- virtual std::unique_ptr LocalGetFmd(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, bool force_retrieve = false, bool do_create = false, uid_t uid = 0, gid_t gid = 0, eos::common::LayoutId::layoutid_t layoutid = 0) = 0; //---------------------------------------------------------------------------- //! Delete a record associated with fid and filesystem fsid //! //! @param fid file id //! @param fsid filesystem id //---------------------------------------------------------------------------- virtual void LocalDeleteFmd(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, bool drop_file = false) = 0; //---------------------------------------------------------------------------- //! Commit modified Fmd record to the local database //! //! @param fmd pointer to Fmd //! //! @return true if record was committed, otherwise false //---------------------------------------------------------------------------- virtual bool Commit(eos::common::FmdHelper* fmd, bool lockit = true, std::string* path = nullptr) = 0; //---------------------------------------------------------------------------- //! Low level Fmd retrieve method //! //! @param fid file identifier //! @param fsid file system identifier //! @param path optional file path //! //! @return true if found and the corresponding FmdHelper object otherwise //! false //---------------------------------------------------------------------------- virtual std::pair LocalRetrieveFmd(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, const std::string& path = "") = 0; //---------------------------------------------------------------------------- //! Update file metadata object with new fid information //! //! @param path full path to file //! @param fid new file identifier //! //! @return true if succesful, otherwise false //---------------------------------------------------------------------------- bool UpdateFmd(const std::string& path, eos::common::FileId::fileid_t fid); //---------------------------------------------------------------------------- //! Update local fmd with info from the disk i.e. physical file extended //! attributes //! //! @param fsid file system id //! @param fid file id to update //! @param disk_size size of the file on disk //! @param disk_xs checksum of the file on disk //! @param check_ts_sec time of the last check of that file //! @param filexs_err indicator for file checksum error //! @param blockxs_err inidicator for block checksum error //! @param layout_err indication for layout error //! //! @return true if record has been committed //---------------------------------------------------------------------------- bool UpdateWithDiskInfo(eos::common::FileSystem::fsid_t fsid, eos::common::FileId::fileid_t fid, unsigned long long disk_size, const std::string& disk_xs, unsigned long check_ts_sec, bool filexs_err, bool blockxs_err, bool layout_err); //---------------------------------------------------------------------------- //! Update local fmd with info from the MGM //! //! @param fsid file system id //! @param fid file id to update //! @param cid container id //! @param lid layout id //! @param mgmsize size of the file in the mgm namespace //! @param mgmchecksum checksum of the file in the mgm namespace //! //! @return true if record has been committed //---------------------------------------------------------------------------- bool UpdateWithMgmInfo(eos::common::FileSystem::fsid_t fsid, eos::common::FileId::fileid_t fid, eos::common::FileId::fileid_t cid, eos::common::LayoutId::layoutid_t lid, unsigned long long mgmsize, std::string mgmchecksum, uid_t uid, gid_t gid, unsigned long long ctime, unsigned long long ctime_ns, unsigned long long mtime, unsigned long long mtime_ns, int layouterror, std::string locations); //---------------------------------------------------------------------------- //! Update local fmd with info from the stripe check //! //! @param fid file identifier //! @param fsid file system id //! @param invalid_stripes list of fsid with invalid stripes //! //---------------------------------------------------------------------------- void UpdateWithStripeCheckInfo( eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, const std::set& invalid_stripes); //---------------------------------------------------------------------------- //! Update local fmd with info from the scanner //! //! @param fid file identifier //! @param fsid file system id //! @param fpath local file path //! @param scan_sz size of the file computed by the scanner //! @param scan_xs_hex hex checksum of the file computed by the scanner //! @param qcl QClient used to communicate to QDB backend //! //! @note: the qclient should favor followers as we're doing only read //! operations and this should reduce the load on the master QDB //---------------------------------------------------------------------------- void UpdateWithScanInfo(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, const std::string& fpath, uint64_t scan_sz, const std::string& scan_xs_hex, std::shared_ptr qcl); //---------------------------------------------------------------------------- //! Clear errors on local fmd //! //! @param fid file identifier //! @param fsid file system id //! //---------------------------------------------------------------------------- void ClearErrors(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid); //---------------------------------------------------------------------------- //! Resync a single entry from disk //! //! @param fstpath file system location //! @param fsid filesystem id //! @param flaglayouterror indicates a layout error //! @param scan_sz size of file computed by the scanner //! @param scan_xs_hex hex checksum of the file computed by the scanner //! //! @return 0 if successful, otherwise errno //---------------------------------------------------------------------------- int ResyncDisk(const char* fstpath, eos::common::FileSystem::fsid_t fsid, bool flaglayouterror, uint64_t scan_sz = 0ull, const std::string& scan_xs_hex = ""); //---------------------------------------------------------------------------- //! Resync files under path into local database //! //! @param path path to scan //! @param fsid file system id //! @param flaglayouterror flag to indicate a layout error //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool ResyncAllDisk(const char* path, eos::common::FileSystem::fsid_t fsid, bool flaglayouterror); //---------------------------------------------------------------------------- //! Resync file meta data from MGM into local database //! //! @param fsid filesystem id //! @param fid file id //! @param manager manager hostname //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool ResyncMgm(eos::common::FileSystem::fsid_t fsid, eos::common::FileId::fileid_t fid, const char* manager); //---------------------------------------------------------------------------- //! Resync all meta data from MGM into local database //! //! @param fsid filesystem id //! param manager manger hostname //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool ResyncAllMgm(eos::common::FileSystem::fsid_t fsid, const char* manager); //------------------------------------------------------------------------------ //! Resync file meta data from QuarkDB into local database //! //! @param fid file identifier //! @param fsid file system identifier //! @param fpath local file path //! @param qcl QClient object used to connect to QuarkDB (this should have a //! preference to connect to followers as it's doing only read ops.) //! //! @return 0 if successful, otherwise errno //------------------------------------------------------------------------------ int ResyncFileFromQdb(eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, const std::string& fpath, std::shared_ptr qcl); //---------------------------------------------------------------------------- //! Resync all meta data from QuarkdDB //! //! @param contact_details QDB contact details //! @param fsid filesystem id //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool ResyncAllFromQdb(const QdbContactDetails& contact_details, eos::common::FileSystem::fsid_t fsid); private: //---------------------------------------------------------------------------- // Virtual private methods are overrideable in derived classes, this allows // for the interface to remain the same while the specific implementation is // done in the derived class //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //! Attach Fmd metadata info to the current file identifier //! //! @param fmd file metadata info protobuf object //! @param fid file identifier //! @param fsid file system identifier //! @param path local file absolute path //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- virtual bool LocalPutFmd(const eos::common::FmdHelper& fmd, eos::common::FileId::fileid_t fid, eos::common::FileSystem::fsid_t fsid, const std::string& path = "") = 0; //---------------------------------------------------------------------------- //! //---------------------------------------------------------------------------- virtual bool ResetDiskInformation(eos::common::FileSystem::fsid_t fsid) = 0; //---------------------------------------------------------------------------- //! //---------------------------------------------------------------------------- virtual bool ResetMgmInformation(eos::common::FileSystem::fsid_t fsid) = 0; // TODO: Technically we could hold move the mIsSyncing map & mutex to this class. Do // this if AttrHandler also needs a syncing lock vs noop virtual void SetSyncStatus(eos::common::FileSystem::fsid_t fsid, bool is_syncing) = 0; }; EOSFSTNAMESPACE_END