Skip to content

Commit

Permalink
support caching of local files, prepar to support http/https data source
Browse files Browse the repository at this point in the history
  • Loading branch information
wyang007 committed Feb 2, 2019
1 parent d5d31e7 commit 01c92d1
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 62 deletions.
68 changes: 54 additions & 14 deletions XrdOssStatInfoDCP.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,46 @@ using namespace std;
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdSys/XrdSysError.hh"

static std::string gLFNprefix = "/atlas/rucio"; // default

extern "C" {

int XrdOssStatInfo(const char *path, struct stat *buff,
int opts, XrdOucEnv *envP)
{
std::string cachePath, prefix, tmp;
std::size_t i;
std::string cachePath, osslocalroot, tmp;
std::size_t i, j;

tmp = path;
i = tmp.rfind("/atlas/rucio");
i = tmp.rfind(gLFNprefix);
if (i != string::npos)
{
prefix = tmp.substr(0, i);
cachePath = prefix + pfn2cache("", tmp.substr(i+1, tmp.length() -i).c_str());
{ // the "path" may be like this: /data/xrd/namespace/atlas/rucio/scope/xx/xx/file
osslocalroot = tmp.substr(0, i);
cachePath = osslocalroot + pfn2cache("", gLFNprefix, tmp.substr(i, tmp.length() -i).c_str());
}
else
{
i = tmp.find("/root:/");
if (i == string::npos) i = tmp.find("/http:/");
if (i == string::npos) i = tmp.find("/https:/");

if (i != string::npos)
{
prefix = tmp.substr(0, i);
i = tmp.rfind("/rucio/");
if (i != string::npos)
cachePath = prefix + pfn2cache("", tmp.substr(i+1, tmp.length() -i).c_str());
else
cachePath = path;
{ // the "path" may be like this: /data/xrd/namespace/root:/host:port/...
osslocalroot = tmp.substr(0, i);
j = tmp.rfind("/rucio/");
if (j != string::npos) // the "path" may be like this: /data/xrd/namespace/root:/host:port/xrootd/rucio/scope/xx/xx/file
cachePath = osslocalroot + pfn2cache("", gLFNprefix, tmp.substr(j, tmp.length() -j).c_str());
else // the "path" may be like this: /data/xrdname/root:/host:port/xrootd/junk (no "/rucio")
{
tmp.replace(0, i, ""); // tmp is now /root:/host:port/xrootd/junk
i = tmp.find(":/");
tmp.replace(0, i +2, "");; // tmp is now host:port/xrootd/junk
i = tmp.find("/");
tmp.replace(0, i, "");; // tmp is now /xrootd/junk
cachePath = osslocalroot + tmp;
}
}
else
else // the "path" maybe like this: /data/xrd/namespace/tmp/README
cachePath = path;
}
return (stat(cachePath.c_str(), buff)? -1 : 0);
Expand All @@ -55,6 +67,34 @@ XrdOssStatInfo_t XrdOssStatInfoInit(XrdOss *native_oss,
const char *config_fn,
const char *parms)
{
std::string opts, key, value;
std::string::iterator it;
int x;

x = 0;
key = "";
value = "";

opts = parms;
opts += " ";
for (it=opts.begin(); it!=opts.end(); ++it)
{
if (*it == '=') x = 1;
else if (*it == ' ')
{
if (key == "glfnprefix")
gLFNprefix = value;
key = "";
value = "";
x = 0;
}
else
{
if (x == 0) key += *it;
if (x == 1) value += *it;
}
}

return (XrdOssStatInfo_t)XrdOssStatInfo;
}
};
Expand Down
77 changes: 50 additions & 27 deletions XrdOucName2NameDCP4RUCIO.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class XrdOucName2NameDiskCacheProxy4Rucio : public XrdOucName2Name

friend XrdOucName2Name *XrdOucgetName2Name(XrdOucgetName2NameArgs);
private:
string myName, localMetaLinkRootDir;
string myName, localMetaLinkRootDir, gLFNprefix, rucioServer;
XrdSysError *eDest;
bool isCmsd;
};
Expand All @@ -48,7 +48,9 @@ XrdOucName2NameDiskCacheProxy4Rucio::XrdOucName2NameDiskCacheProxy4Rucio(XrdSysE

myName = "Xcache4RUCIO";
eDest = erp;
localMetaLinkRootDir = "/dev/shm/atlas";
localMetaLinkRootDir = "";
gLFNprefix = "/atlas/rucio";
rucioServer = "rucio-lb-prod.cern.ch";

isCmsd = false;
if (getenv("XRDPROG"))
Expand All @@ -57,6 +59,9 @@ XrdOucName2NameDiskCacheProxy4Rucio::XrdOucName2NameDiskCacheProxy4Rucio(XrdSysE
if (myProg == "cmsd") isCmsd = true;
}

setenv("XRD_METALINKPROCESSING", "1", 0);
setenv("XRD_LOCALMETALINKFILE", "1", 0);

x = 0;
key = "";
value = "";
Expand All @@ -69,11 +74,11 @@ XrdOucName2NameDiskCacheProxy4Rucio::XrdOucName2NameDiskCacheProxy4Rucio(XrdSysE
else if (*it == ' ')
{
if (key == "metalinkdir")
{
localMetaLinkRootDir = value;
message = myName + " Init : metalinkdir = " + localMetaLinkRootDir;
eDest->Say(message.c_str());
}
else if (key == "glfnprefix")
gLFNprefix = value;
else if (key == "rucioserver")
rucioServer = value;
key = "";
value = "";
x = 0;
Expand All @@ -84,17 +89,27 @@ XrdOucName2NameDiskCacheProxy4Rucio::XrdOucName2NameDiskCacheProxy4Rucio(XrdSysE
if (x == 1) value += *it;
}
}
rucioGetMetaLinkInit(localMetaLinkRootDir, checkPFCcinfoInit(confg));
// defaults
if (localMetaLinkRootDir == "") localMetaLinkRootDir = "/dev/shm" + gLFNprefix;

message = myName + " Init: glfnprefix = " + gLFNprefix;
eDest->Say(message.c_str());
message = myName + " Init: metalinkdir = " + localMetaLinkRootDir;
eDest->Say(message.c_str());
message = myName + " Init: RUCIO metalink server = " + rucioServer;
eDest->Say(message.c_str());

rucioGetMetaLinkInit(localMetaLinkRootDir, gLFNprefix, rucioServer, checkPFCcinfoInit(confg));
}

int XrdOucName2NameDiskCacheProxy4Rucio::lfn2pfn(const char* lfn, char* buff, int blen)
{
std::string myLfn, myPfn, rucioDID;
std::string scope, slashScope, file;
std::size_t i;
MD5_CTX c;
unsigned char md5digest[MD5_DIGEST_LENGTH];
char md5string[MD5_DIGEST_LENGTH*2+1];
// MD5_CTX c;
// unsigned char md5digest[MD5_DIGEST_LENGTH];
// char md5string[MD5_DIGEST_LENGTH*2+1];

if (isCmsd) // cmsd shouldn't do lfn2pfn()
{
Expand All @@ -107,26 +122,34 @@ int XrdOucName2NameDiskCacheProxy4Rucio::lfn2pfn(const char* lfn, char* buff, in
myLfn = lfn;
// see comments in pfn2cache()

if (myLfn.find("/root:/") == 0)
// Do not allow users to specify file:// or root://localhost
if (myLfn.find("/root:/localfile") == 0 || myLfn.find("/file:/") == 0)
{
myPfn = "ENOENT";
return EFAULT;
}

if (myLfn.find("/root:/") == 0 || myLfn.find("/http:/") == 0 || myLfn.find("/https:/") == 0)
myPfn = makeMetaLink(eDest, myName, lfn); // Assume the client know the data source...
else
else if ((i = myLfn.rfind(gLFNprefix)) != 0)
{
// client want so access a local file that is permitted by the xcache configuration
myLfn = "/file:/localhost" + myLfn;
myPfn = makeMetaLink(eDest, myName, myLfn.c_str());
}
else // gLFN
{
i = myLfn.rfind("/atlas/rucio");
if (i == 0)
// with a leading "/"
rucioDID = myLfn.substr(i + gLFNprefix.length(), myLfn.length() -i - gLFNprefix.length());
if (rucioDID.rfind("/") < rucioDID.rfind(":") && rucioDID.rfind(":") != string::npos)
// check if this is /atlas/rucio/scope:file format
myPfn = getMetaLink(eDest, myName, rucioDID);
else
{
rucioDID = myLfn.substr(i + 12, myLfn.length() -i -12); // with a leading "/"
if (rucioDID.rfind("/") < rucioDID.rfind(":") && rucioDID.rfind(":") != string::npos)
// check if this is /atlas/rucio/scope:file format
myPfn = getMetaLink(eDest, myName, rucioDID);
else
{
// otherwise, assume this is /atlas/rucio/scope/xx/xx/file format
rucioDID = rucioDID.replace(rucioDID.rfind("/") -6, 7, ":");
myPfn = getMetaLink(eDest, myName, rucioDID);
}
// otherwise, assume this is /atlas/rucio/scope/xx/xx/file format
rucioDID = rucioDID.replace(rucioDID.rfind("/") -6, 7, ":");
myPfn = getMetaLink(eDest, myName, rucioDID);
}
else
myPfn="ENOENT";
}
if (myPfn == "EFAULT")
return EFAULT;
Expand All @@ -145,7 +168,7 @@ int XrdOucName2NameDiskCacheProxy4Rucio::pfn2lfn(const char* pfn, char* buff, in
{
std::string cachePath;

cachePath = pfn2cache(localMetaLinkRootDir, pfn);
cachePath = pfn2cache(localMetaLinkRootDir, gLFNprefix, pfn);
blen = cachePath.length();
strncpy(buff, cachePath.c_str(), blen);
buff[blen] = '\0';
Expand Down
8 changes: 6 additions & 2 deletions pfn2cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace std;
#include <string>
#include <openssl/md5.h>

std::string pfn2cache(const std::string localMetaLinkRootDir, const char* pfn)
std::string pfn2cache(const std::string localMetaLinkRootDir, const std::string gLFNprefix, const char* pfn)
{
// rucioDID isn't quite ruico DID (scrope:file), rucioDID = scrope/XX/XX/file

Expand Down Expand Up @@ -42,6 +42,10 @@ std::string pfn2cache(const std::string localMetaLinkRootDir, const char* pfn)
// if pfn does have "/rucio/", rucioDID will point to the string after the last
// "rucio", including the leading "/"
// buff = /atlas/rucio<rucioDID>
//
// It is risky to only depend on "Is "/rucio/" in path" to determine if the path is a RUCIO path.
// It is better to check the string after "/rucio/" to see whether it is in the form of scope:file
// or scope/xx/xx/file (hash "/xx/xx/" could be checked)
if (i == string::npos)
cachePath = myPfn;
else
Expand Down Expand Up @@ -78,7 +82,7 @@ std::string pfn2cache(const std::string localMetaLinkRootDir, const char* pfn)
rucioDID = "/" + slashScope + "/" + tmp.substr(0, 2) + "/" + tmp.substr(2, 2) + "/" + file;
}

cachePath = "/atlas/rucio" + rucioDID;
cachePath = gLFNprefix + rucioDID;
}
return cachePath;
}
2 changes: 1 addition & 1 deletion pfn2cache.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
* Author: Wei Yang (SLAC National Accelerator Laboratory / Stanford University, 2017)
*/

std::string pfn2cache(const std::string localMetaLinkRootDir, const char* pfn);
std::string pfn2cache(const std::string, const std::string, const char*);
37 changes: 20 additions & 17 deletions rucioGetMetaLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ std::string rucioServerCgi = "/metalink?schemes=root&sort=geoip";
#define MetaLinkLifeTmin 1440
#define MetaLinkLifeTsec MetaLinkLifeTmin*60

static std::string localMetaLinkRootDir;
static std::string ossLocalRoot;
static std::string gLFNprefix;

struct rucioMetaLink
{
char *data;
size_t size;
};

std::string localMetaLinkRootDir;
std::string ossLocalRoot;

void cleaner()
{
std::string cmd;
Expand All @@ -59,9 +60,11 @@ void cleaner()

static int Xcache4RUCIO_DBG = 0;

void rucioGetMetaLinkInit(const std::string dir, const std::string osslocalroot)
void rucioGetMetaLinkInit(const std::string dir, const std::string glfnprefix, const std::string rucioserver, const std::string osslocalroot)
{
localMetaLinkRootDir = dir;
gLFNprefix = glfnprefix;
rucioServerUrl = "https://" + rucioserver + "/redirect/";
ossLocalRoot = osslocalroot;

std::thread cleanning(cleaner);
Expand Down Expand Up @@ -119,26 +122,26 @@ int mkdir_p(const std::string dir)
// data source at file://localhost//... so that we don't need to Open() with a remote data source.
std::string makeMetaLink(XrdSysError* eDest, const std::string myName, const std::string pfn)
{
std::string metaLinkDir, metaLinkFile, myPfn, tmp;
std::string metaLinkDir, metaLinkFile, myPfn, proto, tmp;
size_t i;

// "repair" pfn, from "/root:/atlrdr1:11094/xrootd" to "root://atlrdr1:11094//xrootd"
// we will also need to consider other protocols such as file: http: https:
myPfn = pfn;
myPfn.replace(0, 7, "");
myPfn.replace(myPfn.find("/"), 1, "//");
myPfn = "root://" + myPfn;
proto = myPfn.substr(1, myPfn.find(":/")); // "root:", not "root"
myPfn.replace(0, proto.length()+2, "");
if (proto == "root:") myPfn.replace(myPfn.find("/"), 1, "//"); // this is the / or // right before path
myPfn = proto + "//" + myPfn;

XrdCl::URL rootURL = myPfn;
if (!rootURL.IsValid()) return "EFAULT";
if (proto == "root:" && !rootURL.IsValid()) return "EFAULT";

metaLinkFile = myPfn;
if (metaLinkFile.find("root://") == 0)
{
metaLinkFile = metaLinkFile.replace(0, 7, ""); // remote "root://"
metaLinkFile = metaLinkFile.replace(0, metaLinkFile.find("/")+2, ""); // remote loginid@hostnaem:port//
}
metaLinkFile = metaLinkFile.replace(0, proto.length()+2, ""); // remove "root://"
metaLinkFile = metaLinkFile.replace(0, metaLinkFile.find("/"), ""); // remove loginid@hostnaem:port/
if (metaLinkFile.substr(0, 1) == "/") metaLinkFile.replace(0, 1, ""); // remove the next leading /

std::string cinfofile = "/" + pfn2cache("", metaLinkFile.c_str()) + ".cinfo";
std::string cinfofile = "/" + pfn2cache("", gLFNprefix, metaLinkFile.c_str()) + ".cinfo";
metaLinkFile = localMetaLinkRootDir + "/" + metaLinkFile + ".metalink";

metaLinkDir = metaLinkFile;
Expand Down Expand Up @@ -230,11 +233,11 @@ std::string getMetaLink(XrdSysError* eDest, const std::string myName, const std:

std::string cinfofile;

cinfofile = "/atlas/rucio/" + slashScope + "/"
cinfofile = gLFNprefix + "/" + slashScope + "/"
+ tmp.substr(0, 2) + "/" + tmp.substr(2, 2) + "/"
+ file + ".cinfo";

metaLinkDir = localMetaLinkRootDir + "/atlas/rucio/" + slashScope + "/"
metaLinkDir = localMetaLinkRootDir + gLFNprefix + "/" + slashScope + "/"
+ tmp.substr(0, 2) + "/" + tmp.substr(2, 2);
if (mkdir_p(metaLinkDir))
{
Expand Down
2 changes: 1 addition & 1 deletion rucioGetMetaLink.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

#include "XrdSys/XrdSysError.hh"

void rucioGetMetaLinkInit(const std::string, const std::string);
void rucioGetMetaLinkInit(const std::string, const std::string, const std::string, const std::string);
string getMetaLink(XrdSysError*, const std::string, const std::string);
string makeMetaLink(XrdSysError*, const std::string, const std::string);

0 comments on commit 01c92d1

Please sign in to comment.