Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added XrdCmsRedirLocal as ofs.cmslib plugin. Allows redirector to red… #1022

Merged
merged 5 commits into from
Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
162 changes: 162 additions & 0 deletions src/XrdCms/XrdCmsRedirLocal.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
//------------------------------------------------------------------------------
// Copyright (c) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
// Author: Paul-Niklas Kramp <p.n.kramp@gsi.de>
// Jan Knedlik <j.knedlik@gsi.de>
//------------------------------------------------------------------------------
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD 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 Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#include <XrdCms/XrdCmsRedirLocal.hh>

//------------------------------------------------------------------------------
//! Necessary implementation for XRootD to get the Plug-in
//------------------------------------------------------------------------------
extern "C" XrdCmsClient *XrdCmsGetClient(XrdSysLogger *Logger, int opMode,
int myPort, XrdOss *theSS) {
XrdCmsRedirLocal *plugin = new XrdCmsRedirLocal(Logger, opMode, myPort, theSS);
return plugin;
}

//------------------------------------------------------------------------------
//! Constructor
//------------------------------------------------------------------------------
XrdCmsRedirLocal::XrdCmsRedirLocal(XrdSysLogger *Logger, int opMode, int myPort,
XrdOss *theSS) : XrdCmsClient(amLocal) {
nativeCmsFinder = new XrdCmsFinderRMT(Logger, opMode, myPort);
this->theSS = theSS;
readOnlyredirect = false;
}
//------------------------------------------------------------------------------
//! Destructor
//------------------------------------------------------------------------------
XrdCmsRedirLocal::~XrdCmsRedirLocal() { delete nativeCmsFinder; }

//------------------------------------------------------------------------------
//! Configure the nativeCmsFinder
//------------------------------------------------------------------------------
int XrdCmsRedirLocal::Configure(const char *cfn, char *Parms, XrdOucEnv *EnvInfo) {
loadConfig(cfn);
if (nativeCmsFinder)
return nativeCmsFinder->Configure(cfn, Parms, EnvInfo);
return 0;
}

void XrdCmsRedirLocal::loadConfig(const char *filename) {
XrdOucStream Config;
int cfgFD;
char *word;

if ((cfgFD = open(filename, O_RDONLY, 0)) < 0) {
return;
}
Config.Attach(cfgFD);
while ((word = Config.GetFirstWord(true))) { //get word in lower case
// search for readonlyredirect,
// which only allows read calls to be redirected to local
if (strcmp(word, "XrdCmsRedirLocal.readonlyredirect") == 0){
// get next word in lower case
std::string readWord = std::string(Config.GetWord(true));//to lower case
if(readWord.find("true") != string::npos){
readOnlyredirect = true;
}
else {
readOnlyredirect = false;
}
}
}
Config.Close();
}

//------------------------------------------------------------------------------
//! Preconditions:
//! Client Protocol Version is >= 784
//! Flag is one of: SFS_O_RDONLY, SFS_O_RDWR, SFS_O_WRONLY, SFS_O_CREAT, SFS_O_TRUNC
//! Locate the file, get Client IP and target IP.
//! 1) If both are private, redirect to local does apply.
//! set ErrInfo of param Resp and return SFS_REDIRECT.
//! 2) Not both are private, redirect to local does NOT apply.
//! return nativeCmsFinder->Locate, for normal redirection procedure
//!
//! @Param Resp: Either set manually here or passed to nativeCmsFinder->Locate
//! @Param path: The path of the file, passed to nativeCmsFinder->Locate
//! @Param flags: The open flags, passed to nativeCmsFinder->Locate
//! @Param EnvInfo: Contains the secEnv, which contains the addressInfo of the
//! Client. Checked to see if redirect to local conditions apply
//------------------------------------------------------------------------------
int XrdCmsRedirLocal::Locate(XrdOucErrInfo &Resp, const char *path, int flags,
XrdOucEnv *EnvInfo) {
int rcode = 0;
if (nativeCmsFinder) {
// get regular target host
rcode = nativeCmsFinder->Locate(Resp, path, flags, EnvInfo);
// define target host from locate result
XrdNetAddr target(-1); // port is necessary, but can be any
target.Set(Resp.getErrText());
// does the target host have a private IP?
if (!target.isPrivate())
return rcode;

// does the client host have a private IP?
if (!EnvInfo->secEnv()->addrInfo->isPrivate())
return rcode;

// get client url redirect capability
int urlRedirSupport = Resp.getUCap();
urlRedirSupport &= XrdOucEI::uUrlOK;
if (!urlRedirSupport)
return rcode;

// get client localredirect capability
int clientLRedirSupport = Resp.getUCap();
clientLRedirSupport &= XrdOucEI::uLclF;
if (!clientLRedirSupport)
return rcode;

// only allow simple (but most prominent) operations to avoid complications
// RDONLY, WRONLY, RDWR, CREAT, TRUNC are allowed
if (flags > 0x202)
return rcode;
// always use native function if readOnlyredirect is configured and a
// non readonly flag is passed
if (readOnlyredirect && !(flags == SFS_O_RDONLY))
return rcode;

// passed all checks, now to actual business
// build a buffer with a total acceptable buffer length,
// which must have a larger capacity than localroot and filename concatenated
int rc = 0;
int maxPathLength = 4096;
char *buff = new char[maxPathLength];
// prepend oss.localroot
const char *ppath = theSS->Lfn2Pfn(path, buff, maxPathLength, rc);
// set info which will be sent to client
Resp.setErrInfo(-1, ppath);
delete[] buff;
return SFS_REDIRECT;
}
return rcode;
}

//------------------------------------------------------------------------------
//! Space
//! Calls nativeCmsFinder->Space
//------------------------------------------------------------------------------
int XrdCmsRedirLocal::Space(XrdOucErrInfo &Resp, const char *path,
XrdOucEnv *EnvInfo) {
if (nativeCmsFinder)
return nativeCmsFinder->Space(Resp, path, EnvInfo);
return 0;
}

XrdVERSIONINFO(XrdCmsGetClient, XrdCmsRedirLocal);
81 changes: 81 additions & 0 deletions src/XrdCms/XrdCmsRedirLocal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// Copyright (c) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
// Author: Paul-Niklas Kramp <p.n.kramp@gsi.de>
// Jan Knedlik <j.knedlik@gsi.de>
//------------------------------------------------------------------------------
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD 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 Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------


/* README:
Options for xrootd config
- Enable:
- Enable with ofs.cmslib libXrdCmsRedirectLocal.so
- allow only readonly request to be redirected to local, default is false
- XrdCmsRedirLocal.readonlyredirect true
*/

#ifndef XRDCMSREDIRPLUGIN_HH_
#define XRDCMSREDIRPLUGIN_HH_
#include <XrdCms/XrdCmsFinder.hh>
#include <XrdCms/XrdCmsClient.hh>
#include <XrdNet/XrdNetAddr.hh>
#include <XrdOss/XrdOss.hh>
#include <XrdOuc/XrdOucEnv.hh>
#include <XrdSec/XrdSecEntity.hh>
#include <XrdSfs/XrdSfsInterface.hh>
#include <XrdOuc/XrdOucStream.hh>
#include <XrdOuc/XrdOucString.hh>
#include <XrdVersion.hh>
#include <string>
#include <fcntl.h>

class XrdCmsRedirLocal : public XrdCmsClient {
public:
XrdCmsRedirLocal(XrdSysLogger *Logger, int opMode, int myPort, XrdOss *theSS);
~XrdCmsRedirLocal();
int Configure(const char *cfn, char *Parms, XrdOucEnv *EnvInfo);
void loadConfig(const char *filename);
int Locate(XrdOucErrInfo &Resp, const char *path, int flags,
XrdOucEnv *EnvInfo);

int Space(XrdOucErrInfo &Resp, const char *path, XrdOucEnv *EnvInfo);
void Added(const char *path, int Pend = 0) {
nativeCmsFinder->Added(path, Pend);
}
int Forward(XrdOucErrInfo &Resp, const char *cmd, const char *arg1 = 0,
const char *arg2 = 0, XrdOucEnv *Env1 = 0, XrdOucEnv *Env2 = 0) {
return nativeCmsFinder->Forward(Resp, cmd, arg1, arg2, Env1, Env2);
}
int isRemote() { return nativeCmsFinder->isRemote(); }
XrdOucTList *Managers() { return nativeCmsFinder->Managers(); }
int Prepare(XrdOucErrInfo &Resp, XrdSfsPrep &pargs, XrdOucEnv *Info = 0) {
return nativeCmsFinder->Prepare(Resp, pargs, Info);
}
void Removed(const char *path) { return nativeCmsFinder->Removed(path); }
void Resume(int Perm = 1) { nativeCmsFinder->Resume(Perm); }
void Suspend(int Perm = 1) { nativeCmsFinder->Suspend(Perm); }
int Resource(int n) { return nativeCmsFinder->Resource(n); }
int Reserve(int n = 1) { return nativeCmsFinder->Reserve(n); }
int Release(int n = 1) { return nativeCmsFinder->Release(n); }

//---------------------------------------------------------------------------
//! used to forward requests to CmsFinder with regular implementation
//---------------------------------------------------------------------------
XrdCmsClient *nativeCmsFinder;
XrdOss *theSS;
bool readOnlyredirect;
};

#endif // XRDCMSREDIRPLUGIN_HH_
20 changes: 19 additions & 1 deletion src/XrdPlugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include( XRootDCommon )
set( LIB_XRD_BWM XrdBwm-${PLUGIN_VERSION} )
set( LIB_XRD_N2NO2P XrdN2No2p-${PLUGIN_VERSION} )
set( LIB_XRD_PSS XrdPss-${PLUGIN_VERSION} )
set( LIB_XRD_CMSREDIRL XrdCmsRedirectLocal-${PLUGIN_VERSION} )
set( LIB_XRD_GPFS XrdOssSIgpfsT-${PLUGIN_VERSION} )
set( LIB_XRD_ZCRC32 XrdCksCalczcrc32-${PLUGIN_VERSION} )
set( LIB_XRD_THROTTLE XrdThrottle-${PLUGIN_VERSION} )
Expand Down Expand Up @@ -147,9 +148,26 @@ set_target_properties(
INTERFACE_LINK_LIBRARIES ""
LINK_INTERFACE_LIBRARIES "" )

#-------------------------------------------------------------------------------
# The XrdCmsRedirLocal module
#-------------------------------------------------------------------------------
add_library(
${LIB_XRD_CMSREDIRL}
MODULE
XrdCms/XrdCmsRedirLocal.cc XrdCms/XrdCmsRedirLocal.hh )

target_link_libraries(
${LIB_XRD_CMSREDIRL} )

set_target_properties(
${LIB_XRD_CMSREDIRL}
PROPERTIES
INTERFACE_LINK_LIBRARIES ""
LINK_INTERFACE_LIBRARIES "" )

#-------------------------------------------------------------------------------
# Install
#-------------------------------------------------------------------------------
install(
TARGETS ${LIB_XRD_PSS} ${LIB_XRD_BWM} ${LIB_XRD_GPFS} ${LIB_XRD_ZCRC32} ${LIB_XRD_THROTTLE} ${LIB_XRD_N2NO2P}
TARGETS ${LIB_XRD_PSS} ${LIB_XRD_BWM} ${LIB_XRD_GPFS} ${LIB_XRD_ZCRC32} ${LIB_XRD_THROTTLE} ${LIB_XRD_N2NO2P} ${LIB_XRD_CMSREDIRL}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )