00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "XrdProofdPlatform.h"
00022
00023 #include "XrdProofGroup.h"
00024 #include "XrdProofdTrace.h"
00025
00026
00027
00028
00029 static int CheckUser(const char *, XrdProofGroup *g, void *u)
00030 {
00031
00032
00033 const char *usr = (const char *)u;
00034
00035 if (g && usr && g->HasMember(usr))
00036
00037 return 1;
00038
00039
00040 return 0;
00041 }
00042
00043
00044 static int ExportGroup(const char *, XrdProofGroup *g, void *u)
00045 {
00046
00047
00048 XrdOucString *msg = (XrdOucString *)u;
00049
00050 if (msg->length() > 0)
00051 *msg += '\n';
00052
00053 *msg = g->Name(); *msg += ": ";
00054 *msg += ", size: ";
00055 *msg += g->Size();
00056 *msg += ", members(s): ";
00057 *msg += g->Members();
00058
00059 return 0;
00060 }
00061
00062
00063 static int PrintGroup(const char *, XrdProofGroup *g, void *)
00064 {
00065
00066
00067 if (g)
00068 g->Print();
00069
00070 return 0;
00071 }
00072
00073
00074 static int AuxFunc(const char *, XrdProofGroup *g, void *s)
00075 {
00076
00077
00078 XrdOucString *opt = (XrdOucString *)s;
00079
00080 if (!opt || opt->length() <= 0 || (*opt) == "getfirst")
00081
00082 return 1;
00083
00084 if (opt->beginswith("getnextgrp:")) {
00085 XrdOucString grp("||");
00086 grp.insert(g->Name(),1);
00087 if (opt->find(grp) == STR_NPOS) {
00088 *opt += grp;
00089 return 1;
00090 }
00091 }
00092
00093
00094 return 0;
00095 }
00096
00097
00098 XrdProofGroup::XrdProofGroup(const char *n, const char *m)
00099 : fName(n), fMembers(m)
00100 {
00101
00102
00103 fSize = 0;
00104 fPriority = -1;
00105 fFraction = -1;
00106 fFracEff = 0;
00107 fMutex = new XrdSysRecMutex;
00108 }
00109
00110 XrdProofGroup::~XrdProofGroup()
00111 {
00112
00113
00114 if (fMutex)
00115 delete fMutex;
00116 fMutex = 0;
00117 }
00118
00119
00120 void XrdProofGroup::Print()
00121 {
00122
00123 XPDLOC(GMGR, "Group::Print")
00124
00125 XrdSysMutexHelper mhp(fMutex);
00126
00127 if (fName != "default") {
00128 TRACE(ALL, "+++ Group: "<<fName<<", size "<<fSize<<" member(s) ("<<fMembers<<")");
00129 TRACE(ALL, "+++ Priority: "<<fPriority<<", fraction: "<<fFraction);
00130 TRACE(ALL, "+++ End of Group: "<<fName);
00131 } else {
00132 TRACE(ALL, "+++ Group: "<<fName);
00133 TRACE(ALL, "+++ Priority: "<<fPriority<<", fraction: "<<fFraction);
00134 TRACE(ALL, "+++ End of Group: "<<fName);
00135 }
00136 }
00137
00138
00139 void XrdProofGroup::Count(const char *usr, int n)
00140 {
00141
00142
00143
00144 if (!usr || strlen(usr) == 0 || n == 0)
00145 return;
00146
00147 XrdSysMutexHelper mhp(fMutex);
00148
00149 XrdProofGroupMember *m = fActives.Find(usr);
00150 if (!m) {
00151
00152 m = new XrdProofGroupMember(usr);
00153 fActives.Add(usr, m);
00154 }
00155
00156
00157 if (m) {
00158 m->Count(n);
00159
00160 if (m->Active() <= 0) {
00161 fActives.Del(usr);
00162 delete m;
00163 }
00164 }
00165 }
00166
00167
00168 int XrdProofGroup::Active(const char *usr)
00169 {
00170
00171
00172
00173 XrdSysMutexHelper mhp(fMutex);
00174
00175 int na = 0;
00176 if (!usr || strlen(usr) == 0) {
00177 na = fActives.Num();
00178 } else {
00179 XrdProofGroupMember *m = fActives.Find(usr);
00180 if (m) na = m->Active();
00181 }
00182
00183 return na;
00184 }
00185
00186
00187 bool XrdProofGroup::HasMember(const char *usr)
00188 {
00189
00190
00191 XrdSysMutexHelper mhp(fMutex);
00192 XrdOucString u(usr); u += ",";
00193 int iu = fMembers.find(u);
00194 if (iu != STR_NPOS)
00195 if (iu == 0 || fMembers[iu-1] == ',')
00196 return 1;
00197 return 0;
00198 }
00199
00200
00201 XrdProofGroupMgr::XrdProofGroupMgr(const char *fn)
00202 {
00203
00204
00205 ResetIter();
00206 Config(fn);
00207 }
00208
00209
00210 XrdProofGroup *XrdProofGroupMgr::Apply(int (*f)(const char *, XrdProofGroup *,
00211 void *), void *arg)
00212 {
00213
00214
00215
00216
00217
00218
00219
00220 return (fGroups.Num() > 0 ? fGroups.Apply(f,arg) : (XrdProofGroup *)0);
00221 }
00222
00223
00224 XrdOucString XrdProofGroupMgr::Export(const char *grp)
00225 {
00226
00227
00228 XrdSysMutexHelper mhp(fMutex);
00229
00230 XrdOucString msg;
00231
00232 if (!grp) {
00233 fGroups.Apply(ExportGroup, (void *) &msg);
00234 } else {
00235 XrdProofGroup *g = fGroups.Find(grp);
00236 ExportGroup(grp, g, (void *) &msg);
00237 }
00238
00239 return msg;
00240 }
00241
00242
00243 void XrdProofGroupMgr::Print(const char *grp)
00244 {
00245
00246
00247 XrdSysMutexHelper mhp(fMutex);
00248
00249 if (!grp) {
00250 fGroups.Apply(PrintGroup, 0);
00251 } else {
00252 XrdProofGroup *g = fGroups.Find(grp);
00253 PrintGroup(grp, g, 0);
00254 }
00255
00256 return;
00257 }
00258
00259
00260 XrdProofGroup *XrdProofGroupMgr::GetGroup(const char *grp)
00261 {
00262
00263
00264
00265
00266 if (grp && strlen(grp) > 0) {
00267 XrdSysMutexHelper mhp(fMutex);
00268 return fGroups.Find(grp);
00269 }
00270 return (XrdProofGroup *)0;
00271 }
00272
00273
00274 XrdProofGroup *XrdProofGroupMgr::GetUserGroup(const char *usr, const char *grp)
00275 {
00276
00277
00278
00279
00280
00281
00282 XrdProofGroup *g = 0;
00283
00284
00285 if (!usr || strlen(usr) <= 0)
00286 return g;
00287
00288 XrdSysMutexHelper mhp(fMutex);
00289
00290
00291 if (grp && strlen(grp) > 0) {
00292 g = fGroups.Find(grp);
00293 if (g && (!strncmp(g->Name(),"default",7) || g->HasMember(usr)))
00294 return g;
00295 else
00296 return (XrdProofGroup *)0;
00297 }
00298
00299
00300 g = fGroups.Apply(CheckUser, (void *)usr);
00301
00302
00303 return ((!g) ? fGroups.Find("default") : g);
00304 }
00305
00306
00307 XrdProofGroup *XrdProofGroupMgr::Next()
00308 {
00309
00310
00311
00312
00313
00314
00315
00316
00317 return fGroups.Apply(AuxFunc,&fIterator);
00318 }
00319
00320
00321 int XrdProofGroupMgr::Config(const char *fn)
00322 {
00323
00324
00325 XPDLOC(GMGR, "GroupMgr::Config")
00326
00327 if (!fn || strlen(fn) <= 0) {
00328
00329
00330 XrdSysMutexHelper mhp(fMutex);
00331
00332 fGroups.Purge();
00333
00334 fGroups.Add("default", new XrdProofGroup("default"));
00335 return fGroups.Num();;
00336 }
00337
00338
00339 if (fCfgFile.fName != fn) {
00340 fCfgFile.fName = fn;
00341 XrdProofdAux::Expand(fCfgFile.fName);
00342 fCfgFile.fMtime = 0;
00343 }
00344
00345
00346 struct stat st;
00347 if (stat(fCfgFile.fName.c_str(), &st) != 0)
00348 return -1;
00349 TRACE(DBG, "enter: time of last modification: " << st.st_mtime);
00350
00351
00352 if (st.st_mtime <= fCfgFile.fMtime) return fGroups.Num();
00353
00354
00355 fCfgFile.fMtime = st.st_mtime;
00356
00357
00358 XrdSysMutexHelper mhp(fMutex);
00359
00360
00361 fGroups.Purge();
00362
00363
00364 fGroups.Add("default", new XrdProofGroup("default"));
00365
00366
00367
00368 if (ParseInfoFrom(fCfgFile.fName.c_str()) != 0) {
00369 TRACE(XERR, "problems parsing config file "<<fCfgFile.fName);
00370 }
00371
00372
00373 Print(0);
00374
00375
00376 return fGroups.Num();
00377 }
00378
00379
00380 int XrdProofGroupMgr::ParseInfoFrom(const char *fn)
00381 {
00382
00383
00384
00385 XPDLOC(GMGR, "GroupMgr::ParseInfoFrom")
00386
00387
00388 if (!fn || strlen(fn) <= 0) {
00389 TRACE(XERR, "file name undefined!");
00390 return -1;
00391 }
00392
00393
00394 FILE *fin = 0;
00395 if (!(fin = fopen(fn, "r"))) {
00396 TRACE(XERR, "cannot open file: "<<fn<<" (errno:"<<errno<<")");
00397 return -1;
00398 }
00399
00400
00401 char lin[2048];
00402 while (fgets(lin,sizeof(lin),fin)) {
00403
00404 if (lin[strlen(lin)-1] == '\n') lin[strlen(lin)-1] = '\0';
00405
00406 if (lin[0] == '#' || strlen(lin) <= 0) continue;
00407
00408 bool gotkey = 0, gotgrp = 0;
00409 XrdOucString gl(lin), tok, key, group;
00410 gl.replace(" ",",");
00411 int from = 0;
00412 while ((from = gl.tokenize(tok, from, ',')) != -1) {
00413 if (tok.length() > 0) {
00414 if (!gotkey) {
00415 key = tok;
00416 gotkey = 1;
00417 } else if (!gotgrp) {
00418 group = tok;
00419 gotgrp = 1;
00420 break;
00421 }
00422 }
00423 }
00424
00425 if (!gotkey || !gotgrp) {
00426
00427 TRACE(DBG, "incomplete line: " << lin);
00428 continue;
00429 }
00430
00431 if (key == "include") {
00432
00433 XrdOucString subfn = group;
00434
00435 XrdProofdAux::Expand(subfn);
00436
00437 if (ParseInfoFrom(subfn.c_str()) != 0) {
00438 TRACE(XERR, "problems parsing included file "<<subfn);
00439 }
00440 continue;
00441 }
00442
00443 if (key == "priorityfile") {
00444
00445 fPriorityFile.fName = group;
00446 XrdProofdAux::Expand(fPriorityFile.fName);
00447 fPriorityFile.fMtime = 0;
00448 continue;
00449 }
00450
00451
00452 XrdProofGroup *g = fGroups.Find(group.c_str());
00453
00454
00455 if (key == "group") {
00456 if (!g)
00457
00458 fGroups.Add(group.c_str(), (g = new XrdProofGroup(group.c_str())));
00459 while ((from = gl.tokenize(tok, from, ',')) != -1) {
00460 if (tok.length() > 0)
00461
00462 g->AddMember(tok.c_str());
00463 }
00464 } else if (key == "property") {
00465
00466
00467 XrdOucString name;
00468 int nom=0;
00469 bool gotname = 0, gotnom = 0;
00470 while ((from = gl.tokenize(tok, from, ',')) != -1) {
00471 if (tok.length() > 0) {
00472 if (!gotname) {
00473 name = tok;
00474 gotname= 1;
00475 } else if (!gotnom) {
00476 nom = atoi(tok.c_str());
00477 gotnom = 1;
00478 break;
00479 }
00480 }
00481 }
00482 if (!gotname || !gotnom) {
00483
00484 TRACE(DBG, "incomplete property line: " << lin);
00485 continue;
00486 }
00487 if (!g)
00488
00489 fGroups.Add(group.c_str(), (g = new XrdProofGroup(group.c_str())));
00490 if (name == "priority")
00491 g->SetPriority((float)nom);
00492 if (name == "fraction")
00493 g->SetFraction(nom);
00494 }
00495 }
00496
00497 fclose(fin);
00498
00499 return 0;
00500 }
00501
00502
00503 int XrdProofGroupMgr::ReadPriorities()
00504 {
00505
00506
00507
00508 XPDLOC(GMGR, "GroupMgr::ReadPriorities")
00509
00510
00511 struct stat st;
00512 if (stat(fPriorityFile.fName.c_str(), &st) != 0)
00513 return -1;
00514 TRACE(DBG, "time of last modification: " << st.st_mtime);
00515
00516
00517 if (st.st_mtime <= fPriorityFile.fMtime) {
00518 TRACE(DBG, "file unchanged since last reading - do nothing ");
00519 return 1;
00520 }
00521
00522
00523 fPriorityFile.fMtime = st.st_mtime;
00524
00525
00526 FILE *fin = 0;
00527 if (!(fin = fopen(fPriorityFile.fName.c_str(), "r"))) {
00528 TRACE(XERR, "cannot open file: "<<fPriorityFile.fName<<" (errno:"<<errno<<")");
00529 return -1;
00530 }
00531
00532
00533 XrdSysMutexHelper mhp(fMutex);
00534
00535
00536 char lin[2048];
00537 while (fgets(lin,sizeof(lin),fin)) {
00538
00539 if (lin[strlen(lin)-1] == '\n') lin[strlen(lin)-1] = '\0';
00540
00541 if (lin[0] == '#' || strlen(lin) <= 0) continue;
00542
00543 XrdOucString gl(lin), group, value;
00544
00545 int from = 0;
00546 if ((from = gl.tokenize(group, 0, '=')) == -1)
00547 continue;
00548
00549 XrdProofGroup *g = fGroups.Find(group.c_str());
00550 if (!g) {
00551 TRACE(XERR, "found info for unknown group: "<<group<<" - ignoring");
00552 continue;
00553 }
00554 gl.tokenize(value, from, '=');
00555 if (value.length() <= 0) {
00556 TRACE(XERR, "value missing: read line is: '"<<gl<<"'");
00557 continue;
00558 }
00559
00560 if (value.find('.') == STR_NPOS)
00561 value += '.';
00562
00563 g->SetPriority((float)strtod(value.c_str(),0));
00564 }
00565
00566
00567 return 0;
00568 }
00569
00570
00571 static int GetGroupsInfo(const char *, XrdProofGroup *g, void *s)
00572 {
00573
00574
00575 XpdGroupGlobal_t *glo = (XpdGroupGlobal_t *)s;
00576
00577 if (glo) {
00578 if (g->Active() > 0) {
00579
00580 if (glo->prmin == -1 || g->Priority() < glo->prmin)
00581 glo->prmin = g->Priority();
00582 if (glo->prmax == -1 || g->Priority() > glo->prmax)
00583 glo->prmax = g->Priority();
00584
00585 if (g->Fraction() > 0) {
00586 g->SetFracEff((float)(g->Fraction()));
00587 glo->totfrac += (float)(g->Fraction());
00588 } else {
00589 glo->nofrac += 1;
00590 }
00591 }
00592 } else {
00593
00594 return 1;
00595 }
00596
00597
00598 return 0;
00599 }
00600
00601
00602 static int SetGroupFracEff(const char *, XrdProofGroup *g, void *s)
00603 {
00604
00605
00606 XpdGroupEff_t *eff = (XpdGroupEff_t *)s;
00607
00608 if (eff && eff->glo) {
00609 XpdGroupGlobal_t *glo = eff->glo;
00610 if (g->Active() > 0) {
00611 if (eff->opt == 0) {
00612 float ef = g->Priority() / glo->prmin;
00613 g->SetFracEff(ef);
00614 } else if (eff->opt == 1) {
00615 if (g->Fraction() < 0) {
00616 float ef = ((100. - glo->totfrac) / glo->nofrac);
00617 g->SetFracEff(ef);
00618 }
00619 } else if (eff->opt == 2) {
00620 if (g->FracEff() < 0) {
00621
00622 float ef = (eff->cut / glo->nofrac);
00623 g->SetFracEff(ef);
00624 } else {
00625
00626 float ef = g->FracEff() * eff->norm;
00627 g->SetFracEff(ef);
00628 }
00629 }
00630 }
00631 } else {
00632
00633 return 1;
00634 }
00635
00636
00637 return 0;
00638 }
00639
00640
00641 int XrdProofGroupMgr::SetEffectiveFractions(bool opri)
00642 {
00643
00644
00645
00646
00647
00648
00649
00650 XpdGroupGlobal_t glo = {-1., -1., 0, 0.};
00651 Apply(GetGroupsInfo, &glo);
00652
00653 XpdGroupEff_t eff = {0, &glo, 0.5, 1.};
00654 if (opri) {
00655
00656 ResetIter();
00657 eff.opt = 0;
00658 Apply(SetGroupFracEff, &eff);
00659
00660 } else {
00661
00662
00663
00664
00665 if (glo.totfrac < 100. && glo.nofrac > 0) {
00666 eff.opt = 1;
00667 Apply(SetGroupFracEff, &eff);
00668 } else if (glo.totfrac > 100) {
00669
00670 eff.opt = 2;
00671 eff.norm = (glo.nofrac > 0) ? (100. - eff.cut)/glo.totfrac : 100./glo.totfrac ;
00672 Apply(SetGroupFracEff, &eff);
00673 }
00674 }
00675
00676
00677 return 0;
00678 }