XRootD
XrdOfsFSctl.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d O f s F S c t l . c c */
4 /* */
5 /* (c) 2018 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <unistd.h>
31 #include <cerrno>
32 #include <fcntl.h>
33 #include <cstring>
34 #include <cstdio>
35 #include <cstdlib>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 
40 #include "XrdNet/XrdNetIF.hh"
41 
42 #include "XrdOfs/XrdOfs.hh"
43 #include "XrdOfs/XrdOfsFSctl_PI.hh"
44 #include "XrdOfs/XrdOfsTrace.hh"
45 #include "XrdOfs/XrdOfsSecurity.hh"
46 
47 #include "XrdCms/XrdCmsClient.hh"
48 
49 #include "XrdOss/XrdOss.hh"
50 
51 #include "XrdSys/XrdSysError.hh"
52 #include "XrdSys/XrdSysFAttr.hh"
53 #include "XrdSys/XrdSysHeaders.hh"
54 #include "XrdSys/XrdSysPlatform.hh"
55 
56 #include "XrdOuc/XrdOucEnv.hh"
57 #include "XrdOuc/XrdOucERoute.hh"
58 #include "XrdOuc/XrdOucExport.hh"
59 
60 #include "XrdSec/XrdSecEntity.hh"
61 #include "XrdSfs/XrdSfsFAttr.hh"
62 #include "XrdSfs/XrdSfsFlags.hh"
64 
65 #ifdef AIX
66 #include <sys/mode.h>
67 #endif
68 
69 /******************************************************************************/
70 /* E r r o r R o u t i n g O b j e c t */
71 /******************************************************************************/
72 
73 extern XrdSysError OfsEroute;
74 
75 extern XrdSysTrace OfsTrace;
76 
77 /******************************************************************************/
78 /* F i l e S y s t e m O b j e c t */
79 /******************************************************************************/
80 
81 extern XrdOfs* XrdOfsFS;
82 
83 /******************************************************************************/
84 /* S t o r a g e S y s t e m O b j e c t */
85 /******************************************************************************/
86 
87 extern XrdOss *XrdOfsOss;
88 
89 /******************************************************************************/
90 /* f s c t l ( V e r s i o n 1 ) */
91 /******************************************************************************/
92 
93 int XrdOfs::fsctl( int cmd,
94  const char *args,
95  XrdOucErrInfo &einfo,
96  const XrdSecEntity *client)
97 /*
98  Function: Perform filesystem operations:
99 
100  Input: cmd - Operation command (currently supported):
101  SFS_FSCTL_LOCATE - locate file
102  SFS_FSCTL_STATCC - return cluster config status
103  SFS_FSCTL_STATFS - return file system info (physical)
104  SFS_FSCTL_STATLS - return file system info (logical)
105  SFS_FSCTL_STATXA - return file extended attributes
106  arg - Command dependent argument:
107  - Locate: The path whose location is wanted
108  buf - The stat structure to hold the results
109  einfo - Error/Response information structure.
110  client - Authentication credentials, if any.
111 
112  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
113 */
114 {
115  EPNAME("fsctl");
116  static int PrivTab[] = {XrdAccPriv_Delete, XrdAccPriv_Insert,
120  static char PrivLet[] = {'d', 'i',
121  'k', 'l',
122  'n', 'r',
123  'w'};
124  static const int PrivNum = sizeof(PrivLet);
125 
126  int retc, i, blen, privs, opcode = cmd & SFS_FSCTL_CMD;
127  const char *tident = einfo.getErrUser();
128  char *bP, *cP;
129 
130 // Process the LOCATE request
131 //
132  if (opcode == SFS_FSCTL_LOCATE)
133  {static const int locMask = (SFS_O_FORCE|SFS_O_NOWAIT|SFS_O_RESET|
135  struct stat fstat;
136  char pbuff[1024], rType[3];
137  const char *Resp[2] = {rType, pbuff};
138  const char *locArg, *opq, *Path = Split(args,&opq,pbuff,sizeof(pbuff));
139  XrdNetIF::ifType ifType;
140  int Resp1Len;
141  int find_flag = SFS_O_LOCATE | (cmd & locMask);
142  XrdOucEnv loc_Env(opq ? opq+1 : 0,0,client);
143 
144  ZTRACE(fsctl, "locate args=" <<(args ? args : "''"));
145 
146  if (cmd & SFS_O_TRUNC) locArg = (char *)"*";
147  else { if (*Path == '*') {locArg = Path; Path++;}
148  else locArg = Path;
149  AUTHORIZE(client,&loc_Env,AOP_Stat,"locate",Path,einfo);
150  }
151  if (Finder && Finder->isRemote()
152  && (retc = Finder->Locate(einfo, locArg, find_flag, &loc_Env)))
153  return fsError(einfo, retc);
154 
155  if (cmd & SFS_O_TRUNC) {rType[0] = 'S'; rType[1] = ossRW;}
156  else {if ((retc = XrdOfsOss->Stat(Path, &fstat, 0, &loc_Env)))
157  return XrdOfsFS->Emsg(epname, einfo, retc, "locate", Path);
158  rType[0] = ((fstat.st_mode & S_IFBLK) == S_IFBLK ? 's' : 'S');
159  rType[1] = (fstat.st_mode & S_IWUSR ? 'w' : 'r');
160  }
161  rType[2] = '\0';
162 
163  ifType = XrdNetIF::GetIFType((einfo.getUCap() & XrdOucEI::uIPv4) != 0,
164  (einfo.getUCap() & XrdOucEI::uIPv64) != 0,
165  (einfo.getUCap() & XrdOucEI::uPrip) != 0);
166  bool retHN = (cmd & SFS_O_HNAME) != 0;
167  if ((Resp1Len = myIF->GetDest(pbuff, sizeof(pbuff), ifType, retHN)))
168  {einfo.setErrInfo(Resp1Len+3, (const char **)Resp, 2);
169  return SFS_DATA;
170  }
171  return Emsg(epname, einfo, ENETUNREACH, "locate", Path);
172  }
173 
174 // Process the STATFS request
175 //
176  if (opcode == SFS_FSCTL_STATFS)
177  {char pbuff[1024];
178  const char *opq, *Path = Split(args, &opq, pbuff, sizeof(pbuff));
179  XrdOucEnv fs_Env(opq ? opq+1 : 0,0,client);
180  ZTRACE(fsctl, "statfs args=" <<(args ? args : "''"));
181  AUTHORIZE(client,&fs_Env,AOP_Stat,"statfs",Path,einfo);
182  if (Finder && Finder->isRemote()
183  && (retc = Finder->Space(einfo, Path, &fs_Env)))
184  return fsError(einfo, retc);
185  bP = einfo.getMsgBuff(blen);
186  if ((retc = XrdOfsOss->StatFS(Path, bP, blen, &fs_Env)))
187  return XrdOfsFS->Emsg(epname, einfo, retc, "statfs", args);
188  einfo.setErrCode(blen+1);
189  return SFS_DATA;
190  }
191 
192 // Process the STATLS request
193 //
194  if (opcode == SFS_FSCTL_STATLS)
195  {char pbuff[1024];
196  const char *opq, *Path = Split(args, &opq, pbuff, sizeof(pbuff));
197  XrdOucEnv statls_Env(opq ? opq+1 : 0,0,client);
198  ZTRACE(fsctl, "statls args=" <<(args ? args : "''"));
199  AUTHORIZE(client,&statls_Env,AOP_Stat,"statfs",Path,einfo);
200  if (Finder && Finder->isRemote())
201  {statls_Env.Put("cms.qvfs", "1");
202  if ((retc = Finder->Space(einfo, Path, &statls_Env)))
203  {if (retc == SFS_DATA) retc = Reformat(einfo);
204  return fsError(einfo, retc);
205  }
206  }
207  bP = einfo.getMsgBuff(blen);
208  if ((retc = XrdOfsOss->StatLS(statls_Env, Path, bP, blen)))
209  return XrdOfsFS->Emsg(epname, einfo, retc, "statls", Path);
210  einfo.setErrCode(blen+1);
211  return SFS_DATA;
212  }
213 
214 // Process the STATXA request
215 //
216  if (opcode == SFS_FSCTL_STATXA)
217  {char pbuff[1024];
218  const char *opq, *Path = Split(args, &opq, pbuff, sizeof(pbuff));
219  XrdOucEnv xa_Env(opq ? opq+1 : 0,0,client);
220  ZTRACE(fsctl, "statxa args=" <<(args ? args : "''"));
221  AUTHORIZE(client,&xa_Env,AOP_Stat,"statxa",Path,einfo);
222  if (Finder && Finder->isRemote()
223  && (retc = Finder->Locate(einfo,Path,SFS_O_RDONLY|SFS_O_STAT,&xa_Env)))
224  return fsError(einfo, retc);
225  bP = einfo.getMsgBuff(blen);
226  if ((retc = XrdOfsOss->StatXA(Path, bP, blen, &xa_Env)))
227  return XrdOfsFS->Emsg(epname, einfo, retc, "statxa", Path);
228  if (!client || !XrdOfsFS->Authorization) privs = XrdAccPriv_All;
229  else privs = XrdOfsFS->Authorization->Access(client, Path, AOP_Any);
230  cP = bP + blen; strcpy(cP, "&ofs.ap="); cP += 8;
231  if (privs == XrdAccPriv_All) *cP++ = 'a';
232  else {for (i = 0; i < PrivNum; i++)
233  if (PrivTab[i] & privs) *cP++ = PrivLet[i];
234  if (cP == (bP + blen + 1)) *cP++ = '?';
235  }
236  *cP++ = '\0';
237  einfo.setErrCode(cP-bP+1);
238  return SFS_DATA;
239  }
240 
241 // Process the STATCC request (this should always succeed)
242 //
243  if (opcode == SFS_FSCTL_STATCC)
244  {static const int lcc_flag = SFS_O_LOCATE | SFS_O_LOCAL;
245  XrdOucEnv lcc_Env(0,0,client);
246  ZTRACE(fsctl, "statcc args=" <<(args ? args : "''"));
247  if (Finder) retc = Finder ->Locate(einfo,".",lcc_flag,&lcc_Env);
248  else if (Balancer) retc = Balancer->Locate(einfo,".",lcc_flag,&lcc_Env);
249  else retc = SFS_ERROR;
250  if (retc != SFS_DATA) einfo.setErrInfo(5, "none|");
251  return fsError(einfo, SFS_DATA);
252  }
253 
254 // Operation is not supported
255 //
256  return XrdOfsFS->Emsg(epname, einfo, ENOTSUP, "fsctl", args);
257 }
258 
259 /******************************************************************************/
260 /* F S c t l ( V e r s i o n 2 ) */
261 /******************************************************************************/
262 
263 int XrdOfs::FSctl(const int cmd,
264  XrdSfsFSctl &args,
265  XrdOucErrInfo &eInfo,
266  const XrdSecEntity *client)
267 {
268  EPNAME("FSctl");
269 
270 // If this is the cache-specfic we need to do a lot more work. Otherwise this
271 // is a simple case of wheter we have a plug-in for this or not.
272 //
273  if (cmd == SFS_FSCTL_PLUGXC)
274  {if (FSctl_PC)
275  {if (args.Arg2Len == -2)
276  {XrdOucEnv pc_Env(args.ArgP[1] ? args.ArgP[1] : 0, 0, client);
277  AUTHORIZE(client,&pc_Env,AOP_Read,"FSctl",args.ArgP[0],eInfo);
278  }
279  return FSctl_PC->FSctl(cmd, args, eInfo, client);
280  }
281  }
282  else if (FSctl_PI) return FSctl_PI->FSctl(cmd, args, eInfo, client);
283 
284 // Operation is not supported
285 //
286  return XrdOfsFS->Emsg("FSctl", eInfo, ENOTSUP, "FSctl", "");
287 }
288 
289 /******************************************************************************/
290 /* F S c t l f i l e */
291 /******************************************************************************/
292 
293 int XrdOfs::FSctl(XrdOfsFile &file, const int cmd, int alen, const char *args,
294  const XrdSecEntity *client)
295 {
296 // Supported only if we have a plugin for this
297 //
298  if (FSctl_PI) return FSctl_PI->FSctl(cmd,alen,args,file,file.error,client);
299 
300 // No Go
301 //
302  file.error.setErrInfo(ENOTSUP, "fctl operation not supported");
303  return SFS_ERROR;
304 }
@ AOP_Any
Special for getting privs.
@ AOP_Stat
exists(), stat()
@ AOP_Read
open() r/o, prepare()
@ XrdAccPriv_Insert
Definition: XrdAccPrivs.hh:44
@ XrdAccPriv_Lookup
Definition: XrdAccPrivs.hh:47
@ XrdAccPriv_Rename
Definition: XrdAccPrivs.hh:48
@ XrdAccPriv_All
Definition: XrdAccPrivs.hh:39
@ XrdAccPriv_Read
Definition: XrdAccPrivs.hh:49
@ XrdAccPriv_Lock
Definition: XrdAccPrivs.hh:45
@ XrdAccPriv_Write
Definition: XrdAccPrivs.hh:51
@ XrdAccPriv_Delete
Definition: XrdAccPrivs.hh:43
#define tident
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define ZTRACE(act, x)
Definition: XrdBwmTrace.hh:52
XrdOss * XrdOfsOss
Definition: XrdOfs.cc:163
XrdSysTrace OfsTrace
XrdSysError OfsEroute
XrdOfs * XrdOfsFS
Definition: XrdOfsFS.cc:47
#define AUTHORIZE(usr, env, optype, action, pathp, edata)
int fstat(int fildes, struct stat *buf)
XrdOucString Path
#define SFS_O_HNAME
#define SFS_DATA
int Arg2Len
Length or -count of args in extension.
#define SFS_O_RESET
#define SFS_O_DIRLIST
#define SFS_FSCTL_STATFS
#define SFS_O_STAT
#define SFS_ERROR
#define SFS_O_FORCE
#define SFS_FSCTL_CMD
#define SFS_O_RDONLY
#define SFS_FSCTL_STATLS
#define SFS_FSCTL_STATCC
#define SFS_O_LOCATE
#define SFS_FSCTL_STATXA
#define SFS_FSCTL_LOCATE
#define SFS_O_RAWIO
#define SFS_O_LOCAL
#define SFS_O_NOWAIT
#define SFS_FSCTL_PLUGXC
#define SFS_O_TRUNC
< SFS_FSCTL_PLUGIN/PLUGIO/PLUGXC parms
virtual XrdAccPrivs Access(const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env=0)=0
virtual int isRemote()
virtual int Space(XrdOucErrInfo &Resp, const char *path, XrdOucEnv *Info=0)=0
virtual int Locate(XrdOucErrInfo &Resp, const char *path, int flags, XrdOucEnv *Info=0)=0
static ifType GetIFType(bool conIPv4, bool hasIP64, bool pvtIP)
Definition: XrdNetIF.hh:250
int GetDest(char *dest, int dlen, ifType ifT=PublicV6, bool prefn=false)
Definition: XrdNetIF.cc:389
ifType
The enum that is used to index into ifData to get appropriate interface.
Definition: XrdNetIF.hh:65
virtual int FSctl(const int cmd, int alen, const char *args, XrdSfsFile &file, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)=0
const char * Split(const char *Args, const char **Opq, char *Path, int Plen)
Definition: XrdOfs.cc:2685
XrdCmsClient * Finder
Definition: XrdOfs.hh:429
int fsctl(const int cmd, const char *args, XrdOucErrInfo &out_error, const XrdSecEntity *client=0)
Definition: XrdOfsFSctl.cc:93
static int Emsg(const char *, XrdOucErrInfo &, int, const char *x, XrdOfsHandle *hP)
Definition: XrdOfs.cc:2513
XrdNetIF * myIF
Definition: XrdOfs.hh:394
static int fsError(XrdOucErrInfo &myError, int rc)
Definition: XrdOfs.cc:2628
int FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)
Definition: XrdOfsFSctl.cc:263
int stat(const char *Name, struct stat *buf, XrdOucErrInfo &out_error, const XrdSecEntity *client, const char *opaque=0)
Definition: XrdOfs.cc:2361
virtual int StatLS(XrdOucEnv &env, const char *path, char *buff, int &blen)
Definition: XrdOss.cc:97
virtual int StatXA(const char *path, char *buff, int &blen, XrdOucEnv *envP=0)
Definition: XrdOss.cc:127
virtual int StatFS(const char *path, char *buff, int &blen, XrdOucEnv *envP=0)
Definition: XrdOss.cc:87
virtual int Stat(const char *path, struct stat *buff, int opts=0, XrdOucEnv *envP=0)=0
void Put(const char *varname, const char *value)
Definition: XrdOucEnv.hh:85
int setErrInfo(int code, const char *emsg)
char * getMsgBuff(int &mblen)
const char * getErrUser()
int setErrCode(int code)
XrdOucErrInfo & error
static const int uIPv64
ucap: Supports only IPv4 info
static const int uIPv4
ucap: Supports read redirects
static const int uPrip