// ---------------------------------------------------------------------- // File: Remover.cc // Author: Andreas-Joachim Peters - CERN // ---------------------------------------------------------------------- /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2011 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 .* ************************************************************************/ #include "common/SymKeys.hh" #include "fst/storage/Storage.hh" #include "fst/XrdFstOfs.hh" #include "fst/Deletion.hh" #include "fst/Config.hh" EOSFSTNAMESPACE_BEGIN //------------------------------------------------------------------------------ // Thead requesting deletions from the MGM and unlinking the physical files //------------------------------------------------------------------------------ void Storage::Remover() { using namespace std::chrono; static auto last_request_ts = system_clock::now(); static std::chrono::seconds request_interval(300); // Used as barrier for FSTs proper config (void)gConfig.getFstNodeConfigQueue("Remover").c_str(); (void)gConfig.WaitManager(); uint64_t num_deleted = 0ull; const char* ptr = getenv("EOS_FST_DELETE_QUERY_INTERVAL"); if (ptr) { try { request_interval = chrono::seconds(std::stoi(std::string(ptr))); eos_static_info("msg=\"update deletions request interval\" val=%llu", request_interval.count()); } catch (...) {} } // Check for deletions when starting (void) gOFS.Query2Delete(); // Thread that unlinks stored files while (true) { num_deleted = 0ull; std::unique_ptr to_del; while ((to_del = GetDeletion())) { for (unsigned int i = 0; i < to_del->mFidVect.size(); ++i) { eos_static_debug("msg=\"delete file\" fxid=%08llx fsid=%u", to_del->mFidVect[i], to_del->mFsid); ++num_deleted; const std::string hex_fid = eos::common::FileId::Fid2Hex(to_del->mFidVect[i]); XrdOucErrInfo error; XrdOucString capOpaqueString = "/?mgm.pcmd=drop"; XrdOucString OpaqueString = ""; OpaqueString += "&mgm.fsid="; OpaqueString += (int) to_del->mFsid; OpaqueString += "&mgm.fid="; OpaqueString += hex_fid.c_str(); OpaqueString += "&mgm.localprefix="; OpaqueString += to_del->mLocalPrefix; XrdOucEnv Opaque(OpaqueString.c_str()); capOpaqueString += OpaqueString; // Delete local file std::string deletionreport; std::string deletionreport64; if ((gOFS._rem("/DELETION", error, (const XrdSecEntity*) 0, &Opaque, 0, 0, 0, true, &deletionreport) != SFS_OK)) { eos_static_warning("msg=\"unable to remove local file\" fxid=%s " "fsid=%lu localprefix=%s", hex_fid.c_str(), to_del->mFsid, to_del->mLocalPrefix.c_str()); } else { // Encode the deletion report only if deletion is successful eos::common::SymKey::ZBase64(deletionreport, deletionreport64); capOpaqueString += "&mgm.report="; capOpaqueString += deletionreport64.c_str(); } // Update the manager if (gOFS.CallManager(&error, 0, 0 , capOpaqueString)) { eos_static_err("msg=\"unable to drop file\" fxid=\"%s\" fsid=\"%u\"", hex_fid.c_str(), to_del->mFsid); } } } auto now_ts = system_clock::now(); bool request_del = (duration_cast(now_ts - last_request_ts) > request_interval); // Ask for more deletions if deleted something in last round or request // interval expired if (num_deleted || request_del) { eos_static_debug("%s", "msg=\"query manager for deletions\""); last_request_ts = now_ts; (void) gOFS.Query2Delete(); } else { std::this_thread::sleep_for(std::chrono::seconds(10)); } } } EOSFSTNAMESPACE_END