XrdFfsMisc.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /* XrdFfsMisc.cc  Miscellanies functions                                      */
00003 /*                                                                            */
00004 /* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University  */
00005 /*                            All Rights Reserved                             */
00006 /* Author: Wei Yang (SLAC National Accelerator Laboratory, 2009)              */
00007 /*         Contract DE-AC02-76-SFO0515 with the Department of Energy          */
00008 /******************************************************************************/
00009 
00010 #define _FILE_OFFSET_BITS 64
00011 #include <string.h>
00012 #include <sys/types.h>
00013 //#include <sys/xattr.h>
00014 #include <iostream>
00015 #include <libgen.h>
00016 #include <unistd.h>
00017 #include <netdb.h>
00018 #include <pwd.h>
00019 #include <grp.h>
00020 #include <time.h>
00021 #include <pthread.h>
00022 #include <syslog.h>
00023 
00024 #include "XrdClient/XrdClientUrlInfo.hh"
00025 #include "XrdClient/XrdClientEnv.hh"
00026 #include "XrdClient/XrdClientConst.hh"
00027 #include "XrdClient/XrdClient.hh"
00028 #include "XrdClient/XrdClientAdmin.hh"
00029 #include "XrdOuc/XrdOucString.hh"
00030 #include "XrdSec/XrdSecEntity.hh"
00031 #include "XrdSecsss/XrdSecsssID.hh"
00032 #include "XrdFfs/XrdFfsDent.hh"
00033 #include "XrdFfs/XrdFfsFsinfo.hh"
00034 #include "XrdFfs/XrdFfsMisc.hh"
00035 #include "XrdFfs/XrdFfsPosix.hh"
00036 #include "XrdFfs/XrdFfsQueue.hh"
00037 
00038 #ifdef __cplusplus
00039   extern "C" {
00040 #endif
00041 
00042 char XrdFfsMisc_get_current_url(const char *oldurl, char *newurl) 
00043 {
00044     bool stat;
00045     long id, flags, modtime;
00046     long long size;
00047     struct stat stbuf;
00048 
00049 /* if it is a directory, return oldurl */
00050     if (XrdFfsPosix_stat(oldurl, &stbuf) == 0 && S_ISDIR(stbuf.st_mode))
00051     {
00052         strcpy(newurl, oldurl);
00053         return 1;
00054     }
00055 
00056     const char* tmp = &oldurl[7];
00057     const char* p = index(tmp,'/');
00058     tmp = p+1;
00059     XrdOucString path = tmp;
00060 
00061     XrdOucString url(oldurl);
00062     XrdClientAdmin *adm = new XrdClientAdmin(url.c_str());
00063     if (adm->Connect()) 
00064     {
00065         stat = adm->Stat((char *)path.c_str(), id, size, flags, modtime);
00066 // We might have been redirected to a destination server. Better 
00067 // to remember it and use only this one as output.
00068         if (stat && adm->GetCurrentUrl().IsValid()) 
00069         {
00070             strcpy(newurl, adm->GetCurrentUrl().GetUrl().c_str());
00071             delete adm;
00072             return 1;
00073         }
00074     }
00075     delete adm;
00076     return 0;
00077 }
00078 
00079 uint32_t XrdFfsMisc_ip2nl(char *ip)
00080 {
00081     uint32_t ipn = 0;
00082     char *n, tmp[16];
00083 
00084     strcpy(tmp, ip);
00085     ip = tmp;
00086 
00087     n = strchr(ip, '.');
00088     n[0] = '\0';
00089     ipn += atoi(ip) * 256 * 256 * 256;
00090     ip = n + 1;
00091 
00092     n = strchr(ip, '.');
00093     n[0] = '\0';
00094     ipn += atoi(ip) * 256 * 256;
00095     ip = n + 1;
00096 
00097     n = strchr(ip, '.');
00098     n[0] = '\0';
00099     ipn += atoi(ip) * 256;
00100     ip = n + 1;
00101 
00102     ipn += atoi(ip);
00103 
00104     return htonl(ipn);
00105 }
00106 
00107 char* XrdFfsMisc_getNameByAddr(char* ipaddr)
00108 {
00109     char *ipname;
00110     struct hostent *host;
00111     uint32_t ip;
00112     ip = XrdFfsMisc_ip2nl(ipaddr);
00113     host = gethostbyaddr(&ip, 4, AF_INET);
00114     ipname = (char*)malloc(256);
00115     strcpy(ipname, host->h_name);
00116     return ipname;
00117 }
00118 
00119 int XrdFfsMisc_get_all_urls_real(const char *oldurl, char **newurls, const int nnodes)
00120 {
00121     int rval = 0;
00122 
00123     const char* tmp = &oldurl[7];
00124     const char* p = index(tmp,'/');
00125     tmp = p+1;
00126     XrdOucString path = tmp;
00127 
00128     XrdOucString url = oldurl;
00129     XrdClientAdmin *adm = new XrdClientAdmin(url.c_str());
00130 
00131     XrdClientVector<XrdClientLocate_Info> allhosts;
00132     XrdClientLocate_Info host;
00133 
00134     if (adm->Connect())
00135     {
00136         adm->Locate((kXR_char *)path.c_str(), allhosts);
00137         if (allhosts.GetSize() > nnodes) 
00138         {
00139             rval = -1; /* array newurls doesn't have enough elements */
00140         }
00141         else 
00142             while (allhosts.GetSize())
00143             {
00144                 host = allhosts.Pop_front();
00145                 strcpy(newurls[rval],"root://");
00146                 strcat(newurls[rval],(char*)host.Location);
00147                 strcat(newurls[rval],"/");
00148                 strcat(newurls[rval],(char*)path.c_str());
00149                 if (host.Infotype == XrdClientLocate_Info::kXrdcLocManager ||
00150                     host.Infotype == XrdClientLocate_Info::kXrdcLocManagerPending)
00151                     rval = rval + XrdFfsMisc_get_all_urls(newurls[rval], &newurls[rval], nnodes - rval);
00152                 else
00153                     rval++;
00154             }
00155     }
00156     delete adm;
00157     return rval;
00158 }
00159 
00160 /*
00161    function XrdFfsMisc_get_all_urls() has the same interface as XrdFfsMisc_get_all_urls_real(), but 
00162    used a cache to reduce unnecessary queries to the redirector 
00163 */ 
00164 
00165 char XrdFfsMiscCururl[1024] = "";
00166 char *XrdFfsMiscUrlcache[XrdFfs_MAX_NUM_NODES];
00167 int XrdFfsMiscNcachedurls = 0;
00168 time_t XrdFfsMiscUrlcachetime = 0;
00169 pthread_mutex_t XrdFfsMiscUrlcache_mutex = PTHREAD_MUTEX_INITIALIZER;
00170 
00171 int XrdFfsMisc_get_all_urls(const char *oldurl, char **newurls, const int nnodes)
00172 {
00173     time_t currtime;
00174     int i, nurls;
00175 
00176     pthread_mutex_lock(&XrdFfsMiscUrlcache_mutex); 
00177 
00178     currtime = time(NULL);
00179 /* set the cache to not expired in 10 years so that we know if a host is down */
00180     if (XrdFfsMiscCururl[0] == '\0' || (currtime - XrdFfsMiscUrlcachetime) > 315360000 || strcmp(XrdFfsMiscCururl, oldurl) != 0)
00181     {
00182         for (i = 0; i < XrdFfsMiscNcachedurls; i++)
00183             if (XrdFfsMiscUrlcache[i] != NULL) free(XrdFfsMiscUrlcache[i]);
00184         for (i = 0; i < XrdFfs_MAX_NUM_NODES; i++)
00185             XrdFfsMiscUrlcache[i] = (char*) malloc(1024);
00186         
00187         XrdFfsMiscUrlcachetime = currtime;
00188         strcpy(XrdFfsMiscCururl, oldurl);
00189         XrdFfsMiscNcachedurls = XrdFfsMisc_get_all_urls_real(oldurl, XrdFfsMiscUrlcache, nnodes);
00190         for (i = XrdFfsMiscNcachedurls; i < XrdFfs_MAX_NUM_NODES; i++)
00191             if (XrdFfsMiscUrlcache[i] != NULL) free(XrdFfsMiscUrlcache[i]);
00192     }
00193 
00194     nurls = XrdFfsMiscNcachedurls;
00195     for (i = 0; i < nurls; i++)
00196     {
00197         newurls[i] = (char*) malloc(1024);
00198         strcpy(newurls[i], XrdFfsMiscUrlcache[i]);
00199     }
00200 
00201     pthread_mutex_unlock(&XrdFfsMiscUrlcache_mutex);
00202     return nurls;
00203 }
00204 
00205 int XrdFfsMisc_get_list_of_data_servers(char* list)
00206 {
00207     int i;
00208     char *url, *rc, *hostname, *hostip, *port, *p;
00209   
00210     rc = (char*)malloc(sizeof(char) * XrdFfs_MAX_NUM_NODES * 1024);
00211     rc[0] = '\0';
00212     pthread_mutex_lock(&XrdFfsMiscUrlcache_mutex);
00213     for (i = 0; i < XrdFfsMiscNcachedurls; i++)
00214     {
00215         url = strdup(XrdFfsMiscUrlcache[i]); 
00216         hostip = &url[7];
00217         p = strchr(hostip, ':');
00218         p[0] = '\0';
00219         port = ++p;
00220         p = strchr(port, '/');
00221         p[0] = '\0';
00222 
00223         hostname = XrdFfsMisc_getNameByAddr(hostip);
00224         strcat(rc, hostname); 
00225         strcat(rc, ":");
00226         strcat(rc, port);
00227         strcat(rc, "\n");
00228         free(hostname);
00229         free(url);
00230     }
00231     pthread_mutex_unlock(&XrdFfsMiscUrlcache_mutex);
00232     strcpy(list, rc);
00233     free(rc);
00234     return i;
00235 }
00236 
00237 void XrdFfsMisc_refresh_url_cache(const char* url)
00238 {
00239     int i, nurls;
00240     char *surl, **turls;
00241 
00242     turls = (char**) malloc(sizeof(char*) * XrdFfs_MAX_NUM_NODES);
00243 
00244 // invalid the cache first
00245     pthread_mutex_lock(&XrdFfsMiscUrlcache_mutex);
00246     XrdFfsMiscUrlcachetime = 0;
00247     pthread_mutex_unlock(&XrdFfsMiscUrlcache_mutex);
00248 
00249     if (url != NULL)
00250         surl = strdup(url);
00251     else
00252         surl = strdup(XrdFfsMiscCururl);
00253 
00254     nurls = XrdFfsMisc_get_all_urls(surl, turls, XrdFfs_MAX_NUM_NODES);
00255 
00256     free(surl);
00257     for (i = 0; i < nurls; i++) free(turls[i]);
00258     free(turls);
00259 }
00260 
00261 void XrdFfsMisc_xrd_init(const char *rdrurl, int startQueue)
00262 {
00263     static int OneTimeInitDone = 0;
00264 
00265 // Do not execute this more than once
00266 //
00267    if (OneTimeInitDone) return;
00268    OneTimeInitDone = 1;
00269 
00270 //    EnvPutInt(NAME_RECONNECTTIMEOUT,20);
00271     EnvPutInt(NAME_FIRSTCONNECTMAXCNT,2);
00272     EnvPutInt(NAME_DATASERVERCONN_TTL, 3600);
00273 //    EnvPutInt(NAME_READAHEADSIZE,DFLT_READAHEADSIZE);
00274 //    EnvPutInt(NAME_READCACHESIZE,DFLT_READCACHESIZE);
00275 //    EnvPutInt(NAME_READAHEADSIZE,64*1024);
00276 //    EnvPutInt(NAME_READCACHESIZE,64*64*1024);
00277     EnvPutInt(NAME_READAHEADSIZE,0);
00278     EnvPutInt(NAME_READCACHESIZE,0);
00279     EnvPutInt(NAME_REQUESTTIMEOUT, 30);
00280     EnvPutInt(NAME_FIRSTCONNECTMAXCNT, 2);
00281 
00282     if (getenv("XROOTDFS_SECMOD") != NULL && !strcmp(getenv("XROOTDFS_SECMOD"), "sss"))
00283         XrdFfsMisc_xrd_secsss_init();
00284 
00285     int i;
00286     char *hostlist, *p1, *p2;
00287 
00288     XrdFfsMisc_refresh_url_cache(rdrurl);
00289 
00290     hostlist = (char*) malloc(sizeof(char) * XrdFfs_MAX_NUM_NODES * 1024);
00291     i = XrdFfsMisc_get_list_of_data_servers(hostlist);
00292 
00293     openlog("XrootdFS", LOG_ODELAY | LOG_PID, LOG_DAEMON);
00294     syslog(LOG_INFO, "INFO: Starting with %d data servers :", i);
00295     p1 = hostlist;
00296     p2 = strchr(p1, '\n');
00297     while (p2 != NULL)
00298     {
00299         p2[0] = '\0';
00300         syslog(LOG_INFO, "   %s", p1);
00301         p1 = p2 +1;
00302         p2 = strchr(p1, '\n');
00303     }
00304 //    closelog();
00305 
00306     free(hostlist);
00307 
00308 #ifndef NOUSE_QUEUE
00309    if (startQueue)
00310    {
00311        if (getenv("XROOTDFS_NWORKERS") != NULL)
00312            XrdFfsQueue_create_workers(atoi(getenv("XROOTDFS_NWORKERS")));
00313        else
00314            XrdFfsQueue_create_workers(4);
00315 
00316        syslog(LOG_INFO, "INFO: Starting %d workers", XrdFfsQueue_count_workers());
00317    }
00318 #endif
00319 
00320     XrdFfsDent_cache_init();
00321 }
00322 
00323 
00324 /*  SSS security module */
00325 
00326 XrdSecEntity *XrdFfsMiscUent;
00327 XrdSecsssID *XrdFfsMiscSssid;
00328 bool XrdFfsMiscSecsss = false;
00329 pthread_mutex_t XrdFfsMiscSecsss_mutex = PTHREAD_MUTEX_INITIALIZER;
00330 
00331 void XrdFfsMisc_xrd_secsss_init()
00332 {
00333     XrdFfsMiscSecsss = true;
00334     XrdFfsMiscUent = new XrdSecEntity("");
00335     XrdFfsMiscSssid = new XrdSecsssID(XrdSecsssID::idDynamic);
00336 }
00337 
00338 void XrdFfsMisc_xrd_secsss_register(uid_t user_uid, gid_t user_gid)
00339 {
00340     struct passwd *pw;
00341     struct group *gr;
00342     char user_num[9];
00343 
00344     if (XrdFfsMiscSecsss)
00345     {
00346         sprintf(user_num, "%d", user_uid);
00347         pw = getpwuid(user_uid);
00348         gr = getgrgid(user_gid);
00349 
00350         pthread_mutex_lock(&XrdFfsMiscSecsss_mutex);
00351     
00352         XrdFfsMiscUent->name = pw->pw_name;
00353         XrdFfsMiscUent->grps = gr->gr_name;
00354         XrdFfsMiscSssid->Register(user_num, XrdFfsMiscUent, 1);
00355 
00356         pthread_mutex_unlock(&XrdFfsMiscSecsss_mutex);
00357     }
00358 }
00359 
00360 void XrdFfsMisc_xrd_secsss_editurl(char *url, uid_t user_uid)
00361 {
00362     char user_num[9], nurl[1024];
00363 
00364     if (XrdFfsMiscSecsss)
00365     {
00366         sprintf(user_num, "%d", user_uid);
00367      
00368         nurl[0] = '\0';
00369         strcat(nurl, "root://");
00370         strcat(nurl, user_num);
00371         strcat(nurl, "@");
00372         strcat(nurl, &(url[7])); 
00373         strcpy(url, nurl);
00374     }
00375 }
00376 
00377 #ifdef __cplusplus
00378   }
00379 #endif

Generated on Tue Jul 5 14:46:34 2011 for ROOT_528-00b_version by  doxygen 1.5.1