// ---------------------------------------------------------------------- // File: proc/admin/Space.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/Path.hh" #include "common/Constants.hh" #include "common/token/EosTok.hh" #include "mgm/proc/ProcInterface.hh" #include "mgm/tgc/Constants.hh" #include "mgm/http/rest-api/Constants.hh" #include "mgm/http/rest-api/manager/RestApiManager.hh" #include "mgm/tracker/ReplicationTracker.hh" #include "mgm/inspector/FileInspector.hh" #include "mgm/XrdMgmOfs.hh" #include "mgm/Egroup.hh" #include "mgm/config/IConfigEngine.hh" #include "namespace/interface/IFsView.hh" #include "namespace/interface/IContainerMDSvc.hh" #include "namespace/interface/IView.hh" EOSMGMNAMESPACE_BEGIN int ProcCommand::Space() { if (mSubCmd == "ls") { { std::string output; std::string format; std::string mListFormat; format = FsView::GetSpaceFormat(std::string(mOutFormat.c_str())); if ((mOutFormat == "l")) { mListFormat = FsView::GetFileSystemFormat(std::string(mOutFormat.c_str())); } eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); FsView::gFsView.PrintSpaces(output, format, mListFormat, mOutDepth, mSelection); stdOut += output.c_str(); } } if (mSubCmd == "tracker") { std::string output; gOFS->mReplicationTracker->Scan(2 * 86400, false, &output); stdOut += "# ------------------------------------------------------------------------------------\n"; stdOut += output.c_str(); stdOut += "# ------------------------------------------------------------------------------------\n"; retc = 0; } if (mSubCmd == "inspector") { std::string output; std::string options = (pOpaque->Get("mgm.options")) ? pOpaque->Get("mgm.options") : ""; gOFS->mFileInspector->Dump(output, options, FileInspector::LockFsView::On); stdOut += output.c_str(); retc = 0; } if (mSubCmd == "status") { bool mformat = (mOutFormat == "m"); const char* fmtstr = mformat ? "%s=%s " : "%-32s := %s\n"; std::string space = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); if (FsView::gFsView.mSpaceView.count(space)) { if (!mformat) { stdOut += "# ------------------------------------------------------------------------------------\n"; } if (!mformat) { stdOut += "# Space Variables\n"; } if (!mformat) { stdOut += "# ....................................................................................\n"; } std::vector keylist; FsView::gFsView.mSpaceView[space]->GetConfigKeys(keylist); std::sort(keylist.begin(), keylist.end()); for (size_t i = 0; i < keylist.size(); i++) { char line[32678]; if (((keylist[i] == "nominalsize") || (keylist[i] == "headroom")) && !mformat) { XrdOucString sizestring; // size printout snprintf(line, sizeof(line) - 1, fmtstr, keylist[i].c_str(), eos::common::StringConversion::GetReadableSizeString(sizestring, strtoull(FsView::gFsView.mSpaceView[space]->GetConfigMember( keylist[i]).c_str(), 0, 10), "B")); } else { snprintf(line, sizeof(line) - 1, fmtstr, keylist[i].c_str(), FsView::gFsView.mSpaceView[space]->GetConfigMember(keylist[i]).c_str()); } stdOut += line; } } else { stdErr = "error: cannot find space - no space with name="; stdErr += space.c_str(); retc = ENOENT; } } if (mSubCmd == "set") { if (pVid->uid == 0) { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; std::string status = (pOpaque->Get("mgm.space.state")) ? pOpaque->Get("mgm.space.state") : ""; if ((!spacename.length()) || (!status.length())) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); if (!FsView::gFsView.mSpaceView.count(spacename)) { stdErr = "error: no such space - define one using 'space define' or " "add a filesystem under that space!"; retc = EINVAL; } else { std::string key = "status"; { // loop over all groups std::map::const_iterator it; for (it = FsView::gFsView.mGroupView.begin(); it != FsView::gFsView.mGroupView.end(); it++) { if (!it->second->SetConfigMember(key, status)) { stdErr += "error: cannot set status in group <"; stdErr += it->first.c_str(); stdErr += ">\n"; retc = EIO; } } } { // loop over all nodes std::map::const_iterator it; for (it = FsView::gFsView.mNodeView.begin(); it != FsView::gFsView.mNodeView.end(); it++) { if (!it->second->SetConfigMember(key, status)) { stdErr += "error: cannot set status for node <"; stdErr += it->first.c_str(); stdErr += ">\n"; retc = EIO; } } } } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "node-set") { if (pVid->uid == 0) { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; std::string key = (pOpaque->Get("mgm.space.node-set.key")) ? pOpaque->Get("mgm.space.node-set.key") : ""; std::string val = (pOpaque->Get("mgm.space.node-set.val")) ? pOpaque->Get("mgm.space.node-set.val") : ""; if ((!spacename.length()) || (!key.length()) || (!val.length())) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexWriteLock lock(FsView::gFsView.ViewMutex); if (!FsView::gFsView.mSpaceView.count(spacename)) { stdErr = "error: no such space - define one using 'space define' or " "add a filesystem under that space!"; retc = EINVAL; } else { { // loop over all nodes std::map::const_iterator it; for (it = FsView::gFsView.mNodeView.begin(); it != FsView::gFsView.mNodeView.end(); it++) { XrdOucString file = val.c_str(); if (file.beginswith("file:/")) { // load the file on the MGM file.erase(0, 5); eos::common::Path iPath(file.c_str()); XrdOucString fpath = iPath.GetPath(); if (!fpath.beginswith("/var/eos/")) { stdErr = "error: cannot load requested file="; stdErr += file.c_str(); stdErr += " - only files under /var/eos/ can bo loaded\n"; retc = EINVAL; } else { std::ifstream ifs(file.c_str(), std::ios::in | std::ios::binary); if (!ifs) { stdErr = "error: cannot load requested file="; stdErr += file.c_str(); retc = EINVAL; } else { val = std::string((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); // store the value b64 encoded XrdOucString val64; eos::common::SymKey::Base64Encode((char*) val.c_str(), val.length(), val64); val = "base64:"; val += val64.c_str(); stdOut += "success: loaded contents \n"; stdOut += val.c_str(); } } } if (!retc && !it->second->SetConfigMember(key, val)) { stdErr += "error: cannot set node-set for node <"; stdErr += it->first.c_str(); stdErr += ">\n"; retc = EIO; } } } } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "node-get") { if (pVid->uid == 0) { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; std::string key = (pOpaque->Get("mgm.space.node-get.key")) ? pOpaque->Get("mgm.space.node-get.key") : ""; if ((!spacename.length()) || (!key.length())) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); if (!FsView::gFsView.mSpaceView.count(spacename)) { stdErr = "error: no such space - define one using 'space define' or " "add a filesystem under that space!"; retc = EINVAL; } else { { std::string val; bool identical = true; // loop over all nodes std::map::const_iterator it; for (it = FsView::gFsView.mNodeView.begin(); it != FsView::gFsView.mNodeView.end(); it++) { std::string new_val = it->second->GetConfigMember(key); if (val.length() && new_val != val) { identical = false; } val = new_val; stdOut += it->first.c_str(); stdOut += ":="; stdOut += new_val.c_str(); stdOut += "\n"; } if (identical) { stdOut = "*:="; stdOut += val.c_str(); stdOut += "\n"; } } } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "reset") { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; XrdOucString option = pOpaque->Get("mgm.option"); eos::common::RWMutexReadLock fsViewLock(FsView::gFsView.ViewMutex); if ((!option.length()) || (option == "drain")) { if (FsView::gFsView.mSpaceView.count(spacename)) { FsView::gFsView.mSpaceView[spacename]->ResetDraining(); stdOut = "info: reset draining in space '"; stdOut += spacename.c_str(); stdOut += "'"; } else { stdErr = "error: illegal space name"; retc = EINVAL; } } if ((!option.length()) || (option == "egroup")) { gOFS->EgroupRefresh->Reset(); stdOut += "\ninfo: clear cached EGroup information ..."; } if ((option == "nsfilesystemview")) { eos::common::RWMutexWriteLock lock(gOFS->eosViewRWMutex); gOFS->eosFsView->shrink(); stdOut += "\ninfo: resized namespace filesystem view ..."; } if ((option == "nsfilemap")) { stdOut += "\n info: ns does not support file map resizing"; } if ((option == "nsdirectorymap")) { stdOut += "\ninfo: ns does not support directory map resizing"; } if ((option == "ns")) { eos::common::RWMutexWriteLock lock(gOFS->eosViewRWMutex); gOFS->eosFsView->shrink(); stdOut += "\ninfo: ns does not support map resizing"; } if ((!option.length()) || (option == "mapping")) { eos::common::Mapping::Reset(); stdOut += "\ninfo: clear all user/group uid/gid caches ...\n"; } if (option == "scheduledrain") { gOFS->mFidTracker.Clear(TrackerType::Drain); stdOut = "info: reset drain scheduling map in space '"; stdOut += spacename.c_str(); stdOut += "'"; } if (option == "schedulebalance") { gOFS->mFidTracker.Clear(TrackerType::Balance); stdOut = "info: reset balance scheduling map in space '"; stdOut += spacename.c_str(); stdOut += "'"; } } if (mSubCmd == "define") { if (pVid->uid == 0) { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; std::string groupsize = (pOpaque->Get("mgm.space.groupsize")) ? pOpaque->Get("mgm.space.groupsize") : ""; std::string groupmod = (pOpaque->Get("mgm.space.groupmod")) ? pOpaque->Get("mgm.space.groupmod") : ""; int gsize = atoi(groupsize.c_str()); int gmod = atoi(groupmod.c_str()); char line[1024]; snprintf(line, sizeof(line) - 1, "%d", gsize); std::string sgroupsize = line; snprintf(line, sizeof(line) - 1, "%d", gmod); std::string sgroupmod = line; if ((!spacename.length()) || (!groupsize.length()) || (groupsize != sgroupsize) || (gsize < 0) || (gsize > 1024) || (groupmod != sgroupmod) || (gmod < 0) || (gmod > 1024)) { stdErr = "error: illegal parameters"; retc = EINVAL; if ((groupsize != sgroupsize) || (gsize < 0) || (gsize > 1024)) { stdErr = "error: must be a positive integer (<=1024)!"; retc = EINVAL; } if ((groupmod != sgroupmod) || (gmod < 0) || (gmod > 256)) { stdErr = "error: must be a positive integer (<=256)!"; retc = EINVAL; } } else { eos::common::RWMutexWriteLock lock(FsView::gFsView.ViewMutex); if (!FsView::gFsView.mSpaceView.count(spacename)) { stdOut = "info: creating space '"; stdOut += spacename.c_str(); stdOut += "'"; if (!FsView::gFsView.RegisterSpace(spacename.c_str())) { stdErr = "error: cannot register space <"; stdErr += spacename.c_str(); stdErr += ">"; retc = EIO; } } if (!retc) { // set this new space parameters if ((!FsView::gFsView.mSpaceView[spacename]->SetConfigMember( std::string("groupsize"), groupsize)) || (!FsView::gFsView.mSpaceView[spacename]->SetConfigMember( std::string("groupmod"), groupmod))) { retc = EIO; stdErr = "error: cannot set space config value"; } } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "config") { if (pVid->uid == 0) { std::string identifier = (pOpaque->Get("mgm.space.name")) ? pOpaque->Get("mgm.space.name") : ""; std::string key = (pOpaque->Get("mgm.space.key")) ? pOpaque->Get("mgm.space.key") : ""; std::string value = (pOpaque->Get("mgm.space.value")) ? pOpaque->Get("mgm.space.value") : ""; if ((!identifier.length()) || (!key.length()) || (!value.length())) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); FileSystem* fs = nullptr; if (FsView::gFsView.mSpaceView.count(identifier)) { if (!strcmp(mgm::rest::TAPE_REST_API_SWITCH_ON_OFF, key.c_str())) { //REST API activation if ((value != "on") && (value != "off")) { retc = EINVAL; stdErr = "error: value has to either on or off"; } else { const std::string& spaceName = identifier; if (spaceName != "default") { retc = EIO; stdErr = "error: the tape REST API can only be enabled or disabled on the default space"; } else { if (!FsView::gFsView.mSpaceView[spaceName]->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } else { auto config = gOFS->mRestApiManager->getTapeRestApiConfig(); if (value == "on") { if (!config->isActivated()) { //Stage should be deactivated by default if (!FsView::gFsView.mSpaceView[spaceName]->SetConfigMember( rest::TAPE_REST_API_STAGE_SWITCH_ON_OFF, "off")) { retc = EIO; stdErr = "error: cannot set space config value"; } else { config->setActivated(true); config->setStageEnabled(false); stdOut += "success: Tape REST API enabled"; } } else { stdOut += "The tape REST API is already enabled"; } } else { //Switch off the tape REST API //Also switch off the STAGE resource if (!FsView::gFsView.mSpaceView[spaceName]->SetConfigMember( rest::TAPE_REST_API_STAGE_SWITCH_ON_OFF, "off")) { retc = EIO; stdErr = "error: cannot set space config value"; } else { config->setActivated(false); config->setStageEnabled(false); stdOut += "success: Tape REST API disabled"; } } } } } } if (!strcmp(mgm::rest::TAPE_REST_API_STAGE_SWITCH_ON_OFF, key.c_str())) { //REST API STAGE resource activation if ((value != "on") && (value != "off")) { retc = EINVAL; stdErr = "error: value has to either on or off"; } else { const std::string& spaceName = identifier; if (spaceName != "default") { retc = EIO; stdErr = "error: the tape REST API STAGE resource can only be enabled or disabled on the default space"; } else { if (!FsView::gFsView.mSpaceView[identifier] ->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } else { if (value == "on") { gOFS->mRestApiManager->getTapeRestApiConfig()->setStageEnabled(true); stdOut += "success: Tape REST API STAGE resource enabled"; } else { gOFS->mRestApiManager->getTapeRestApiConfig()->setStageEnabled(false); stdOut += "success: Tape REST API STAGE resource disabled"; } } } } } // set a space related parameter if (!key.compare(0, 6, "space.")) { key.erase(0, 6); if (key.substr(0, 7) == "policy.") { if (value == "remove") { if (!FsView::gFsView.mSpaceView[identifier]->DeleteConfigMember(key)) { retc = ENOENT; stdErr = "error: key has not been deleted"; } else { stdOut = "success: removed space policy '"; stdOut += key.c_str(); stdOut += "'\n"; } } else { // set a space policy parameters e.g. default placement attributes if (!FsView::gFsView.mSpaceView[identifier]->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } else { stdOut = "success: configured policy in space='"; stdOut += identifier.c_str(); stdOut += "' as "; stdOut += key.c_str(); stdOut += "='"; stdOut += value.c_str(); stdOut += "'\n"; retc = 0 ; } } } else { if ((key == "nominalsize") || (key == "headroom") || (key == "graceperiod") || (key == "drainperiod") || (key == "balancer") || (key == "balancer.node.rate") || (key == "balancer.node.ntx") || (key == "drainer.node.rate") || (key == "drainer.node.ntx") || (key == "drainer.node.nfs") || (key == "drainer.retries") || (key == "drainer.fs.ntx") || (key == "converter") || (key == "tracker") || (key == "inspector") || (key == "inspector.interval") || (key == "lru") || (key == "lru.interval") || (key == "wfe") || (key == "wfe.interval") || (key == "wfe.ntx") || (key == "converter.ntx") || (key == "autorepair") || (key == "groupbalancer") || (key == "groupbalancer.ntx") || (key == "groupbalancer.threshold") || (key == "groupbalancer.min_file_size") || (key == "groupbalancer.max_file_size") || (key == "groupbalancer.engine") || (key == "groupbalancer.engine.std.threshold") || (key == "groupbalancer.engine.mm.min_threshold") || (key == "groupbalancer.engine.mm.max_threshold") || (key == "geobalancer") || (key == "geobalancer.ntx") || (key == "geobalancer.threshold") || (key == "geo.access.policy.read.exact") || (key == "geo.access.policy.write.exact") || (key == "filearchivedgc") || (key == eos::mgm::tgc::TGC_NAME_QRY_PERIOD_SECS) || (key == eos::mgm::tgc::TGC_NAME_AVAIL_BYTES) || (key == eos::mgm::tgc::TGC_NAME_FREE_BYTES_SCRIPT) || (key == eos::mgm::tgc::TGC_NAME_TOTAL_BYTES) || (key == "balancer.threshold") || (key == "token.generation") || (key == eos::common::SCAN_IO_RATE_NAME) || (key == eos::common::SCAN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_RAIN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_DISK_INTERVAL_NAME) || (key == eos::common::SCAN_NS_INTERVAL_NAME) || (key == eos::common::SCAN_NS_RATE_NAME)) { if ((key == "balancer") || (key == "converter") || (key == "tracker") || (key == "inspector") || (key == "autorepair") || (key == "lru") || (key == "groupbalancer") || (key == "geobalancer") || (key == "geo.access.policy.read.exact") || (key == "geo.access.policy.write.exact") || (key == "filearchivedgc")) { if ((value != "on") && (value != "off")) { retc = EINVAL; stdErr = "error: value has to either on or off"; } else { if (!FsView::gFsView.mSpaceView[identifier]->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } else { if (key == "balancer") { if (value == "on") { stdOut += "success: balancer is enabled!"; } else { stdOut += "success: balancer is disabled!"; } } if (key == "converter") { if (value == "on") { stdOut += "success: converter is enabled!"; } else { stdOut += "success: converter is disabled!"; } } if (key == "tracker") { if (value == "on") { gOFS->mReplicationTracker->enable(); stdOut += "success: tracker is enabled!"; } else { gOFS->mReplicationTracker->disable(); stdOut += "success: tracker is disabled!"; } } if (key == "inspector") { if (value == "on") { gOFS->mFileInspector->enable(); stdOut += "success: file inspector is enabled!"; } else { gOFS->mFileInspector->disable(); stdOut += "success: file inspector is disabled!"; } } if (key == "autorepair") { if (value == "on") { stdOut += "success: auto-repair is enabled!"; } else { stdOut += "success: auto-repair is disabled!"; } } if (key == "groupbalancer") { if (value == "on") { stdOut += "success: groupbalancer is enabled!"; } else { stdOut += "success: groupbalancer is disabled!"; } } if (key == "geobalancer") { if (value == "on") { stdOut += "success: geobalancer is enabled!"; } else { stdOut += "success: geobalancer is disabled!"; } } if (key == "geo.access.policy.read.exact") { if (value == "on") { stdOut += "success: geo access policy prefers the exact geo matching replica for reading!"; } else { stdOut += "success: geo access policy prefers with a weight the geo matching replica for reading!"; } } if (key == "geo.access.policy.write.exact") { if (value == "on") { stdOut += "success: geo access policy prefers the exact geo matching replica for placements!"; } else { stdOut += "success: geo access policy prefers with a weight the geo matching replica for placements!"; } } if (key == "scheduler.skip.overloaded") { if (value == "on") { stdOut += "success: scheduler skips overloaded eth-out nodes!"; } else { stdOut += "success: scheduler does not skip overloaded eth-out nodes!"; } } if (key == "filearchivedgc") { if (value == "on") { stdOut += "success: 'file archived' garbage collector is enabled"; } else { stdOut += "success: 'file archived' garbage collector is disabled"; } } } } } else if (key == "wfe") { if ((value != "on") && (value != "off") && (value != "paused")) { retc = EINVAL; stdErr = "error: value has to either on, paused or off"; } else { if (!FsView::gFsView.mSpaceView[identifier]->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } } } else { errno = 0; unsigned long long size = eos::common::StringConversion::GetSizeFromString( value.c_str()); if (!errno) { if ((key != "balancer.threshold") && (key != "groupbalancer.threshold") && (key != "geobalancer.threshold")) { // the threshold is allowed to be decimal! char ssize[1024]; snprintf(ssize, sizeof(ssize) - 1, "%llu", size); value = ssize; } if (!FsView::gFsView.mSpaceView[identifier]->SetConfigMember(key, value)) { retc = EIO; stdErr = "error: cannot set space config value"; } else { stdOut = "success: setting "; stdOut += key.c_str(); stdOut += "="; stdOut += value.c_str(); } if ((key == "token.generation")) { eos::common::EosTok::sTokenGeneration = strtoull(value.c_str(), 0, 0); } if ((key == "policy.recycle")) { if (value == "on") { gOFS->enforceRecycleBin = true; } else { gOFS->enforceRecycleBin = false; } } } else { retc = EINVAL; stdErr = "error: value has to be a positiv number"; } } } } } // Set a filesystem related parameter if (!key.compare(0, 3, "fs.")) { key.erase(0, 3); // we disable the autosave, do all the updates and then switch back // to autosave and evt. save all changes gOFS->ConfEngine->SetAutoSave(false); // Store these as a global parameters of the space if ((key == "headroom") || (key == "graceperiod") || (key == "drainperiod") || (key == eos::common::SCAN_IO_RATE_NAME) || (key == eos::common::SCAN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_RAIN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_DISK_INTERVAL_NAME) || (key == eos::common::SCAN_NS_INTERVAL_NAME) || (key == eos::common::SCAN_NS_RATE_NAME)) { unsigned long long size = eos::common::StringConversion::GetSizeFromString( value.c_str()); char ssize[1024]; snprintf(ssize, sizeof(ssize) - 1, "%llu", size); if ((!FsView::gFsView.mSpaceView[identifier]->SetConfigMember(key, ssize))) { stdErr += "error: failed to set space parameter <"; stdErr += key.c_str(); stdErr += ">\n"; retc = EINVAL; } } else { if (key != "configstatus") { stdErr += "error: not an allowed parameter <"; stdErr += key.c_str(); stdErr += ">\n"; retc = EINVAL; } } for (auto it = FsView::gFsView.mSpaceView[identifier]->begin(); it != FsView::gFsView.mSpaceView[identifier]->end(); ++it) { fs = FsView::gFsView.mIdView.lookupByID(*it); if (fs) { // check the allowed strings if (((key == "configstatus") && (eos::common::FileSystem::GetConfigStatusFromString(value.c_str()) != eos::common::ConfigStatus::kUnknown))) { fs->SetString(key.c_str(), value.c_str()); FsView::gFsView.StoreFsConfig(fs); } else { errno = 0; eos::common::StringConversion::GetSizeFromString(value.c_str()); if (((key == "headroom") || (key == "graceperiod") || (key == "drainperiod") || (key == eos::common::SCAN_IO_RATE_NAME) || (key == eos::common::SCAN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_RAIN_ENTRY_INTERVAL_NAME) || (key == eos::common::SCAN_DISK_INTERVAL_NAME) || (key == eos::common::SCAN_NS_INTERVAL_NAME) || (key == eos::common::SCAN_NS_RATE_NAME)) && (!errno)) { fs->SetLongLong(key.c_str(), eos::common::StringConversion::GetSizeFromString(value.c_str())); FsView::gFsView.StoreFsConfig(fs); } else { stdErr += "error: not an allowed parameter <"; stdErr += key.c_str(); stdErr += ">\n"; retc = EINVAL; break; } } } else { stdErr += "error: cannot identify the filesystem by <"; stdErr += identifier.c_str(); stdErr += ">\n"; retc = EINVAL; } } gOFS->ConfEngine->SetAutoSave(true); gOFS->ConfEngine->AutoSave(); } } else { retc = EINVAL; stdErr = "error: cannot find space <"; stdErr += identifier.c_str(); stdErr += ">"; } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "quota") { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; std::string onoff = (pOpaque->Get("mgm.space.quota")) ? pOpaque->Get("mgm.space.quota") : ""; std::string key = "quota"; if (pVid->uid == 0) { if ((!spacename.length()) || (!onoff.length()) || ((onoff != "on") && (onoff != "off"))) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex); if (FsView::gFsView.mSpaceView.count(spacename)) { if (!FsView::gFsView.mSpaceView[spacename]->SetConfigMember(key, onoff)) { retc = EIO; stdErr = "error: cannot set space config value"; } } else { retc = EINVAL; stdErr = "error: no such space defined"; } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } if (mSubCmd == "rm") { if (pVid->uid == 0) { std::string spacename = (pOpaque->Get("mgm.space")) ? pOpaque->Get("mgm.space") : ""; if ((!spacename.length())) { stdErr = "error: illegal parameters"; retc = EINVAL; } else { eos::common::RWMutexWriteLock lock(FsView::gFsView.ViewMutex); if (!FsView::gFsView.mSpaceView.count(spacename)) { stdErr = "error: no such space '"; stdErr += spacename.c_str(); stdErr += "'"; retc = ENOENT; } else { for (auto it = FsView::gFsView.mSpaceView[spacename]->begin(); it != FsView::gFsView.mSpaceView[spacename]->end(); it++) { FileSystem* fs = FsView::gFsView.mIdView.lookupByID(*it); if (fs) { // check that filesystems are empty if ((fs->GetConfigStatus(false) != eos::common::ConfigStatus::kEmpty)) { stdErr = "error: unable to remove space '"; stdErr += spacename.c_str(); stdErr += "' - filesystems are not all in empty state - try to drain them or: space config configstatus=empty\n"; retc = EBUSY; return SFS_OK; } } } common::SharedHashLocator spaceLocator = common::SharedHashLocator::makeForSpace(spacename); if (!mq::SharedHashWrapper::deleteHash(gOFS->mMessagingRealm.get(), spaceLocator)) { stdErr = "error: unable to remove config of space '"; stdErr += spacename.c_str(); stdErr += "'"; retc = EIO; } else { if (FsView::gFsView.UnRegisterSpace(spacename.c_str())) { stdOut = "success: removed space '"; stdOut += spacename.c_str(); stdOut += "'"; } else { stdErr = "error: unable to unregister space '"; stdErr += spacename.c_str(); stdErr += "'"; } } } } } else { retc = EPERM; stdErr = "error: you have to take role 'root' to execute this command"; } } return SFS_OK; } EOSMGMNAMESPACE_END