Skip to content

Commit

Permalink
Implement blacklisting in a FileCache decision plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
bbockelm committed Sep 14, 2015
1 parent 9f37b68 commit 6ba02af
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
1 change: 1 addition & 0 deletions packaging/rhel/xrootd.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ fi
%{_libdir}/libXrdPss-4.so
%{_libdir}/libXrdXrootd-4.so
%{_libdir}/libXrdFileCache-4.so
%{_libdir}/libXrdBlacklistDecision-4.so
%{_libdir}/libXrdHttp-4.so
%{_libdir}/libXrdOssSIgpfsT-4.so
%{_libdir}/libXrdServer.so.*
Expand Down
23 changes: 23 additions & 0 deletions src/XrdFileCache.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include( XRootDCommon )
# Modules
#-------------------------------------------------------------------------------
set( LIB_XRD_FILECACHE XrdFileCache-${PLUGIN_VERSION} )
set( LIB_XRD_BLACKLIST XrdBlacklistDecision-${PLUGIN_VERSION} )

#-------------------------------------------------------------------------------
# Shared library version
Expand Down Expand Up @@ -38,6 +39,24 @@ set_target_properties(
INTERFACE_LINK_LIBRARIES ""
LINK_INTERFACE_LIBRARIES "" )

#-------------------------------------------------------------------------------
# The XrdBlacklistDecision library
#-------------------------------------------------------------------------------
add_library(
${LIB_XRD_BLACKLIST}
MODULE
XrdFileCache/XrdFileCacheBlacklistDecision.cc)

target_link_libraries(
${LIB_XRD_BLACKLIST}
)

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

#-------------------------------------------------------------------------------
# xrdpfc_print
#-------------------------------------------------------------------------------
Expand All @@ -59,6 +78,10 @@ install(
TARGETS ${LIB_XRD_FILECACHE}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )

install(
TARGETS ${LIB_XRD_BLACKLIST}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )

install(
TARGETS xrdpfc_print
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
Expand Down
130 changes: 130 additions & 0 deletions src/XrdFileCache/XrdFileCacheBlacklistDecision.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//----------------------------------------------------------------------------------
// Copyright (c) 2015 by Board of Trustees of the Leland Stanford, Jr., University
// Author: Alja Mrak-Tadel, Matevz Tadel, Brian Bockelman
//----------------------------------------------------------------------------------
// 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 "XrdFileCacheDecision.hh"
#include "XrdSys/XrdSysError.hh"

#include <vector>
#include <fcntl.h>
#include <stdio.h>
#include <fnmatch.h>

class BlacklistDecision : public XrdFileCache::Decision
{
//----------------------------------------------------------------------------
//! A decision library that allows all files to be cached except for a blacklist
//----------------------------------------------------------------------------

public:
virtual bool Decide(const std::string & url, XrdOss &) const
{
size_t slashslash = url.find("//");
const char *fname = url.c_str();
if (slashslash != std::string::npos)
{
fname += slashslash+2;
fname = strchr(fname, '/');
if (!fname) {return true;}
}
std::string url_path = fname;
size_t question = url_path.find("?");
if (question != std::string::npos)
{
url_path[question] = '\0';
fname = url_path.c_str();
}
if ((strlen(fname) > 1) && (fname[0] == '/') && (fname[1] == '/'))
{
fname++;
}
//m_log.Emsg("BlacklistDecide", "Deciding whether to cache file", fname);
for (std::vector<std::string>::const_iterator it = m_blacklist.begin(); it != m_blacklist.end(); it++)
{
if (!fnmatch(it->c_str(), fname, FNM_PATHNAME))
{
//m_log.Emsg("BlacklistDecide", "Not caching file as it matches blacklist entry", it->c_str());
return false;
}
}
//m_log.Emsg("BlacklistDecide", "Caching file", fname);
return true;
}

BlacklistDecision(XrdSysError &log)
: m_log(log)
{
}

virtual bool ConfigDecision(const char * parms)
{
if (!parms || !parms[0] || (strlen(parms) == 0))
{
m_log.Emsg("ConfigDecision", "Blacklist file not specified.");
return false;
}
m_log.Emsg("ConfigDecision", "Using blacklist", parms);
FILE * fp = fopen(parms, "r");
if (fp == 0)
{
m_log.Emsg("ConfigDecision", errno, "Failed to open blacklist:", parms);
return false;
}

ssize_t read;
size_t len =0;
char *line = NULL;
while (-1 != (read=getline(&line, &len, fp)))
{
char *trimmed = line;
while (trimmed[0] && isspace(trimmed[0])) {trimmed++;}
if (trimmed[0] == 0) {continue;}
size_t filelen = strlen(trimmed);
if (trimmed[filelen-1] == '\n') {trimmed[filelen-1] = '\0';}
m_blacklist.push_back(trimmed);
}
free(line);
fclose(fp);
if (!feof(fp))
{
m_log.Emsg("ConfigDecision", errno, "Failed to parse blacklist");
}
for (std::vector<std::string>::const_iterator it=m_blacklist.begin(); it!=m_blacklist.end(); it++)
{
m_log.Emsg("ConfigDecision", "Cache is blacklisting paths matching", it->c_str());
}
return true;
}

private:
std::vector<std::string> m_blacklist;
XrdSysError &m_log;
};

/******************************************************************************/
/* XrdFileCacheGetDecision */
/******************************************************************************/

// Return a decision object to use.
extern "C"
{
XrdFileCache::Decision *XrdFileCacheGetDecision(XrdSysError &err)
{
return new BlacklistDecision(err);
}
}

2 changes: 1 addition & 1 deletion src/XrdFileCache/XrdFileCacheDecision.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace XrdFileCache
//!
//! @return decision
//---------------------------------------------------------------------
virtual bool Decide(std::string &, XrdOss &) const = 0;
virtual bool Decide(const std::string &, XrdOss &) const = 0;

//------------------------------------------------------------------------------
//! Parse configuration arguments.
Expand Down
3 changes: 2 additions & 1 deletion src/XrdFileCache/XrdFileCacheFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ bool Factory::xdlib(XrdOucStream &Config)
std::string libp;
if (!(val = Config.GetWord()) || !val[0])
{
clLog()->Info(XrdCl::AppMsg, " Factory:;Config() decisionlib not specified; always caching files");
clLog()->Info(XrdCl::AppMsg, " Factory::Config() decisionlib not specified; always caching files");
return true;
}
else
Expand Down Expand Up @@ -150,6 +150,7 @@ bool Factory::xdlib(XrdOucStream &Config)
d->ConfigDecision(params);

m_decisionpoints.push_back(d);
clLog()->Info(XrdCl::AppMsg, "Factory::Config() successfully created decision lib from %s", libp.c_str());
return true;
}
//______________________________________________________________________________
Expand Down

0 comments on commit 6ba02af

Please sign in to comment.