|
21 | 21 | #include "TPluginManager.h" |
22 | 22 | #include "TROOT.h" |
23 | 23 |
|
| 24 | +// XRootD protocol redirection |
| 25 | +#ifdef R__UNIX |
| 26 | + |
| 27 | +#ifdef R__FBSD |
| 28 | +#include <sys/extattr.h> |
| 29 | +#else |
| 30 | +#include <sys/xattr.h> |
| 31 | +#endif |
| 32 | + |
| 33 | +#ifdef R__MACOSX |
| 34 | +/* On macOS getxattr takes two extra arguments that should be set to 0 */ |
| 35 | +#define getxattr(path, name, value, size) getxattr(path, name, value, size, 0u, 0) |
| 36 | +#endif |
| 37 | + |
| 38 | +#ifdef R__FBSD |
| 39 | +#define getxattr(path, name, value, size) extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, value, size) |
| 40 | +#endif |
| 41 | + |
| 42 | +#include "TEnv.h" |
| 43 | + |
| 44 | +#endif |
| 45 | + |
24 | 46 | #include <algorithm> |
25 | 47 | #include <cctype> // for towlower |
26 | 48 | #include <cerrno> |
@@ -68,6 +90,23 @@ ROOT::Internal::RRawFile::Create(std::string_view url, ROptions options) |
68 | 90 | #ifdef _WIN32 |
69 | 91 | return std::unique_ptr<RRawFile>(new RRawFileWin(url, options)); |
70 | 92 | #else |
| 93 | + // If URL is a file on an EOS FUSE mount, attempt redirection to XRootD protocol. |
| 94 | + if (gEnv->GetValue("TFile.CrossProtocolRedirects", 1) == 1) { |
| 95 | + // At the moment the url parameter can only be the file name |
| 96 | + ssize_t len = getxattr(url.data(), "eos.url.xroot", nullptr, 0); |
| 97 | + if (len > 0) { |
| 98 | + std::string xurl(len, 0); |
| 99 | + std::string fileNameFromUrl{url.data()}; |
| 100 | + if (getxattr(fileNameFromUrl.c_str(), "eos.url.xroot", &xurl[0], len) == len) { |
| 101 | + // Sometimes the `getxattr` call may return an invalid URL due |
| 102 | + // to the POSIX attribute not being yet completely filled by EOS. |
| 103 | + if (auto baseName = fileNameFromUrl.substr(fileNameFromUrl.find_last_of("/") + 1); |
| 104 | + std::equal(baseName.crbegin(), baseName.crend(), xurl.crbegin())) { |
| 105 | + return Create(xurl, options); |
| 106 | + } |
| 107 | + } |
| 108 | + } |
| 109 | + } |
71 | 110 | return std::unique_ptr<RRawFile>(new RRawFileUnix(url, options)); |
72 | 111 | #endif |
73 | 112 | } |
|
0 commit comments