//------------------------------------------------------------------------------
// File: proc/admin/Group.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 "mgm/proc/ProcInterface.hh"
#include "mgm/XrdMgmOfs.hh"
#include "mgm/FsView.hh"
EOSMGMNAMESPACE_BEGIN
int
ProcCommand::Group()
{
if (mSubCmd == "ls") {
{
std::string output;
std::string format;
std::string mListFormat;
std::string fqdn;
format = FsView::GetGroupFormat(std::string(mOutFormat.c_str()));
if ((mOutFormat == "l")) {
mListFormat = FsView::GetFileSystemFormat(std::string(mOutFormat.c_str()));
}
if ((mOutFormat == "IO")) {
mListFormat = FsView::GetFileSystemFormat(std::string("io"));
mOutFormat = "io";
}
if (pOpaque->Get("mgm.outhost")) {
fqdn = pOpaque->Get("mgm.outhost");
}
if (fqdn != "brief") {
if (format.find("S") != std::string::npos) {
format.replace(format.find("S"), 1, "s");
}
if (mListFormat.find("S") != std::string::npos) {
mListFormat.replace(mListFormat.find("S"), 1, "s");
}
}
eos::common::RWMutexReadLock lock(FsView::gFsView.ViewMutex);
FsView::gFsView.PrintGroups(output, format, mListFormat, mOutDepth ,
mSelection);
stdOut += output.c_str();
}
}
if (mSubCmd == "set") {
if (pVid->uid == 0) {
std::string groupname = (pOpaque->Get("mgm.group")) ? pOpaque->Get("mgm.group")
: "";
std::string status = (pOpaque->Get("mgm.group.state")) ?
pOpaque->Get("mgm.group.state") : "";
std::string key = "status";
if ((!groupname.length()) || (!status.length())) {
stdErr = "error: illegal parameters";
retc = EINVAL;
} else {
eos::common::RWMutexWriteLock lock(FsView::gFsView.ViewMutex);
if (!FsView::gFsView.mGroupView.count(groupname)) {
stdOut = "info: creating group '";
stdOut += groupname.c_str();
stdOut += "'";
if (!FsView::gFsView.RegisterGroup(groupname.c_str())) {
std::string groupconfigname = common::SharedHashLocator::makeForGroup(
groupname).getConfigQueue();
retc = EIO;
stdErr = "error: cannot register group <";
stdErr += groupname.c_str();
stdErr += ">";
}
}
if (!retc) {
// Set this new group to offline
if (!FsView::gFsView.mGroupView[groupname]->SetConfigMember
(key, status)) {
stdErr = "error: cannot set config status";
retc = EIO;
}
if (status == "on") {
// Recompute the drain status in this group
bool setactive = false;
if (FsView::gFsView.mGroupView.count(groupname)) {
for (auto git = FsView::gFsView.mGroupView[groupname]->begin();
git != FsView::gFsView.mGroupView[groupname]->end(); git++) {
FileSystem* fs = FsView::gFsView.mIdView.lookupByID(*git);
if (fs) {
common::DrainStatus drainstatus =
(eos::common::FileSystem::GetDrainStatusFromString(
fs->GetString("local.drain").c_str()));
if ((drainstatus == eos::common::DrainStatus::kDraining) ||
(drainstatus == eos::common::DrainStatus::kDrainStalling)) {
// If any group filesystem is draining, all the others have
// to enable the pull for draining!
setactive = true;
}
}
}
for (auto git = FsView::gFsView.mGroupView[groupname]->begin();
git != FsView::gFsView.mGroupView[groupname]->end(); git++) {
FileSystem* fs = FsView::gFsView.mIdView.lookupByID(*git);
if (fs) {
if (setactive) {
if (fs->GetString("stat.drainer") != "on") {
fs->SetString("stat.drainer", "on");
}
} else {
if (fs->GetString("stat.drainer") != "off") {
fs->SetString("stat.drainer", "off");
}
}
}
}
}
}
if (status == "off") {
// Disable all draining in this group
if (FsView::gFsView.mGroupView.count(groupname)) {
for (auto git = FsView::gFsView.mGroupView[groupname]->begin();
git != FsView::gFsView.mGroupView[groupname]->end(); git++) {
FileSystem* fs = FsView::gFsView.mIdView.lookupByID(*git);
if (fs) {
fs->SetString("stat.drainer", "off");
}
}
}
}
}
}
} else {
retc = EPERM;
stdErr = "error: you have to take role 'root' to execute this command";
}
}
if (mSubCmd == "rm") {
if (pVid->uid == 0) {
std::string groupname = (pOpaque->Get("mgm.group")) ? pOpaque->Get("mgm.group")
: "";
if ((!groupname.length())) {
stdErr = "error: illegal parameters";
retc = EINVAL;
} else {
eos::common::RWMutexWriteLock lock(FsView::gFsView.ViewMutex);
if (!FsView::gFsView.mGroupView.count(groupname)) {
stdErr = "error: no such group '";
stdErr += groupname.c_str();
stdErr += "'";
retc = ENOENT;
} else {
for (auto it = FsView::gFsView.mGroupView[groupname]->begin();
it != FsView::gFsView.mGroupView[groupname]->end(); it++) {
FileSystem* fs = FsView::gFsView.mIdView.lookupByID(*it);
if (fs) {
// check that all filesystems are empty
if ((fs->GetConfigStatus(false) != eos::common::ConfigStatus::kEmpty)) {
stdErr = "error: unable to remove group '";
stdErr += groupname.c_str();
stdErr += "' - filesystems are not all in empty state - try list the group and drain them or set: fs config configstatus=empty\n";
retc = EBUSY;
return SFS_OK;
}
}
}
common::SharedHashLocator groupLocator =
common::SharedHashLocator::makeForGroup(groupname);
if (!mq::SharedHashWrapper::deleteHash(gOFS->mMessagingRealm.get(), groupLocator)) {
stdErr = "error: unable to remove config of group '";
stdErr += groupname.c_str();
stdErr += "'";
retc = EIO;
} else {
if (FsView::gFsView.UnRegisterGroup(groupname.c_str())) {
stdOut = "success: removed group '";
stdOut += groupname.c_str();
stdOut += "'";
} else {
stdErr = "error: unable to unregister group '";
stdErr += groupname.c_str();
stdErr += "'";
}
}
}
}
} else {
retc = EPERM;
stdErr = "error: you have to take role 'root' to execute this command";
}
}
return SFS_OK;
}
EOSMGMNAMESPACE_END