diff --git a/src/XrdOss/XrdOssApi.hh b/src/XrdOss/XrdOssApi.hh index bb5ebc97bdc..7cc39fe41df 100644 --- a/src/XrdOss/XrdOssApi.hh +++ b/src/XrdOss/XrdOssApi.hh @@ -242,6 +242,9 @@ int Trace; // Trace flags int Solitary; // True if running in stand-alone mode int OptFlags; // General option flags +XrdOucPListAnchor SPList; // The path to space list +#define spAssign 1 + char *N2N_Lib; // -> Name2Name Library Path char *N2N_Parms; // -> Name2Name Object Parameters XrdOucName2Name *lcl_N2N; // -> File mapper for local files @@ -325,7 +328,7 @@ int Stage_RT(const char *, const char *, XrdOucEnv &, unsigned lo void ConfigMio(XrdSysError &Eroute); int ConfigN2N(XrdSysError &Eroute, XrdOucEnv *envP); int ConfigProc(XrdSysError &Eroute); -void ConfigSpace(); +void ConfigSpace(XrdSysError &Eroute); void ConfigSpace(const char *Lfn); void ConfigSpath(XrdSysError &Eroute, const char *Pn, unsigned long long &Fv, int noMSS); @@ -347,6 +350,8 @@ int xnml(XrdOucStream &Config, XrdSysError &Eroute); int xpath(XrdOucStream &Config, XrdSysError &Eroute); int xprerd(XrdOucStream &Config, XrdSysError &Eroute); int xspace(XrdOucStream &Config, XrdSysError &Eroute, int *isCD=0); +int xspace(XrdOucStream &Config, XrdSysError &Eroute, + const char *grp, bool isAsgn); int xspaceBuild(char *grp, char *fn, int isxa, XrdSysError &Eroute); int xstg(XrdOucStream &Config, XrdSysError &Eroute); int xstl(XrdOucStream &Config, XrdSysError &Eroute); diff --git a/src/XrdOss/XrdOssConfig.cc b/src/XrdOss/XrdOssConfig.cc index 84ebdfa96d2..889f0c6ce54 100644 --- a/src/XrdOss/XrdOssConfig.cc +++ b/src/XrdOss/XrdOssConfig.cc @@ -316,7 +316,7 @@ int XrdOssSys::Configure(const char *configfn, XrdSysError &Eroute, // Configure space (final pass) // - ConfigSpace(); + ConfigSpace(Eroute); // Set the prefix for files in cache file systems if ( OptFlags & XrdOss_CacheFS ) @@ -426,6 +426,13 @@ void XrdOssSys::Config_Display(XrdSysError &Eroute) {List_Path(" oss.path ", fp->Path(), fp->Flag(), Eroute); fp = fp->Next(); } + fp = SPList.First(); + while(fp) + {Eroute.Say(" oss.space ", fp->Name(), + (fp->Attr() == spAssign ? " assign " : " default "), + fp->Path()); + fp = fp->Next(); + } } /******************************************************************************/ @@ -570,7 +577,7 @@ int XrdOssSys::ConfigProc(XrdSysError &Eroute) /* C o n f i g S p a c e */ /******************************************************************************/ -void XrdOssSys::ConfigSpace() +void XrdOssSys::ConfigSpace(XrdSysError &Eroute) { XrdOucPList *fp = RPList.First(); int noCacheFS = !(OptFlags & XrdOss_CacheFS); @@ -585,6 +592,25 @@ void XrdOssSys::ConfigSpace() ConfigSpace(fp->Path()); fp = fp->Next(); } + +// If there is a space list then verify it +// + if ((fp = SPList.First())) + {XrdOssCache_Group *fsg; + const char *what; + bool zAssign = false; + while(fp) + {if (fp->Attr() != spAssign) what = "default space "; + else {zAssign = true; what = "assign space ";} + const char *grp = fp->Name(); + fsg = XrdOssCache_Group::fsgroups; + while(fsg) {if (!strcmp(fsg->group,grp)) break; fsg = fsg->next;} + if (!fsg) Eroute.Say("Config warning: unable to ", what, grp, + " to ", fp->Path(), "; space not defined."); + fp = fp->Next(); + } + if (zAssign) SPList.Default(static_cast(spAssign)); + } } /******************************************************************************/ @@ -1436,6 +1462,7 @@ int XrdOssSys::xprerd(XrdOucStream &Config, XrdSysError &Eroute) /* Function: xspace Purpose: To parse the directive: space + or: space {assign}default} [...] logical name for the filesystem. path to the filesystem. @@ -1454,6 +1481,7 @@ int XrdOssSys::xspace(XrdOucStream &Config, XrdSysError &Eroute, int *isCD) struct dirent *dp; struct stat buff; DIR *DFD; + bool isAsgn; // Get the space name // @@ -1468,6 +1496,11 @@ int XrdOssSys::xspace(XrdOucStream &Config, XrdSysError &Eroute, int *isCD) if (!(val = Config.GetWord())) {Eroute.Emsg("Config", "space path not specified"); return 1;} +// Check if assignment +// + if (((isAsgn = !strcmp("assign",val)) || ! strcmp("default",val)) && !isCD) + return xspace(Config, Eroute, grp, isAsgn); + k = strlen(val); if (k >= (int)(sizeof(fn)-1) || val[0] != '/' || k < 2) {Eroute.Emsg("Config", "invalid space path - ", val); return 1;} @@ -1526,6 +1559,36 @@ int XrdOssSys::xspace(XrdOucStream &Config, XrdSysError &Eroute, int *isCD) return rc != 0; } +/******************************************************************************/ + +int XrdOssSys::xspace(XrdOucStream &Config, XrdSysError &Eroute, + const char *grp, bool isAsgn) +{ + XrdOucPList *pl; + char *path; + +// Get the path +// + path = Config.GetWord(); + if (!path || !path[0]) + {Eroute.Emsg("Config", "space path not specified"); return 1;} + +// Create a new path list object and add it to list of paths +// +do{if ((pl = SPList.Match(path))) pl->Set(path, grp); + else {pl = new XrdOucPList(path, grp); + SPList.Insert(pl); + } + pl->Set((isAsgn ? spAssign : 0)); + } while((path = Config.GetWord())); + +// All done +// + return 0; +} + +/******************************************************************************/ + int XrdOssSys::xspaceBuild(char *grp, char *fn, int isxa, XrdSysError &Eroute) { XrdOssCache_FS::FSOpts fopts = (isxa ? XrdOssCache_FS::isXA diff --git a/src/XrdOss/XrdOssCreate.cc b/src/XrdOss/XrdOssCreate.cc index 3aab5e0094b..bb76a283105 100644 --- a/src/XrdOss/XrdOssCreate.cc +++ b/src/XrdOss/XrdOssCreate.cc @@ -83,10 +83,11 @@ class XrdOssCreateInfo {public: unsigned long long pOpts; const char *Path; + const char *LFN; mode_t Amode; int cOpts; - XrdOssCreateInfo(const char *path, mode_t amode, int opts) - : Path(path), Amode(amode), cOpts(opts) {} + XrdOssCreateInfo(const char *path, const char *lfn, mode_t amode, int opts) + : Path(path), LFN(lfn), Amode(amode), cOpts(opts) {} ~XrdOssCreateInfo() {} }; @@ -117,7 +118,7 @@ int XrdOssSys::Create(const char *tident, const char *path, mode_t access_mode, char local_path[MAXPATHLEN+1], *p, pc; unsigned long long remotefs; int isLink = 0, Missing = 1, retc = 0, datfd; - XrdOssCreateInfo crInfo(local_path, access_mode, Opts); + XrdOssCreateInfo crInfo(local_path, path, access_mode, Opts); struct stat buf; // Get options associated with this path and check if it's r/w @@ -228,6 +229,7 @@ int XrdOssSys::Alloc_Cache(XrdOssCreateInfo &crInfo, XrdOucEnv &env) { EPNAME("Alloc_Cache") int datfd, rc; + const char *spName; char pbuff[MAXPATHLEN+1], cgbuff[XrdOssSpace::minSNbsz], *tmp; XrdOssCache::allocInfo aInfo(crInfo.Path, pbuff, sizeof(pbuff)); @@ -237,9 +239,17 @@ int XrdOssSys::Alloc_Cache(XrdOssCreateInfo &crInfo, XrdOucEnv &env) && XrdOuca2x::a2sz(OssEroute,"invalid asize",tmp,&aInfo.cgSize,0)) return -XRDOSS_E8018; +// Determine the space we should use for this allocation +// + spName = env.Get(OSS_CGROUP); + if (!spName || (SPList.NotEmpty() && SPList.Default() == spAssign)) + {XrdOucPList *pl = SPList.About(crInfo.LFN); + if (pl && (!spName || pl->Attr() == spAssign)) spName = pl->Name(); + } + // Get the correct cache group and partition path // - if ((aInfo.cgPath=XrdOssCache::Parse(env.Get(OSS_CGROUP),cgbuff,sizeof(cgbuff)))) + if ((aInfo.cgPath=XrdOssCache::Parse(spName,cgbuff,sizeof(cgbuff)))) aInfo.cgPlen = strlen(aInfo.cgPath); // Allocate space in the cache. diff --git a/src/XrdOuc/XrdOucPList.hh b/src/XrdOuc/XrdOucPList.hh index 9786e6d9781..7ebeddb62a5 100644 --- a/src/XrdOuc/XrdOucPList.hh +++ b/src/XrdOuc/XrdOucPList.hh @@ -30,6 +30,7 @@ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ +#include #include #include @@ -39,6 +40,7 @@ public: inline int Attr() {return attrs;} inline unsigned long long Flag() {return flags;} +inline const char *Name() {return name;} inline XrdOucPList *Next() {return next;} inline char *Path() {return path;} inline int Plen() {return pathlen;} @@ -48,10 +50,24 @@ inline int PathOK(const char *pd, const int pl) inline void Set(int aval) {attrs = aval;} inline void Set(unsigned long long fval) {flags = fval;} +inline void Set(const char *pd, const char *pn) + {if (path) free(path); + pathlen = strlen(pd); + int n = strlen(pn) + 1 + pathlen + 1; + path = (char *)malloc(n); + n = snprintf(path, n, "%s", pd); + name = path+pathlen+1; + strcpy(name, pn); // This is safe + } XrdOucPList(const char *pd="", unsigned long long fv=0) : flags(fv), next(0), path(strdup(pd)), pathlen(strlen(pd)), attrs(0) {} + + XrdOucPList(const char *pd, const char *pn) + : next(0), path(0), attrs(0) + {Set(pd, pn);} + ~XrdOucPList() {if (path) free(path);} @@ -59,7 +75,10 @@ friend class XrdOucPListAnchor; private: +union{ unsigned long long flags; +char *name; + }; XrdOucPList *next; char *path; int pathlen; @@ -80,6 +99,8 @@ inline XrdOucPList *About(const char *pathname) } inline void Default(unsigned long long x) {dflts = x;} +inline +unsigned long long Default() {return dflts;} inline void Defstar(unsigned long long x) {dstrs = x;} inline void Empty(XrdOucPList *newlist=0)