32 #include "XrdVersion.hh"
39 #include <sys/types.h>
61 std::map<std::string, FactoryHelper*>::iterator it;
62 for( it = pFactoryMap.begin(); it != pFactoryMap.end(); ++it )
64 it->second->counter--;
65 if( it->second->counter == 0 )
69 delete pDefaultFactory;
81 std::string normUrl = NormalizeURL( url );
85 std::map<std::string, FactoryHelper*>::iterator it;
86 it = pFactoryMap.find( normUrl );
87 if( it != pFactoryMap.end() )
89 if( it->second->isEnv )
102 pFactoryMap.erase( it );
109 FactoryHelper *h =
new FactoryHelper();
110 h->factory = factory;
112 pFactoryMap[normUrl] = h;
124 if( pDefaultFactory && pDefaultFactory->isEnv )
127 delete pDefaultFactory;
133 pDefaultFactory =
new FactoryHelper;
134 pDefaultFactory->factory = factory;
149 if( pDefaultFactory && pDefaultFactory->isEnv )
150 return pDefaultFactory->factory;
152 std::string normUrl = NormalizeURL( url );
153 if( normUrl.empty() )
155 if( pDefaultFactory )
156 return pDefaultFactory->factory;
160 std::map<std::string, FactoryHelper*>::iterator it;
161 it = pFactoryMap.find( normUrl );
162 if( it != pFactoryMap.end() && it->second->isEnv )
163 return it->second->factory;
166 std::map<std::string, FactoryHelper*>::iterator itProt;
167 itProt = pFactoryMap.find( protocol );
168 if( itProt != pFactoryMap.end() && itProt->second->isEnv )
169 return itProt->second->factory;
171 if( pDefaultFactory )
172 return pDefaultFactory->factory;
174 if( it != pFactoryMap.end() )
175 return it->second->factory;
177 if( itProt != pFactoryMap.end() )
178 return itProt->second->factory;
197 bool loadConfigs =
true;
199 env->
GetString(
"PlugIn", defaultPlugIn );
200 if( !defaultPlugIn.empty() )
204 defaultPlugIn.c_str());
206 std::pair<XrdOucPinLoader*, PlugInFactory *> pg = LoadFactory(
207 defaultPlugIn, std::map<std::string, std::string>() );
212 defaultPlugIn.c_str());
216 pDefaultFactory =
new FactoryHelper();
217 pDefaultFactory->factory = pg.second;
218 pDefaultFactory->plugin = pg.first;
219 pDefaultFactory->isEnv =
true;
229 "No default plug-in, loading plug-in configs..." );
231 ProcessConfigDir(
"/etc/xrootd/client.plugins.d" );
234 passwd *pwd = pwdHandler.
Get( getuid() );
237 std::string userPlugIns = pwd->pw_dir;
238 userPlugIns +=
"/.xrootd/client.plugins.d";
239 ProcessConfigDir( userPlugIns );
242 env->
GetString(
"PlugInConfDir", customPlugIns );
243 if( !customPlugIns.empty() )
244 ProcessConfigDir( customPlugIns );
251 void PlugInManager::ProcessConfigDir(
const std::string &dir )
257 std::vector<std::string> entries;
258 std::vector<std::string>::iterator it;
263 dir.c_str(), st.
ToString().c_str() );
266 std::sort( entries.begin(), entries.end() );
268 for( it = entries.begin(); it != entries.end(); ++it )
270 std::string confFile = dir +
"/" + *it;
271 std::string suffix =
".conf";
272 if( confFile.length() <= suffix.length() )
274 if( !std::equal( suffix.rbegin(), suffix.rend(), confFile.rbegin() ) )
277 ProcessPlugInConfig( confFile );
284 void PlugInManager::ProcessPlugInConfig(
const std::string &confFile )
287 log->Dump(
PlugInMgrMsg,
"Processing: %s", confFile.c_str() );
292 std::map<std::string, std::string> config;
296 log->Debug(
PlugInMgrMsg,
"Unable process config %s: %s",
297 confFile.c_str(), st.ToString().c_str() );
301 const char *keys[] = {
"url",
"lib",
"enable", 0 };
302 for(
int i = 0; keys[i]; ++i )
304 if( config.find( keys[i] ) == config.end() )
306 log->Debug(
PlugInMgrMsg,
"Unable to find '%s' key in the config file "
307 "%s, ignoring this config", keys[i], confFile.c_str() );
315 std::string url = config[
"url"];
316 std::string lib = config[
"lib"];
317 std::string enable = config[
"enable"];
319 log->Dump(
PlugInMgrMsg,
"Settings from '%s': url='%s', lib='%s', "
320 "enable='%s'", confFile.c_str(), url.c_str(), lib.c_str(),
323 std::pair<XrdOucPinLoader*, PlugInFactory *> pg;
324 pg.first = 0; pg.second = 0;
325 if( enable ==
"true" )
327 log->Debug(
PlugInMgrMsg,
"Trying to load a plug-in for '%s' from '%s'",
328 url.c_str(), lib.c_str() );
330 pg = LoadFactory( lib, config );
336 log->Debug(
PlugInMgrMsg,
"Trying to disable plug-in for '%s'",
349 std::pair<XrdOucPinLoader*,PlugInFactory*> PlugInManager::LoadFactory(
350 const std::string &lib,
const std::map<std::string, std::string> &config )
355 if( lib ==
"XrdEcDefault" )
357 auto itr = config.find(
"nbdta" );
358 if( itr == config.end() )
359 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>(
nullptr,
nullptr );
360 uint8_t nbdta = std::stoul( itr->second );
361 itr = config.find(
"nbprt" );
362 if( itr == config.end() )
363 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>(
nullptr,
nullptr );
364 uint8_t nbprt = std::stoul( itr->second );
365 itr = config.find(
"chsz" );
366 if( itr == config.end() )
367 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>(
nullptr,
nullptr );
368 uint64_t chsz = std::stoul( itr->second );
369 std::vector<std::string> plgr;
370 itr = config.find(
"plgr" );
371 if( itr != config.end() )
374 std::string xrdclECenv = std::to_string(nbdta) +
"," +
375 std::to_string(nbprt) +
"," +
376 std::to_string(chsz);
377 setenv(
"XRDCL_EC", xrdclECenv.c_str(), 1);
379 EcPlugInFactory *ecHandler =
new EcPlugInFactory( nbdta, nbprt, chsz, std::move( plgr ) );
380 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>(
nullptr, ecHandler );
384 char errorBuff[1024];
386 &XrdVERSIONINFOVAR(
XrdCl ),
387 "client", lib.c_str() );
389 PlugInFunc_t pgFunc = (PlugInFunc_t)pgHandler->
Resolve(
"XrdClGetPlugIn", -1);
393 log->Debug(
PlugInMgrMsg,
"Error while loading %s: %s", lib.c_str(),
397 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>( 0, 0 );
400 PlugInFactory *f = (PlugInFactory*)pgFunc( &config );
405 return std::make_pair<XrdOucPinLoader*, PlugInFactory*>( 0, 0 );
408 return std::make_pair( pgHandler, f );
415 const std::string &lib,
416 PlugInFactory *factory,
423 std::vector<std::string> urls;
424 std::vector<std::string> normalizedURLs;
425 std::vector<std::string>::iterator it;
427 if (urlString ==
"*") {
428 if (pDefaultFactory) {
429 if (pDefaultFactory->isEnv) {
430 log->Debug(
PlugInMgrMsg,
"There is already an env default plugin "
431 "loaded, skipping %s", lib.c_str());
434 log->Debug(
PlugInMgrMsg,
"There can be only one default plugin "
435 "loaded, skipping %s", lib.c_str());
439 pDefaultFactory =
new FactoryHelper();
440 pDefaultFactory->factory = factory;
441 pDefaultFactory->plugin = plugin;
442 pDefaultFactory->isEnv =
false;
449 for( it = urls.begin(); it != urls.end(); ++it )
451 std::string normURL = NormalizeURL( *it );
454 log->Debug(
PlugInMgrMsg,
"Url cannot be normalized: '%s', ignoring",
458 normalizedURLs.push_back( normURL );
461 std::sort( normalizedURLs.begin(), normalizedURLs.end() );
463 auto last = std::unique( normalizedURLs.begin(), normalizedURLs.end() );
464 normalizedURLs.erase( last, normalizedURLs.end() );
466 if( normalizedURLs.empty() )
472 FactoryHelper *h = 0;
476 h =
new FactoryHelper();
478 h->counter = normalizedURLs.size();
480 h->factory = factory;
483 std::map<std::string, FactoryHelper*>::iterator mapIt;
484 for( it = normalizedURLs.begin(); it != normalizedURLs.end(); ++it )
486 mapIt = pFactoryMap.find( *it );
487 if( mapIt != pFactoryMap.end() )
489 mapIt->second->counter--;
490 if( mapIt->second->counter == 0 )
491 delete mapIt->second;
496 log->Debug(
PlugInMgrMsg,
"Registering a factory for %s from %s",
497 it->c_str(), lib.c_str() );
498 pFactoryMap[*it] = h;
502 if( mapIt != pFactoryMap.end() )
504 log->Debug(
PlugInMgrMsg,
"Removing the factory for %s",
506 pFactoryMap.erase( mapIt );
517 std::string PlugInManager::NormalizeURL(
const std::string url )
520 if( !urlObj.IsValid() )
523 std::string protocol = urlObj.GetProtocol();
524 std::string hostname = urlObj.GetHostName();
526 if( hostname ==
"*" )
529 std::ostringstream o;
530 o << protocol <<
"://" << hostname <<
":";
531 o << urlObj.GetPort();
static Log * GetLog()
Get default log.
static Env * GetEnv()
Get default client environment.
bool GetString(const std::string &key, std::string &value)
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
void ProcessEnvironmentSettings()
bool RegisterFactory(const std::string &url, PlugInFactory *factory)
PlugInManager()
Constructor.
bool RegisterDefaultFactory(PlugInFactory *factory)
Register a plug-in factory applying to all URLs.
~PlugInManager()
Destructor.
PlugInFactory * GetFactory(const std::string url)
const std::string & GetProtocol() const
Get the protocol.
static Status ProcessConfig(std::map< std::string, std::string > &config, const std::string &file)
Process a config file and return key-value pairs.
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
static Status GetDirectoryEntries(std::vector< std::string > &entries, const std::string &path)
Get directory entries.
void * Resolve(const char *symbl, int mcnt=1)
void Unload(bool dodel=false)
struct passwd * Get(const char *Usr)
const char *const DefaultPlugIn
const char *const DefaultPlugInConfDir
const uint64_t PlugInMgrMsg
Procedure execution status.
bool IsOK() const
We're fine.
std::string ToString() const
Create a string representation.