30 #define _FILE_OFFSET_BITS 64
34 #include <sys/types.h>
36 #if !defined(__solaris__) && !defined(__FreeBSD__)
37 #include <sys/xattr.h>
41 #define ENOATTR ENODATA
64 #define MAXROOTURLLEN 1024
71 if (rc == 0 && S_ISBLK(buf->st_mode))
73 buf->st_mode &= 0007777;
74 if ( buf->st_mode & S_IXUSR )
75 buf->st_mode |= 0040000;
77 buf->st_mode |= 0100000;
100 std::string dir = url.
GetPath();
105 std::unique_ptr<XrdCl::LocationInfo> ptr( info );
112 std::string nodeUrl =
"root://" + info->
At(0).
GetAddress() +
"/" + dir;
184 char xattrbuf[1024], nameclass[128], *namesubclass;
185 char *token, *key, *val;
186 char *lasts_xattr[256], *lasts_tokens[128];
192 strncpy(nameclass, name, 11);
193 nameclass[11] =
'\0';
195 if (strcmp(nameclass,
"xroot.space") != 0 &&
196 strcmp(nameclass,
"xroot.xattr") != 0 &&
197 strcmp(nameclass,
"xroot.cksum") != 0)
204 if (bufsize == -1)
return -1;
206 if (strlen(name) > 11)
208 strcpy(nameclass, name);
209 namesubclass = &nameclass[12];
213 strcpy((
char*)value, xattrbuf);
217 token = strtok_r(xattrbuf,
"&", lasts_xattr);
218 while ( token != NULL )
220 key = strtok_r(token,
"=", lasts_tokens);
221 val = strtok_r(NULL,
"=", lasts_tokens);
222 if (! strcmp(key, namesubclass))
224 strcpy((
char*)value, val);
227 token = strtok_r(NULL,
"&", lasts_xattr);
238 fd =
XrdFfsPosix_open(rdrurl, O_CREAT | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
261 else if (S_ISDIR(args->
st_mode))
264 *(args->
err) = errno;
279 for (i = 0; i < nurls; i++)
282 strncat(newurls[i],path,
MAXROOTURLLEN - strlen(newurls[i]) -1);
284 args[i].url = newurls[i];
285 args[i].err = &errno_i[i];
286 args[i].res = &res_i[i];
287 args[i].st_mode = st_mode;
294 for (i = 0; i < nurls; i++)
302 for (i = 0; i < nurls; i++)
308 else if (res_i[i] != 0 && errno_i[i] == 125)
312 syslog(LOG_WARNING,
"WARNING: unlink/rmdir(%s) failed (connection timeout)", newurls[i]);
315 else if (res_i[i] != 0 && errno_i[i] != ENOENT)
319 syslog(LOG_WARNING,
"WARNING: unlink/rmdir(%s) failed (errno = %d)", newurls[i], errno);
323 for (i = 0; i < nurls; i++)
341 int i, nurls, res, rval = 0;
346 if (nurls < 0) rval = -1;
348 for (i = 0; i < nurls; i++)
353 strcat(fromurl, newurls[i]);
356 strcat(tourl, newurls[i]);
375 syslog(LOG_WARNING,
"WARNING: rename(%s, %s) failed (errno = %d)", fromurl, tourl, errno);
383 for (i = 0; i < nurls; i++)
386 if (rval != 0 && errno == 0) errno = EIO;
392 int i, nurls, res, rval = 0;
397 if (nurls < 0) rval = -1;
399 for (i = 0; i < nurls; i++)
402 strncat(newurls[i],path,
MAXROOTURLLEN - strlen(newurls[i]) -1);
407 if (S_ISREG(stbuf.st_mode))
413 syslog(LOG_WARNING,
"WARNING: (f)truncate(%s) failed (errno = %d)", newurls[i], errno);
418 else if (errno != ENOENT)
422 for (i = 0; i < nurls; i++)
425 if (rval != 0 && errno == 0) errno = EIO;
457 if ( dp == NULL && errno != 0)
459 *(args->
err) = errno;
476 int i, j, n, nents, nurls;
477 bool hasDirLock =
false;
503 errno = (nurls == 0? ENOENT : EACCES);
507 for (i = 0; i < nurls; i++)
510 strncat(newurls[i], path,
MAXROOTURLLEN - strlen(newurls[i]) -1);
512 args[i].url = newurls[i];
513 args[i].err = &errno_i[i];
514 args[i].res = &res_i[i];
515 args[i].dents = &dir_i[i];
522 for (i = 0; i < nurls; i++)
530 for (i = 0; i < nurls; i++)
531 if (res_i[i] != 0 && errno_i[i] == 125)
534 syslog(LOG_WARNING,
"WARNING: opendir(%s) failed (connection timeout)", newurls[i]);
538 for (i = 0; i < nurls; i++)
540 for (i = 1; i < nurls; i++)
543 char *last = NULL, **dnarraytmp;
546 *direntarray = (
char **) malloc(
sizeof(
char*) * n);
551 for (i = 0; i < n; i++)
555 if (! strcmp(dnarraytmp[i],
"DIR_LOCK"))
564 tmp = strdup(dnarraytmp[i]);
565 tmp_dot = tmp + strlen(tmp) - 5;
567 if (! strcmp(tmp_dot,
".lock") || ! strcmp(tmp_dot,
".fail"))
569 for (j = nents - 1; j >= 0; j--)
572 if (! strcmp(tmp, (*direntarray)[j]))
579 if (j >= 0)
continue;
584 if (last == NULL || strcmp(last, dnarraytmp[i]) != 0)
586 last = dnarraytmp[i];
587 (*direntarray)[nents++] = strdup(dnarraytmp[i]);
591 for (i = 0; i < n; i++) free(dnarraytmp[i]);
601 if (hasDirLock) (*direntarray)[nents++] = strdup(
"DIR_LOCK");
627 *(args->
err) = errno;
628 sscanf((
const char*)xattr,
"%lld", &llVal);
629 oss_size =
static_cast<off_t
>(llVal);
630 args->
stbuf->f_blocks = (fsblkcnt_t) (oss_size / args->
stbuf->f_bsize);
632 if (*(args->
res) == -1)
634 args->
stbuf->f_blocks = 0;
635 args->
stbuf->f_bavail = 0;
636 args->
stbuf->f_bfree = 0;
640 *(args->
err) = errno;
641 sscanf((
const char*)xattr,
"%lld", &llVal);
642 oss_size =
static_cast<off_t
>(llVal);
643 args->
stbuf->f_bavail = (fsblkcnt_t) (oss_size / args->
stbuf->f_bsize);
645 if (*(args->
res) == -1)
647 args->
stbuf->f_blocks = 0;
648 args->
stbuf->f_bavail = 0;
649 args->
stbuf->f_bfree = 0;
668 *(args->
err) = errno;
669 sscanf((
const char*)xattr,
"%lld", &llVal);
670 oss_size =
static_cast<off_t
>(llVal);
671 args->
stbuf->f_bfree = args->
stbuf->f_blocks - (fsblkcnt_t) (oss_size / args->
stbuf->f_bsize);
696 if (strstr(path,
"oss.cgroup") != NULL)
700 for (i = 0; i < nurls; i++)
702 strncat(newurls[i], path,
MAXROOTURLLEN - strlen(newurls[i]) -1);
704 args[i].url = newurls[i];
705 args[i].res = &res_i[i];
706 args[i].err = &errno_i[i];
707 stbuf_i[i].f_bsize = stbuf->f_bsize;
708 args[i].stbuf = &(stbuf_i[i]);
709 args[i].osscgroup = osscgroup;
716 for (i = 0; i < nurls; i++)
728 for (i = 0; i < nurls; i++)
730 stbuf->f_blocks +=
args[i].stbuf->f_blocks;
731 stbuf->f_bavail +=
args[i].stbuf->f_bavail;
732 stbuf->f_bfree +=
args[i].stbuf->f_bfree;
735 for (i = 0; i < nurls; i++)
755 *(args->
err) = errno;
773 strncat(rootpath,rdrurl,
MAXROOTURLLEN - strlen(rootpath) -1);
800 for (i = 0; i < nurls; i++)
804 args[i].url = newurls[i];
805 args[i].res = &res_i[i];
806 args[i].err = &errno_i[i];
807 args[i].stbuf = &(stbuf_i[i]);
814 for (i = 0; i < nurls; i++)
822 for (i = 0; i < nurls; i++)
824 time_t max_mtime = 0;
827 if (stbuf_i[i].st_mtime <= max_mtime)
continue;
830 memcpy((
void*)stbuf, (
void*)(&stbuf_i[i]),
sizeof(
struct stat));
833 else if (res_i[i] != 0 && errno_i[i] == 125)
837 syslog(LOG_WARNING,
"WARNING: stat(%s) failed (connection timeout)", newurls[i]);
841 for (i = 0; i < nurls; i++)
int XrdFfsDent_cache_search(char *dname, char *dentname)
void XrdFfsDent_names_join(struct XrdFfsDentnames **p, struct XrdFfsDentnames **n)
void XrdFfsDent_names_add(struct XrdFfsDentnames **p, char *name)
int XrdFfsDent_cache_fill(char *dname, char ***dnarray, int nents)
int XrdFfsDent_names_extract(struct XrdFfsDentnames **p, char ***dnarray)
int XrdFfsMisc_get_number_of_data_servers()
void XrdFfsMisc_xrd_secsss_editurl(char *url, uid_t user_uid, int *id)
int XrdFfsMisc_get_all_urls(const char *oldurl, char **newurls, const int nnodes)
#define XrdFfs_MAX_NUM_NODES
int XrdFfsPosix_ftruncate(int fildes, off_t offset)
int XrdFfsPosix_rmdirall(const char *rdrurl, const char *path, uid_t user_uid)
int XrdFfsPosix_rename(const char *oldpath, const char *newpath)
DIR * XrdFfsPosix_opendir(const char *path)
int XrdFfsPosix_open(const char *path, int oflags, mode_t mode)
int XrdFfsPosix_fsync(int fildes)
int XrdFfsPosix_unlink(const char *path)
void * XrdFfsPosix_x_statvfsall(void *x)
int XrdFfsPosix_renameall(const char *rdrurl, const char *from, const char *to, uid_t user_uid)
void XrdFfsPosix_clear_from_rdr_cache(const char *rdrurl)
int XrdFfsPosix_truncate(const char *path, off_t Size)
ssize_t XrdFfsPosix_pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
void * XrdFfsPosix_x_readdirall(void *x)
int XrdFfsPosix_truncateall(const char *rdrurl, const char *path, off_t size, uid_t user_uid)
ssize_t XrdFfsPosix_read(int fildes, void *buf, size_t nbyte)
int XrdFfsPosix_closedir(DIR *dirp)
int XrdFfsPosix_rmdir(const char *path)
struct dirent * XrdFfsPosix_readdir(DIR *dirp)
void * XrdFfsPosix_x_statall(void *x)
off_t XrdFfsPosix_lseek(int fildes, off_t offset, int whence)
int XrdFfsPosix_close(int fildes)
ssize_t XrdFfsPosix_pread(int fildes, void *buf, size_t nbyte, off_t offset)
int XrdFfsPosix_statvfsall(const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
int XrdFfsPosix_deleteall(const char *rdrurl, const char *path, uid_t user_uid, mode_t st_mode)
struct XrdFfsDentnames ** dents
int XrdFfsPosix_readdirall(const char *rdrurl, const char *path, char ***direntarray, uid_t user_uid)
int XrdFfsPosix_statall(const char *rdrurl, const char *path, struct stat *stbuf, uid_t user_uid)
int XrdFfsPosix_unlinkall(const char *rdrurl, const char *path, uid_t user_uid)
int XrdFfsPosix_stat(const char *path, struct stat *buf)
int XrdFfsPosix_mkdir(const char *path, mode_t mode)
void * XrdFfsPosix_x_deleteall(void *x)
long long XrdFfsPosix_getxattr(const char *path, const char *name, void *value, unsigned long long size)
ssize_t XrdFfsPosix_write(int fildes, const void *buf, size_t nbyte)
void XrdFfsQueue_free_task(struct XrdFfsQueueTasks *task)
struct XrdFfsQueueTasks * XrdFfsQueue_create_task(void *(*func)(void *), void **args, short initstat)
unsigned int XrdFfsQueue_count_tasks()
void XrdFfsQueue_wait_task(struct XrdFfsQueueTasks *task)
int stat(const char *path, struct stat *buf)
int statvfs(const char *path, struct statvfs *buf)
Send file/filesystem queries to an XRootD cluster.
XRootDStatus DeepLocate(const std::string &path, OpenFlags::Flags flags, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
const std::string & GetAddress() const
Get address.
Location & At(uint32_t index)
Get the location at index.
const std::string & GetPath() const
Get the path.
static ssize_t Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Pread() conforms to POSIX.1-2001 pread()
static int Closedir(DIR *dirp)
Closedir() conforms to POSIX.1-2001 closedir()
static int Stat(const char *path, struct stat *buf)
Stat() conforms to POSIX.1-2001 stat()
static int Mkdir(const char *path, mode_t mode)
Mkdir() conforms to POSIX.1-2001 mkdir()
static int Unlink(const char *path)
Unlink() conforms to POSIX.1-2001 unlink()
static int Rmdir(const char *path)
Rmdir() conforms to POSIX.1-2001 rmdir()
static int Rename(const char *oldpath, const char *newpath)
Rename() conforms to POSIX.1-2001 rename()
static int Close(int fildes)
Close() conforms to POSIX.1-2001 close()
static ssize_t Write(int fildes, const void *buf, size_t nbyte)
Write() conforms to POSIX.1-2001 write()
static struct dirent * Readdir(DIR *dirp)
static int Ftruncate(int fildes, off_t offset)
Ftruncate() conforms to POSIX.1-2001 ftruncate()
static DIR * Opendir(const char *path)
Opendir() conforms to POSIX.1-2001 opendir()
static int Fsync(int fildes)
Fsync() conforms to POSIX.1-2001 fsync()
static long long Getxattr(const char *path, const char *name, void *value, unsigned long long size)
static ssize_t Read(int fildes, void *buf, size_t nbyte)
Read() conforms to POSIX.1-2001 read()
static off_t Lseek(int fildes, off_t offset, int whence)
Lseek() conforms to POSIX.1-2001 lseek()
static int Open(const char *path, int oflag, mode_t mode=0, XrdPosixCallBack *cbP=0)
static ssize_t Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Pwrite() conforms to POSIX.1-2001 pwrite()
static int Truncate(const char *path, off_t offset)
Telldir() conforms to POSIX.1-2001 telldir()
static INT to(const char *buffer)
bool IsOK() const
We're fine.