00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define FUSE_USE_VERSION 26
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015
00016 #if defined(__linux__)
00017
00018 #ifndef _XOPEN_SOURCE
00019 #define _XOPEN_SOURCE 500
00020 #endif
00021 #endif
00022
00023 #ifdef HAVE_FUSE
00024 #include <fuse.h>
00025 #include <string.h>
00026 #include <fcntl.h>
00027 #include <dirent.h>
00028 #include <errno.h>
00029 #include <sys/time.h>
00030 #include <pthread.h>
00031 #include <pwd.h>
00032 #include <libgen.h>
00033 #include <syslog.h>
00034 #if !defined(__solaris__)
00035 #include <sys/xattr.h>
00036 #endif
00037
00038 #include "XrdFfs/XrdFfsPosix.hh"
00039 #include "XrdFfs/XrdFfsMisc.hh"
00040 #include "XrdFfs/XrdFfsWcache.hh"
00041 #include "XrdFfs/XrdFfsQueue.hh"
00042
00043 #include "XrdFfs/XrdFfsFsinfo.hh"
00044 #include "XrdPosix/XrdPosixXrootd.hh"
00045
00046 char *rdr, *cns, *fastls="", *daemon_user;
00047
00048 bool ofsfwd;
00049
00050 static void* xrootdfs_init(struct fuse_conn_info *conn)
00051 {
00052 struct passwd *pw;
00053
00054 if (daemon_user != NULL)
00055 {
00056 pw = getpwnam(daemon_user);
00057 setgid((gid_t)pw->pw_gid);
00058 setuid((uid_t)pw->pw_uid);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifndef NOUSE_QUEUE
00069 if (getenv("XROOTDFS_NWORKERS") != NULL)
00070 XrdFfsQueue_create_workers(atoi(getenv("XROOTDFS_NWORKERS")));
00071 else
00072 XrdFfsQueue_create_workers(4);
00073
00074 syslog(LOG_INFO, "INFO: Starting %d workers", XrdFfsQueue_count_workers());
00075 #else
00076 syslog(LOG_INFO, "INFO: Not compiled to use task queue");
00077 #endif
00078 return NULL;
00079 }
00080
00081 static int xrootdfs_getattr(const char *path, struct stat *stbuf)
00082 {
00083
00084 int res;
00085 char rootpath[1024];
00086 uid_t user_uid, uid;
00087 gid_t user_gid, gid;
00088
00089 user_uid = fuse_get_context()->uid;
00090 uid = getuid();
00091
00092 user_gid = fuse_get_context()->gid;
00093 gid = getgid();
00094
00095 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00096
00097 rootpath[0]='\0';
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 if (cns != NULL && fastls != NULL)
00112 {
00113 strcat(rootpath,cns);
00114 strcat(rootpath,path);
00115 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00116 res = XrdFfsPosix_stat(rootpath, stbuf);
00117 }
00118 else
00119 res = XrdFfsPosix_statall(rdr, path, stbuf, fuse_get_context()->uid);
00120
00121
00122
00123
00124
00125
00126
00127 if (res == 0)
00128 {
00129 if (S_ISREG(stbuf->st_mode))
00130 {
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 if (cns != NULL && fastls != NULL && strcmp(fastls,"RDR") == 0)
00144 {
00145 rootpath[0]='\0';
00146 strcat(rootpath,rdr);
00147 strcat(rootpath,path);
00148 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00149 XrdFfsPosix_stat(rootpath, stbuf);
00150
00151
00152 }
00153 stbuf->st_mode |= 0666;
00154 stbuf->st_mode &= 0772777;
00155 stbuf->st_blksize = 32768;
00156 return 0;
00157 }
00158 else if (S_ISDIR(stbuf->st_mode))
00159 {
00160 stbuf->st_mode |= 0777;
00161 stbuf->st_mode &= 0772777;
00162 return 0;
00163 }
00164 else
00165 return -EIO;
00166 }
00167 else if (res == -1 && cns != NULL && fastls != NULL)
00168 return -errno;
00169 else if (cns == NULL)
00170 return -errno;
00171 else
00172 {
00173 rootpath[0]='\0';
00174 strcat(rootpath,cns);
00175 strcat(rootpath,path);
00176 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00177 res = XrdFfsPosix_stat(rootpath, stbuf);
00178
00179
00180 if (res == -1)
00181 return -errno;
00182 else
00183 {
00184 if (S_ISREG(stbuf->st_mode))
00185 return -ENOENT;
00186 else if (S_ISDIR(stbuf->st_mode))
00187 {
00188 stbuf->st_mode |= 0777;
00189 stbuf->st_mode &= 0772777;
00190 return 0;
00191 }
00192 else
00193 return -EIO;
00194 }
00195 }
00196 }
00197
00198 static int xrootdfs_access(const char *path, int mask)
00199 {
00200
00201
00202
00203
00204
00205
00206 return 0;
00207 }
00208
00209 static int xrootdfs_readlink(const char *path, char *buf, size_t size)
00210 {
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 return 0;
00221 }
00222
00223 static int xrootdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
00224 off_t offset, struct fuse_file_info *fi)
00225 {
00226 DIR *dp;
00227 struct dirent *de;
00228
00229 (void) offset;
00230 (void) fi;
00231
00232 char rootpath[1024];
00233
00234 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00235
00236
00237
00238
00239 if (cns != NULL)
00240 {
00241 rootpath[0]='\0';
00242 strcat(rootpath,cns);
00243 strcat(rootpath,path);
00244
00245 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00246 dp = XrdFfsPosix_opendir(rootpath);
00247 if (dp == NULL)
00248 return -errno;
00249
00250 while ((de = XrdFfsPosix_readdir(dp)) != NULL)
00251 {
00252
00253
00254
00255
00256
00257
00258 if (filler(buf, de->d_name, NULL, 0))
00259 break;
00260 }
00261 XrdFfsPosix_closedir(dp);
00262 return 0;
00263 }
00264 else
00265 {
00266 int i, n;
00267 char **dnarray;
00268
00269 n = XrdFfsPosix_readdirall(rdr, path, &dnarray, fuse_get_context()->uid);
00270
00271 for (i = 0; i < n; i++)
00272 if (filler(buf, dnarray[i], NULL, 0)) break;
00273
00274
00275
00276
00277
00278 for (i = 0; i < n; i++)
00279 free(dnarray[i]);
00280 free(dnarray);
00281
00282 return -errno;
00283 }
00284 }
00285
00286 static int xrootdfs_mknod(const char *path, mode_t mode, dev_t rdev)
00287 {
00288 int res;
00289
00290
00291
00292 char rootpath[1024];
00293
00294 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00295 if (S_ISREG(mode))
00296 {
00297 rootpath[0]='\0';
00298 strcat(rootpath,rdr);
00299 strcat(rootpath,path);
00300
00301 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00302 res = XrdFfsPosix_open(rootpath, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00303
00304 if (res == -1)
00305 return -errno;
00306 XrdFfsPosix_close(res);
00307
00308
00309 if (cns == NULL)
00310 return 0;
00311
00312 rootpath[0]='\0';
00313 strcat(rootpath,cns);
00314 strcat(rootpath,path);
00315
00316 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00317 res = XrdFfsPosix_open(rootpath, O_CREAT | O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00318 XrdFfsPosix_close(res);
00319
00320 }
00321 return 0;
00322 }
00323
00324 static int xrootdfs_mkdir(const char *path, mode_t mode)
00325 {
00326 int res;
00327 char rootpath[1024];
00328
00329
00330
00331
00332
00333
00334
00335 rootpath[0]='\0';
00336
00337 if (cns != NULL)
00338 strcat(rootpath,cns);
00339 else
00340 strcat(rootpath,rdr);
00341
00342 strcat(rootpath,path);
00343
00344 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00345 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00346 res = XrdFfsPosix_mkdir(rootpath, mode);
00347 return ((res == -1)? -errno : 0);
00348 }
00349
00350 static int xrootdfs_unlink(const char *path)
00351 {
00352 int res;
00353 char rootpath[1024];
00354
00355 rootpath[0]='\0';
00356 strcat(rootpath,rdr);
00357 strcat(rootpath,path);
00358
00359 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00360 if (ofsfwd == true)
00361 {
00362 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00363 res = XrdFfsPosix_unlink(rootpath);
00364 }
00365 else
00366 res = XrdFfsPosix_unlinkall(rdr, path, fuse_get_context()->uid);
00367
00368 if (res == -1)
00369 return -errno;
00370
00371 if (cns != NULL && ofsfwd == false)
00372 {
00373 rootpath[0]='\0';
00374 strcat(rootpath,cns);
00375 strcat(rootpath,path);
00376
00377 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00378 res = XrdFfsPosix_unlink(rootpath);
00379 if (res == -1)
00380 return -errno;
00381 }
00382 return 0;
00383 }
00384
00385 static int xrootdfs_rmdir(const char *path)
00386 {
00387 int res;
00388
00389 char rootpath[1024];
00390
00391 rootpath[0]='\0';
00392 strcat(rootpath,rdr);
00393 strcat(rootpath,path);
00394
00395 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00396 if (ofsfwd == true)
00397 {
00398 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00399 res = XrdFfsPosix_rmdir(rootpath);
00400 }
00401 else
00402 res = XrdFfsPosix_rmdirall(rdr, path, fuse_get_context()->uid);
00403
00404 if (res == -1)
00405 return -errno;
00406
00407 if (cns != NULL && ofsfwd == false)
00408 {
00409 rootpath[0]='\0';
00410 strcat(rootpath,cns);
00411 strcat(rootpath,path);
00412
00413 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00414 res = XrdFfsPosix_rmdir(rootpath);
00415 if (res == -1)
00416 return -errno;
00417 }
00418
00419
00420
00421 if (ofsfwd == false)
00422 {
00423 rootpath[0]='\0';
00424 strcat(rootpath,rdr);
00425 strcat(rootpath,path);
00426
00427 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00428 XrdFfsPosix_rmdir(rootpath);
00429 }
00430 return 0;
00431 }
00432
00433 static int xrootdfs_symlink(const char *from, const char *to)
00434 {
00435
00436
00437
00438
00439
00440
00441
00442 return -EIO;
00443 }
00444
00445 static int xrootdfs_rename(const char *from, const char *to)
00446 {
00447 int res;
00448 char from_path[1024], to_path[1024];
00449 struct stat stbuf;
00450
00451 from_path[0]='\0';
00452 strcat(from_path, rdr);
00453 strcat(from_path, from);
00454
00455 to_path[0]='\0';
00456 strcat(to_path, rdr);
00457 strcat(to_path, to);
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 return -EXDEV;
00471
00472 XrdFfsPosix_stat(from_path, &stbuf);
00473 if (S_ISDIR(stbuf.st_mode))
00474 return -EXDEV;
00475
00476 if (ofsfwd == true)
00477 res = XrdFfsPosix_rename(from_path, to_path);
00478 else
00479 res = XrdFfsPosix_renameall(rdr, from, to, fuse_get_context()->uid);
00480
00481 if (res == -1)
00482 return -errno;
00483
00484 if (cns != NULL && ofsfwd == false)
00485 {
00486 from_path[0]='\0';
00487 strcat(from_path, cns);
00488 strcat(from_path, from);
00489
00490 to_path[0]='\0';
00491 strcat(to_path, cns);
00492 strcat(to_path, to);
00493
00494 res = XrdFfsPosix_rename(from_path, to_path);
00495 if (res == -1)
00496 return -errno;
00497 }
00498 return 0;
00499
00500
00501 }
00502
00503 static int xrootdfs_link(const char *from, const char *to)
00504 {
00505
00506
00507
00508
00509
00510
00511
00512 return -EMLINK;
00513 }
00514
00515 static int xrootdfs_chmod(const char *path, mode_t mode)
00516 {
00517
00518
00519
00520
00521
00522
00523
00524 return 0;
00525 }
00526
00527 static int xrootdfs_chown(const char *path, uid_t uid, gid_t gid)
00528 {
00529
00530
00531
00532
00533
00534
00535
00536 return 0;
00537 }
00538
00539
00540 static int xrootdfs_ftruncate(const char *path, off_t size,
00541 struct fuse_file_info *fi)
00542 {
00543 int fd, res;
00544
00545
00546 fd = (int) fi->fh;
00547 XrdFfsWcache_flush(fd);
00548 res = XrdFfsPosix_ftruncate(fd, size);
00549 if (res == -1)
00550 return -errno;
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 return 0;
00568 }
00569
00570 static int xrootdfs_truncate(const char *path, off_t size)
00571 {
00572 int res;
00573 char rootpath[1024];
00574
00575 rootpath[0]='\0';
00576 strcat(rootpath,rdr);
00577 strcat(rootpath,path);
00578
00579 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00580 if (ofsfwd == true)
00581 {
00582 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00583 res = XrdFfsPosix_truncate(rootpath, size);
00584 }
00585 else
00586 res = XrdFfsPosix_truncateall(rdr, path, size, fuse_get_context()->uid);
00587
00588 if (res == -1)
00589 return -errno;
00590
00591 if (cns != NULL && ofsfwd == false)
00592 {
00593 rootpath[0]='\0';
00594 strcat(rootpath,cns);
00595 strcat(rootpath,path);
00596
00597 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00598 res = XrdFfsPosix_truncate(rootpath, size);
00599 if (res == -1)
00600 return -errno;
00601 }
00602 return 0;
00603 }
00604
00605 static int xrootdfs_utimens(const char *path, const struct timespec ts[2])
00606 {
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 return 0;
00621 }
00622
00623 static int xrootdfs_open(const char *path, struct fuse_file_info *fi)
00624 {
00625 int res;
00626 char rootpath[1024]="";
00627 strcat(rootpath,rdr);
00628 strcat(rootpath,path);
00629
00630 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00631 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00632 res = XrdFfsPosix_open(rootpath, fi->flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00633 if (res == -1)
00634 return -errno;
00635
00636 fi->fh = res;
00637 XrdFfsWcache_create(fi->fh);
00638 return 0;
00639 }
00640
00641 static int xrootdfs_read(const char *path, char *buf, size_t size, off_t offset,
00642 struct fuse_file_info *fi)
00643 {
00644 int fd;
00645 int res;
00646
00647 fd = (int) fi->fh;
00648 XrdFfsWcache_flush(fd);
00649 res = XrdFfsPosix_pread(fd, buf, size, offset);
00650 if (res == -1)
00651 res = -errno;
00652
00653 return res;
00654 }
00655
00656 static int xrootdfs_write(const char *path, const char *buf, size_t size,
00657 off_t offset, struct fuse_file_info *fi)
00658 {
00659 int fd;
00660 int res;
00661
00662
00663
00664
00665
00666 fd = (int) fi->fh;
00667
00668 res = XrdFfsWcache_pwrite(fd, (char *)buf, size, offset);
00669 if (res == -1)
00670 res = -errno;
00671
00672 return res;
00673 }
00674
00675 static int xrootdfs_statfs(const char *path, struct statvfs *stbuf)
00676 {
00677 int res;
00678
00679
00680
00681
00682
00683
00684 #ifndef __macos__
00685 stbuf->f_bsize = 1024;
00686 #else
00687 stbuf->f_bsize = 1024 * 128;
00688 stbuf->f_frsize = stbuf->f_bsize;
00689 #endif
00690
00691
00692 res = XrdFfsFsinfo_cache_search(&XrdFfsPosix_statvfsall, rdr, path, stbuf, fuse_get_context()->uid);
00693
00694
00695
00696
00697
00698
00699 return res;
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 }
00741
00742 static int xrootdfs_release(const char *path, struct fuse_file_info *fi)
00743 {
00744
00745
00746
00747 int fd, oflag;
00748 struct stat xrdfile, cnsfile;
00749 char rootpath[1024];
00750
00751 fd = (int) fi->fh;
00752 XrdFfsWcache_flush(fd);
00753 XrdFfsWcache_destroy(fd);
00754 XrdFfsPosix_close(fd);
00755 fi->fh = 0;
00756
00757
00758
00759
00760
00761
00762 if (cns == NULL || (fi->flags & 0100001) == (0100000 | O_RDONLY))
00763 return 0;
00764
00765 int res;
00766 char xattr[256], xrdtoken[256];
00767 char *token, *key, *value;
00768 char *lasts_xattr[256], *lasts_tokens[128];
00769
00770 rootpath[0]='\0';
00771 strcat(rootpath,rdr);
00772 strcat(rootpath,path);
00773
00774
00775
00776 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00777 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00778 xrdtoken[0]='\0';
00779 res = XrdFfsPosix_getxattr(rootpath, "xroot.xattr", xattr, 256);
00780 if (res != -1)
00781 {
00782 token = strtok_r(xattr, "&", lasts_xattr);
00783 while (token != NULL)
00784 {
00785 key = strtok_r(token, "=", lasts_tokens);
00786 value = strtok_r(NULL, "=", lasts_tokens);
00787 if (!strcmp(key,"oss.cgroup"))
00788 strcpy(xrdtoken, value);
00789
00790 if (!strcmp(key,"oss.used"))
00791 {long long llVal;
00792 sscanf((const char*)value, "%lld", &llVal);
00793 xrdfile.st_size = llVal;
00794 }
00795 token = strtok_r(NULL, "&", lasts_xattr);
00796 }
00797 }
00798 else
00799 {
00800 XrdFfsPosix_stat(rootpath,&xrdfile);
00801 }
00802
00803 rootpath[0]='\0';
00804 strcat(rootpath,cns);
00805 strcat(rootpath,path);
00806
00807 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00808 if (xrdtoken[0] != '\0' && strstr(path,"?oss.cgroup=") == NULL)
00809 {
00810 strcat(rootpath,"?oss.cgroup=");
00811 strcat(rootpath,xrdtoken);
00812 }
00813
00814 if (XrdFfsPosix_stat(rootpath,&cnsfile) == -1)
00815 oflag = O_CREAT|O_WRONLY;
00816 else
00817 oflag = O_TRUNC|O_WRONLY;
00818
00819
00820
00821
00822
00823 if (cnsfile.st_size != xrdfile.st_size)
00824 {
00825 fd = XrdFfsPosix_open(rootpath,oflag,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
00826 if (fd >= 0)
00827 {
00828 XrdFfsPosix_lseek(fd,(off_t)xrdfile.st_size-1,SEEK_SET);
00829 XrdFfsPosix_write(fd,"",1);
00830 XrdFfsPosix_close(fd);
00831 }
00832 }
00833
00834 return 0;
00835 }
00836
00837 static int xrootdfs_fsync(const char *path, int isdatasync,
00838 struct fuse_file_info *fi)
00839 {
00840
00841
00842
00843 (void) path;
00844 (void) isdatasync;
00845 (void) fi;
00846 return 0;
00847 }
00848
00849
00850 static int xrootdfs_setxattr(const char *path, const char *name, const char *value,
00851 size_t size, int flags)
00852 {
00853 if (fuse_get_context()->uid != 0 && fuse_get_context()->uid != getuid())
00854 return -EPERM;
00855
00856 if (!strcmp(name,"xrootdfs.fs.dataserverlist"))
00857 {
00858 int i;
00859 char *hostlist, *p1, *p2;
00860
00861 XrdFfsMisc_refresh_url_cache(rdr);
00862
00863 hostlist = (char*) malloc(sizeof(char) * XrdFfs_MAX_NUM_NODES * 1024);
00864 i = XrdFfsMisc_get_list_of_data_servers(hostlist);
00865
00866 syslog(LOG_INFO, "INFO: Will use the following %d data servers", i);
00867 p1 = hostlist;
00868 p2 = strchr(p1, '\n');
00869 while (p2 != NULL)
00870 {
00871 p2[0] = '\0';
00872 syslog(LOG_INFO, " %s", p1);
00873 p1 = p2 +1;
00874 p2 = strchr(p1, '\n');
00875 }
00876 free(hostlist);
00877 }
00878 else if (!strcmp(name,"xrootdfs.fs.nworkers"))
00879 {
00880 int i, j;
00881 char *tmp_value;
00882 tmp_value=strdup(value);
00883 if (size > 0) tmp_value[size] = '\0';
00884
00885 i = XrdFfsQueue_count_workers();
00886 j = atoi(tmp_value);
00887 free(tmp_value);
00888 if (j > i)
00889 XrdFfsQueue_create_workers( j-i );
00890 if (j < i)
00891 XrdFfsQueue_remove_workers( i-j );
00892 j = XrdFfsQueue_count_workers();
00893 #ifndef NOUSE_QUEUE
00894 syslog(LOG_INFO, "INFO: Adjust the number of workers from %d to %d", i, j);
00895 #endif
00896 }
00897 return 0;
00898 }
00899
00900 static int xrootdfs_getxattr(const char *path, const char *name, char *value,
00901 size_t size)
00902 {
00903 int xattrlen;
00904 char rootpath[1024]="";
00905 char rooturl[1024]="";
00906
00907 if (!strcmp(name,"xroot.url"))
00908 {
00909 errno = 0;
00910 strcat(rootpath,rdr);
00911 strcat(rootpath,path);
00912
00913
00914 strcat(rooturl, rootpath);
00915
00916 if (size == 0)
00917 return strlen(rooturl);
00918 else if (size >= strlen(rooturl))
00919 {
00920 size = strlen(rooturl);
00921 if (size != 0)
00922 {
00923 value[0] = '\0';
00924 strcat(value, rooturl);
00925 }
00926 return size;
00927 }
00928 else
00929 {
00930 errno = ERANGE;
00931 return -1;
00932 }
00933 }
00934 else if (!strcmp(name, "xrootdfs.fs.dataserverlist"))
00935 {
00936 char hostlist[4096 * 1024];
00937 XrdFfsMisc_get_list_of_data_servers(hostlist);
00938
00939 if (size == 0)
00940 return strlen(hostlist);
00941 else if (size >= strlen(hostlist))
00942 {
00943 size = strlen(hostlist);
00944 if (size != 0)
00945 {
00946 value[0] = '\0';
00947 strcat(value, hostlist);
00948 }
00949 return size;
00950 }
00951 else
00952 {
00953 errno = ERANGE;
00954 return -1;
00955 }
00956 }
00957 else if (!strcmp(name, "xrootdfs.fs.nworkers"))
00958 {
00959 char nworkers[7];
00960 int n;
00961 n = XrdFfsQueue_count_workers();
00962 sprintf(nworkers, "%d", n);
00963
00964 if (size == 0)
00965 return strlen(nworkers);
00966 else if (size >= strlen(nworkers))
00967 {
00968 size = strlen(nworkers);
00969 if (size != 0)
00970 {
00971 value[0] = '\0';
00972 strcat(value, nworkers);
00973 }
00974 return size;
00975 }
00976 else
00977 {
00978 errno = ERANGE;
00979 return -1;
00980 }
00981 }
00982
00983 if (cns != NULL)
00984 strcat(rootpath,cns);
00985 else
00986 strcat(rootpath,rdr);
00987 strcat(rootpath,path);
00988
00989 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
00990 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
00991 xattrlen = XrdFfsPosix_getxattr(rootpath, name, value, size);
00992 if (xattrlen == -1)
00993 return -errno;
00994 else
00995 return xattrlen;
00996 }
00997
00998 static int xrootdfs_listxattr(const char *path, char *list, size_t size)
00999 {
01000
01001
01002
01003
01004
01005
01006 return 0;
01007 }
01008
01009 static int xrootdfs_removexattr(const char *path, const char *name)
01010 {
01011
01012
01013
01014
01015
01016 return 0;
01017 }
01018
01019 static struct fuse_operations xrootdfs_oper;
01020
01021 int main(int argc, char *argv[])
01022 {
01023 static XrdPosixXrootd abc;
01024 xrootdfs_oper.init = xrootdfs_init;
01025 xrootdfs_oper.getattr = xrootdfs_getattr;
01026 xrootdfs_oper.access = xrootdfs_access;
01027 xrootdfs_oper.readlink = xrootdfs_readlink;
01028 xrootdfs_oper.readdir = xrootdfs_readdir;
01029 xrootdfs_oper.mknod = xrootdfs_mknod;
01030 xrootdfs_oper.mkdir = xrootdfs_mkdir;
01031 xrootdfs_oper.symlink = xrootdfs_symlink;
01032 xrootdfs_oper.unlink = xrootdfs_unlink;
01033 xrootdfs_oper.rmdir = xrootdfs_rmdir;
01034 xrootdfs_oper.rename = xrootdfs_rename;
01035 xrootdfs_oper.link = xrootdfs_link;
01036 xrootdfs_oper.chmod = xrootdfs_chmod;
01037 xrootdfs_oper.chown = xrootdfs_chown;
01038 xrootdfs_oper.ftruncate = xrootdfs_ftruncate;
01039 xrootdfs_oper.truncate = xrootdfs_truncate;
01040 xrootdfs_oper.utimens = xrootdfs_utimens;
01041 xrootdfs_oper.open = xrootdfs_open;
01042 xrootdfs_oper.read = xrootdfs_read;
01043 xrootdfs_oper.write = xrootdfs_write;
01044 xrootdfs_oper.statfs = xrootdfs_statfs;
01045 xrootdfs_oper.release = xrootdfs_release;
01046 xrootdfs_oper.fsync = xrootdfs_fsync;
01047 xrootdfs_oper.setxattr = xrootdfs_setxattr;
01048 xrootdfs_oper.getxattr = xrootdfs_getxattr;
01049 xrootdfs_oper.listxattr = xrootdfs_listxattr;
01050 xrootdfs_oper.removexattr = xrootdfs_removexattr;
01051
01052 rdr = getenv("XROOTDFS_RDRURL");
01053 cns = getenv("XROOTDFS_CNSURL");
01054
01055 if (rdr[0] == 'x') rdr = rdr+1;
01056 if (cns != NULL && cns[0] == 'x') cns = cns+1;
01057
01058 fastls = getenv("XROOTDFS_FASTLS");
01059
01060
01061
01062 daemon_user = getenv("XROOTDFS_USER");
01063
01064
01065
01066
01067
01068
01069
01070
01071 if (cns != NULL && getenv("XROOTDFS_OFSFWD") != NULL && ! strcmp(getenv("XROOTDFS_OFSFWD"),"1"))
01072 ofsfwd = true;
01073 else
01074 ofsfwd = false;
01075
01076 XrdFfsMisc_xrd_init(rdr,0);
01077 XrdFfsWcache_init();
01078
01079 umask(0);
01080 return fuse_main(argc, argv, &xrootdfs_oper, NULL);
01081 }
01082 #else
01083
01084 int main(int argc, char *argv[])
01085 {
01086 printf("This platform does not have FUSE; xrootdfs cannot be started!");
01087 exit(13);
01088 }
01089 #endif