XRootD
Loading...
Searching...
No Matches
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"
44#include "XrdOfs/XrdOfsTrace.hh"
46
48
49#include "XrdOss/XrdOss.hh"
50
51#include "XrdSys/XrdSysError.hh"
52#include "XrdSys/XrdSysFAttr.hh"
55
56#include "XrdOuc/XrdOucEnv.hh"
59
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
74
76
77/******************************************************************************/
78/* F i l e S y s t e m O b j e c t */
79/******************************************************************************/
80
81extern 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
87extern XrdOss *XrdOfsOss;
88
89/******************************************************************************/
90/* f s c t l ( V e r s i o n 1 ) */
91/******************************************************************************/
92
93int 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
263int 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
293int 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
@ XrdAccPriv_Lookup
@ XrdAccPriv_Rename
@ XrdAccPriv_All
@ XrdAccPriv_Read
@ XrdAccPriv_Lock
@ XrdAccPriv_Write
@ XrdAccPriv_Delete
#define tident
#define EPNAME(x)
#define ZTRACE(act, x)
#define AUTHORIZE(usr, env, optype, action, pathp, edata)
XrdSysError OfsEroute(0)
XrdSysTrace OfsTrace("ofs")
XrdOss * XrdOfsOss
Definition XrdOfs.cc:163
XrdOfs * XrdOfsFS
Definition XrdOfsFS.cc:47
#define fstat(a, b)
Definition XrdPosix.hh:62
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
static ifType GetIFType(bool conIPv4, bool hasIP64, bool pvtIP)
Definition XrdNetIF.hh:204
ifType
The enum that is used to index into ifData to get appropriate interface.
Definition XrdNetIF.hh:64
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:2686
XrdCmsClient * Finder
Definition XrdOfs.hh:429
int fsctl(const int cmd, const char *args, XrdOucErrInfo &out_error, const XrdSecEntity *client=0)
static int Emsg(const char *, XrdOucErrInfo &, int, const char *x, XrdOfsHandle *hP)
Definition XrdOfs.cc:2514
XrdNetIF * myIF
Definition XrdOfs.hh:394
static int fsError(XrdOucErrInfo &myError, int rc)
Definition XrdOfs.cc:2629
int FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0)
int stat(const char *Name, struct stat *buf, XrdOucErrInfo &out_error, const XrdSecEntity *client, const char *opaque=0)
Definition XrdOfs.cc:2362
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
const char * getErrUser()
char * getMsgBuff(int &mblen)
int setErrInfo(int code, const char *emsg)
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