00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define _FILE_OFFSET_BITS 64
00011 #include <string.h>
00012 #include <sys/types.h>
00013
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
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
00067
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;
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
00162
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
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
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
00266
00267 if (OneTimeInitDone) return;
00268 OneTimeInitDone = 1;
00269
00270
00271 EnvPutInt(NAME_FIRSTCONNECTMAXCNT,2);
00272 EnvPutInt(NAME_DATASERVERCONN_TTL, 3600);
00273
00274
00275
00276
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
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
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