// -----------------------.qc----------------------------------------------- // File: proc/admin/Fusex.cc // Author: Andreas-Joachim Peters - CERN // ---------------------------------------------------------------------- /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2017 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 "mgm/proc/ProcInterface.hh" #include "mgm/XrdMgmOfs.hh" #include "mgm/ZMQ.hh" EOSMGMNAMESPACE_BEGIN int ProcCommand::Fusex() { if (pVid->uid == 0) { if (mSubCmd == "ls") { std::string option = pOpaque->Get("mgm.option") ? pOpaque->Get("mgm.option") : ""; std::string out; gOFS->zMQ->gFuseServer.Print(out, option); stdOut += out.c_str(); retc = 0; } else if (mSubCmd == "conf") { std::string hb = pOpaque->Get("mgm.fusex.hb") ? pOpaque->Get("mgm.fusex.hb") : ""; std::string qc = pOpaque->Get("mgm.fusex.qc") ? pOpaque->Get("mgm.fusex.qc") : ""; std::string bc = pOpaque->Get("mgm.fusex.bc.max") ? pOpaque->Get("mgm.fusex.bc.max") : ""; std::string bc_match = pOpaque->Get("mgm.fusex.bc.match") ? pOpaque->Get("mgm.fusex.bc.match") : ""; int i_hb = atoi(hb.c_str()); int i_qc = atoi(qc.c_str()); int i_bc = atoi(bc.c_str()); if (bc.length()) { gOFS->zMQ->gFuseServer.Client().SetBroadCastMaxAudience(i_bc); stdOut += "info: configure FUSEX broadcast max. client audience to "; stdOut += bc.c_str(); stdOut += " listeners"; stdOut += "\n"; FsView::gFsView.mSpaceView["default"]->SetConfigMember("fusex.bca", bc.c_str()); retc = 0; } if (bc_match.length()) { gOFS->zMQ->gFuseServer.Client().SetBroadCastAudienceSuppressMatch(bc_match); stdOut += "info: configure FUSEX broadcast audience to suppress match to "; stdOut += bc_match.c_str(); stdOut += "\n"; FsView::gFsView.mSpaceView["default"]->SetConfigMember("fusex.bca_match", bc_match.c_str()); retc = 0; } if (!i_bc) { bc = std::to_string(gOFS->zMQ->gFuseServer.Client().BroadCastMaxAudience()); stdOut += "info: configured FUSEX broadcast max. client audience "; stdOut += bc.c_str(); stdOut += " listeners"; stdOut += "\n"; retc = 0; } if (!bc_match.length()) { bc_match = gOFS->zMQ->gFuseServer.Client().BroadCastAudienceSuppressMatch(); stdOut += "info: configured FUSEX broadcast audience to suppress match is '"; stdOut += bc_match.c_str(); stdOut += "'"; stdOut += "\n"; retc = 0; } if (!i_hb) { i_hb = gOFS->zMQ->gFuseServer.Client().HeartbeatInterval(); char shb[16]; snprintf(shb, sizeof(shb), "%d", i_hb); hb = shb; } if (!i_qc) { i_qc = gOFS->zMQ->gFuseServer.Client().QuotaCheckInterval(); char sqc[16]; snprintf(sqc, sizeof(sqc), "%d", i_qc); qc = sqc; } if ((i_hb > 0) && (i_hb <= 15)) { gOFS->zMQ->gFuseServer.Client().SetHeartbeatInterval(i_hb); stdOut += "info: configured FUSEX heartbeat interval is "; stdOut += hb.c_str(); stdOut += " seconds\n"; FsView::gFsView.mSpaceView["default"]->SetConfigMember("fusex.hbi", hb.c_str()); retc = 0; } else { stdErr += "error: hearbeat interval must be [1..15] seconds\n"; retc = EINVAL; } if ((i_qc > 0) && (i_qc <= 60)) { gOFS->zMQ->gFuseServer.Client().SetQuotaCheckInterval(i_qc); stdOut += "info: configured FUSEX quota check interval is "; stdOut += qc.c_str(); stdOut += " seconds\n"; FsView::gFsView.mSpaceView["default"]->SetConfigMember("fusex.qti", qc.c_str()); retc = 0; } else { if (i_qc < 0) { stdErr += "error: quota check interval must be [1..60] seconds\n"; retc = EINVAL; } } } else if (mSubCmd == "evict") { std::string s_reason; std::string uuid = pOpaque->Get("mgm.fusex.uuid") ? pOpaque->Get("mgm.fusex.uuid") : ""; XrdOucString reason64 = pOpaque->Get("mgm.fusex.reason") ? pOpaque->Get("mgm.fusex.reason") : "evicted via EOS shell"; XrdOucString reason; eos::common::SymKey::DeBase64(reason64, reason); s_reason = reason.c_str(); std::vector evicted_out; if (gOFS->zMQ->gFuseServer.Client().Evict(uuid, s_reason , &evicted_out ) == ENOENT) { stdErr += "error: no such client '"; stdErr += uuid.c_str(); retc = ENOENT; stdErr += "'"; } else { if (evicted_out.size() == 1) { stdOut += "info: evicted client '"; stdOut += evicted_out[0].c_str(); stdOut += "'"; } else { if (evicted_out.size() == 0) { stdOut += "info: no client has been evicted!"; } else { stdOut += "info: evicted clients:\n"; for (auto it : evicted_out) { stdOut += it.c_str(); stdOut += "\n"; } } } retc = 0; } } else if (mSubCmd == "droplocks") { std::string sinode = pOpaque->Get("mgm.inode") ? pOpaque->Get("mgm.inode") : ""; std::string spid = pOpaque->Get("mgm.fusex.pid") ? pOpaque->Get("mgm.fusex.pid") : ""; uint64_t inode = strtoull(sinode.c_str(), 0, 16); uint64_t pid = strtoull(spid.c_str(), 0, 10); if (gOFS->zMQ->gFuseServer.Locks().dropLocks(inode, pid)) { stdErr += "error: no such lock for inode '"; stdErr += sinode.c_str(); stdErr += "'"; stdErr += " and process '"; stdErr += spid.c_str(); stdErr += "'"; retc = ENOENT; } else { retc = 0; stdOut += "success: removed locks for inode '"; stdOut += sinode.c_str(); stdOut += "'"; stdOut += " and process '"; stdOut += spid.c_str(); stdOut += "'"; } } else if (mSubCmd == "caps") { std::string option = pOpaque->Get("mgm.option") ? pOpaque->Get("mgm.option") : "t"; std::string filter = pOpaque->Get("mgm.filter") ? pOpaque->Get("mgm.filter") : ""; filter = eos::common::StringConversion::curl_unescaped(filter.c_str()); stdOut += gOFS->zMQ->gFuseServer.Cap().Print(option, filter).c_str(); retc = 0; } else { stdErr += "error: subcmd not implemented"; retc = EINVAL; } } else { stdErr += "error: you have to be root to list VSTs"; retc = EPERM; } return SFS_OK; } EOSMGMNAMESPACE_END