30 #define FUSE_USE_VERSION 26
37 #if defined(__linux__)
40 #define _XOPEN_SOURCE 500
45 #include <fuse/fuse_opt.h>
57 #if defined(__linux__)
58 #include <sys/prctl.h>
60 #include <sys/xattr.h>
70 #define MAXROOTURLLEN 1024
95 struct passwd pw, *pwp;
100 rl.rlim_cur = RLIM_INFINITY;
101 rl.rlim_max = RLIM_INFINITY;
102 setrlimit(RLIMIT_CORE, &rl);
104 pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
105 pwbuf = (
char*)malloc(pwbuflen + 1);
111 for (i=0; i<len; i++)
120 if( setgid((gid_t)pw.pw_gid) != 0 )
121 syslog( LOG_ERR,
"ERROR: Unable to set gid to %d", pw.pw_gid );
122 if( setuid((uid_t)pw.pw_uid) != 0 )
123 syslog( LOG_ERR,
"ERROR: Unable to set uid to %d", pw.pw_uid );
124 #if defined(__linux__)
125 prctl(PR_SET_DUMPABLE, 1);
136 next = strtok_r(strdup(
xrootdfs.
rdr),
"//", &savptr);
137 next = strtok_r(NULL,
"//", &savptr);
138 char exportpath[1024];
139 while ((next = strtok_r(NULL,
"//", &savptr)) != NULL)
141 strcat(exportpath,
"/");
142 strcat(exportpath, next);
144 setenv(
"XRDEXPORTS", exportpath, 1);
157 syslog(LOG_INFO,
"INFO: Not compiled to use task queue");
160 if (fchdir(
cwdfd)) {};
214 if (S_ISREG(stbuf->st_mode))
238 stbuf->st_mode |= 0666;
239 stbuf->st_mode &= 0772777;
240 stbuf->st_blksize = 32768;
243 else if (S_ISDIR(stbuf->st_mode))
245 stbuf->st_mode |= 0777;
246 stbuf->st_mode &= 0772777;
269 if (S_ISREG(stbuf->st_mode))
271 else if (S_ISDIR(stbuf->st_mode))
273 stbuf->st_mode |= 0777;
274 stbuf->st_mode &= 0772777;
309 off_t offset,
struct fuse_file_info *fi)
343 if (filler(buf, de->d_name, NULL, 0))
352 char **dnarray = NULL;
356 for (i = 0; i < n; i++)
357 if (filler(buf, dnarray[i], NULL, 0))
break;
363 for (i = 0; i < n; i++)
371 static int xrootdfs_do_create(
const char *path,
const char *url,
int oflags,
bool use_link_id,
int *fd)
384 int *p_link_id = NULL;
388 p_link_id = &link_id;
391 strncat(rootpath, url,
MAXROOTURLLEN - strlen(rootpath) - 1);
392 strncat(rootpath, path,
MAXROOTURLLEN - strlen(rootpath) - 1);
433 if (res < 0)
return res;
461 if (res < 0)
return res;
496 if (res == 0)
return 0;
507 return ((res == -1)? -errno : 0);
613 strncat(from_path, from,
MAXROOTURLLEN - strlen(from_path) -1);
629 if (S_ISDIR(stbuf.st_mode))
647 strncat(from_path, from,
MAXROOTURLLEN - strlen(from_path) -1);
700 struct fuse_file_info *fi)
797 fd =
XrdFfsPosix_open(rootpath, fi->flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
809 static int xrootdfs_read(
const char *path,
char *buf,
size_t size, off_t offset,
810 struct fuse_file_info *fi)
822 off_t fsize = stbuf.st_size;
825 if ( offset >= fsize )
828 size = (size_t)(fsize - offset) > size ? size : fsize - offset;
831 if ( ((fi->flags & O_ACCMODE) != O_RDWR) && (fi->flags &
O_DIRECT) )
846 off_t offset,
struct fuse_file_info *fi)
874 stbuf->f_bsize = 1024;
876 stbuf->f_bsize = 1024 * 128;
877 stbuf->f_frsize = stbuf->f_bsize;
937 struct stat xrdfile, cnsfile;
955 char xattr[256], xrdtoken[256];
956 char *token, *key, *value;
957 char *lasts_xattr[256], *lasts_tokens[128];
971 token = strtok_r(xattr,
"&", lasts_xattr);
972 while (token != NULL)
974 key = strtok_r(token,
"=", lasts_tokens);
975 value = strtok_r(NULL,
"=", lasts_tokens);
976 if (!strcmp(key,
"oss.cgroup"))
977 strcpy(xrdtoken, value);
979 if (!strcmp(key,
"oss.used"))
981 sscanf((
const char*)value,
"%lld", &llVal);
982 xrdfile.st_size = llVal;
984 token = strtok_r(NULL,
"&", lasts_xattr);
997 if (xrdtoken[0] !=
'\0' && strstr(path,
"?oss.cgroup=") == NULL)
999 strncat(rootpath,
"?oss.cgroup=",
MAXROOTURLLEN - strlen(rootpath) -1);
1000 strncat(rootpath,xrdtoken,
MAXROOTURLLEN - strlen(rootpath) -1);
1004 oflag = O_CREAT|O_WRONLY;
1006 oflag = O_TRUNC|O_WRONLY;
1012 if (cnsfile.st_size != xrdfile.st_size)
1027 struct fuse_file_info *fi)
1039 size_t size,
int flags)
1041 if (fuse_get_context()->uid != 0 && fuse_get_context()->uid != getuid())
1044 if (!strcmp(name,
"xrootdfs.fs.dataserverlist"))
1049 else if (!strcmp(name,
"xrootdfs.fs.nworkers"))
1053 tmp_value=strdup(value);
1054 if (size > 0) tmp_value[size] =
'\0';
1057 j = atoi(tmp_value);
1065 syslog(LOG_INFO,
"INFO: Adjust the number of workers from %d to %d", i, j);
1078 if (!strcmp(name,
"xroot.url"))
1082 strncat(rootpath,path,
MAXROOTURLLEN - strlen(rootpath) -1);
1085 strcpy(rooturl, rootpath);
1088 return strlen(rooturl);
1089 else if (size > strlen(rooturl))
1091 size = strlen(rooturl);
1095 strcat(value, rooturl);
1105 else if (!strcmp(name,
"xrootdfs.fs.dataserverlist"))
1114 xattrlen = strlen(hostlist);
1118 else if (size > strlen(hostlist))
1120 size = strlen(hostlist);
1124 strcat(value, hostlist);
1136 else if (!strcmp(name,
"xrootdfs.fs.nworkers"))
1141 sprintf(nworkers,
"%d", n);
1144 return strlen(nworkers);
1145 else if (size > strlen(nworkers))
1147 size = strlen(nworkers);
1151 strcat(value, nworkers);
1161 else if (!strcmp(name,
"xrootdfs.file.permission"))
1165 strncat(rootpath,path,
MAXROOTURLLEN - strlen(rootpath) -1);
1173 else if (size > (
size_t)xattrlen)
1175 strncpy(value, xattr, size);
1191 strncat(rootpath,path,
MAXROOTURLLEN - strlen(rootpath) -1);
1244 pthread_attr_t attr;
1245 size_t stacksize = 2*1024*1024;
1247 pthread_attr_init(&attr);
1248 pthread_attr_setstacksize(&attr, stacksize);
1249 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1251 thread = (pthread_t*) malloc(
sizeof(pthread_t));
1254 pthread_detach(*thread);
1257 pthread_attr_destroy(&attr);
1265 "usage: %s mountpoint options\n"
1267 "XrootdFS options:\n"
1268 " -h -help --help print help\n"
1270 "Default options:\n"
1271 " fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5\n"
1272 " In case of an Erasure Encoding storage, entry_timeout=0\n"
1275 " -o rdr=redirector_url root URL of the Xrootd redirector\n"
1278 " -o cns=cns_server_url root URL of the CNS server\n"
1279 " -o uid=username cause XrootdFS to switch effective uid to that of username if possible\n"
1280 " -o sss[=keytab] use Xrootd seciruty module \"sss\", specifying a keytab file is optional\n"
1281 " -o refreshdslist=NNNs/m/h/d refresh internal list of data servers in NNN sec/min/hour/day, default unit is second\n"
1282 " Absents of this option will disable automatically refreshing\n"
1283 " -o maxfd=N number of virtual file descriptors for posix requests, default 8192 (min 2048)\n"
1284 " -o nworkers=N number of workers to handle parallel requests to data servers, default 4\n"
1285 " -o fastls=RDR set to RDR when CNS is presented will cause stat() to go to redirector\n"
1296 case FUSE_OPT_KEY_OPT:
1298 case FUSE_OPT_KEY_NONOPT:
1301 setenv(
"XROOTDFS_SECMOD",
"sss", 1);
1305 fuse_opt_add_arg(outargs,
"-ho");
1306 fuse_main(outargs->argc, outargs->argv, &
xrootdfs_oper, NULL);
1346 char **cmdline_opts;
1348 if (getenv(
"XRDCL_EC"))
usingEC =
true;
1350 cmdline_opts = (
char **) malloc(
sizeof(
char*) * (argc -1 + 3));
1351 cmdline_opts[0] = argv[0];
1352 cmdline_opts[1] = strdup(
"-o");
1353 if (getenv(
"XROOTDFS_NO_ALLOW_OTHER") != NULL && ! strcmp(getenv(
"XROOTDFS_NO_ALLOW_OTHER"),
"1") )
1356 cmdline_opts[2] = strdup(
"fsname=xrootdfs,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5");
1358 cmdline_opts[2] = strdup(
"fsname=xrootdfs,max_write=131072,attr_timeout=10,entry_timeout=0,negative_timeout=5");
1363 cmdline_opts[2] = strdup(
"fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5");
1365 cmdline_opts[2] = strdup(
"fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=0,negative_timeout=5");
1368 for (
int i = 1; i < argc; i++)
1369 cmdline_opts[i+2] = argv[i];
1371 struct fuse_args args = FUSE_ARGS_INIT(argc -1 + 3, cmdline_opts);
1453 if (getenv(
"XROOTDFS_OFSFWD") != NULL && ! strcmp(getenv(
"XROOTDFS_OFSFWD"),
"1"))
xrootdfs.
ofsfwd =
true;
1454 if (getenv(
"XROOTDFS_NWORKERS") != NULL) sscanf(getenv(
"XROOTDFS_NWORKERS"),
"%d", &
xrootdfs.
nworkers);
1455 if (getenv(
"XROOTDFS_MAXFD") != NULL) sscanf(getenv(
"XROOTDFS_MAXFD"),
"%d", &
xrootdfs.
maxfd);
1464 argv[1] = strdup(
"-h");
1465 struct fuse_args xargs = FUSE_ARGS_INIT(argc, argv);
1484 setenv(
"XROOTDFS_SECMOD",
"sss", 1);
1495 return fuse_main(args.argc, args.argv, &
xrootdfs_oper, NULL);
static std::string ts()
timestamp output for logging messages
int XrdFfsFsinfo_cache_search(int(*func)(const char *, const char *, struct statvfs *, uid_t), const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
void XrdFfsMisc_logging_url_cache(const char *url)
void XrdFfsMisc_xrd_init(const char *rdrurl, const char *urlcachelife, int startQueue)
int XrdFfsMisc_get_list_of_data_servers(char *list)
void XrdFfsMisc_xrd_secsss_register(uid_t user_uid, gid_t user_gid, int *id)
void XrdFfsMisc_xrd_secsss_editurl(char *url, uid_t user_uid, int *id)
void XrdFfsMisc_refresh_url_cache(const char *url)
#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)
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)
int XrdFfsPosix_truncateall(const char *rdrurl, const char *path, off_t size, uid_t user_uid)
int XrdFfsPosix_closedir(DIR *dirp)
int XrdFfsPosix_rmdir(const char *path)
struct dirent * XrdFfsPosix_readdir(DIR *dirp)
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_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)
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)
int XrdFfsQueue_remove_workers(int n)
int XrdFfsQueue_count_workers()
int XrdFfsQueue_create_workers(int n)
void XrdFfsWcache_init(int basefd, int maxfd)
void XrdFfsWcache_destroy(int fd)
ssize_t XrdFfsWcache_pwrite(int fd, char *buf, size_t len, off_t offset)
ssize_t XrdFfsWcache_pread(int fd, char *buf, size_t len, off_t offset)
ssize_t XrdFfsWcache_flush(int fd)
int XrdFfsWcache_create(int fd, int flags)
static int xrootdfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
static int xrootdfs_mknod(const char *path, mode_t mode, dev_t rdev)
static int xrootdfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
static int xrootdfs_release(const char *path, struct fuse_file_info *fi)
void * XrdFfsMisc_logging_url_cache_pthread_create_cast(void *arg)
int main(int argc, char *argv[])
static int xrootdfs_link(const char *from, const char *to)
static int xrootdfs_getxattr(const char *path, const char *name, char *value, size_t size)
static struct fuse_opt xrootdfs_opts[14]
static int xrootdfs_fsync(const char *path, int isdatasync, struct fuse_file_info *fi)
static int xrootdfs_symlink(const char *from, const char *to)
static void xrootdfs_usage(const char *progname)
static int xrootdfs_rmdir(const char *path)
void xrootdfs_sigusr1_handler(int sig)
static int xrootdfs_open(const char *path, struct fuse_file_info *fi)
static int xrootdfs_access(const char *path, int mask)
static int xrootdfs_utimens(const char *path, const struct timespec ts[2])
static int xrootdfs_create(const char *path, mode_t mode, struct fuse_file_info *fi)
static int xrootdfs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags)
static int xrootdfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
static int xrootdfs_removexattr(const char *path, const char *name)
static int xrootdfs_readlink(const char *path, char *buf, size_t size)
static int xrootdfs_truncate(const char *path, off_t size)
static int xrootdfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
static struct fuse_operations xrootdfs_oper
static int xrootdfs_rename(const char *from, const char *to)
static int xrootdfs_listxattr(const char *path, char *list, size_t size)
static void * xrootdfs_init(struct fuse_conn_info *conn)
static int xrootdfs_mkdir(const char *path, mode_t mode)
static int xrootdfs_chown(const char *path, uid_t uid, gid_t gid)
static int xrootdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
static int xrootdfs_do_create(const char *path, const char *url, int oflags, bool use_link_id, int *fd)
static int xrootdfs_getattr(const char *path, struct stat *stbuf)
static int xrootdfs_unlink(const char *path)
static int xrootdfs_statfs(const char *path, struct statvfs *stbuf)
static int xrootdfs_chmod(const char *path, mode_t mode)
POSIX interface to XRootD with some extensions, as noted.
static int Fstat(int fildes, struct stat *buf)
Fstat() conforms to POSIX.1-2001 fstat()
static INT to(const char *buffer)