ROOT  6.06/09
Reference Guide
XrdProofdSandbox.cxx
Go to the documentation of this file.
1 // @(#)root/proofd:$Id$
2 // Author: G. Ganis Jan 2008
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // XrdProofdSandbox //
15 // //
16 // Authors: G. Ganis, CERN, 2008 //
17 // //
18 // Create and manage a Unix sandbox. //
19 // //
20 //////////////////////////////////////////////////////////////////////////
21 #include "XrdProofdPlatform.h"
22 
23 #include "XrdProofdSandbox.h"
24 #include "XrdSys/XrdSysPriv.hh"
25 
26 // Tracing utilities
27 #include "XrdProofdTrace.h"
28 
29 // Modified via config directives by the manager
31 XrdOucString XrdProofdSandbox::fgWorkdir = "";
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Assert existence on the sandbox for the user defined by 'ui'.
36 /// The sandbox is created under fgWorkdir or $HOME/proof; the boolean
37 /// 'full' controls the set of directories to be asserted: the sub-set
38 /// {cache, packages, .creds} is always asserted; if full is true also
39 /// the sub-dirs {queries, datasets} are asserted.
40 /// If 'changeown' is true the sandbox ownership is set to 'ui'; this
41 /// requires su-privileges.
42 /// The constructor also builds the list of sessions directories in the
43 /// sandbox; directories corresponding to terminated sessions are
44 /// removed if the total number of session directories is larger than
45 /// fgMaxOldSessions .
46 
48  : fChangeOwn(changeown), fUI(ui)
49 {
50  XPDLOC(CMGR, "XrdProofdSandbox")
51 
52  fValid = 0;
53 
54  // The first time fill the info about the owner of this process
55  if (fgUI.fUid < 0)
57 
58  // Default working directory location for the effective user
59  XrdOucString defdir = fgUI.fHomeDir;
60  if (!defdir.endswith('/')) defdir += "/";
61  defdir += ".proof/";
62  XrdOucString initus = ui.fUser[0];
63  int iph = STR_NPOS;
64  if (fgWorkdir.length() > 0) {
65  // The user directory path will be <workdir>/<user>
66  fDir = fgWorkdir;
67  if (fDir.find("<user>") == STR_NPOS) {
68  if (!fDir.endswith('/')) fDir += "/";
69  fDir += "<user>";
70  }
71  // Replace supported place-holders
72  fDir.replace("<workdir>", defdir);
73  // Index of first place-holder
74  iph = fDir.find("<effuser>");
75  int iu = fDir.find("<u>");
76  int ius = fDir.find("<user>");
77  if (iu != STR_NPOS)
78  if ((iph != STR_NPOS && iu < iph) || (iph == STR_NPOS)) iph = iu;
79  if (ius != STR_NPOS)
80  if ((iph != STR_NPOS && ius < iph) || (iph == STR_NPOS)) iph = ius;
81  // Replace supported place-holders
82  fDir.replace("<effuser>", fgUI.fUser);
83  fDir.replace("<u>", initus);
84  fDir.replace("<user>", ui.fUser);
85  } else {
86  if (changeown || ui.fUser == fgUI.fUser) {
87  // Default: $HOME/proof
88  fDir = ui.fHomeDir;
89  if (!fDir.endswith('/'))
90  fDir += "/";
91  fDir += ".proof";
92  } else {
93  // ~daemon_owner/.proof/<user>
94  fDir = fgUI.fHomeDir;
95  if (!fDir.endswith('/'))
96  fDir += "/";
97  fDir += ".proof/";
98  fDir += ui.fUser;
99  }
100  }
101  TRACE(REQ, "work dir = " << fDir);
102 
103  // Make sure the directory exists
104  if (iph > -1) {
105  // Recursively ...
106  XrdOucString path, sb;
107  path.assign(fDir, 0, iph - 1);
108  int from = iph;
109  while ((from = fDir.tokenize(sb, from, '/')) != -1) {
110  path += sb;
111  if (XrdProofdAux::AssertDir(path.c_str(), ui, changeown) == -1) {
112  fErrMsg += "unable to create work dir: ";
113  fErrMsg += path;
114  TRACE(XERR, fErrMsg);
115  return;
116  }
117  path += "/";
118  }
119  } else {
120  if (XrdProofdAux::AssertDir(fDir.c_str(), ui, changeown) == -1) {
121  fErrMsg += "unable to create work dir: ";
122  fErrMsg += fDir;
123  TRACE(XERR, fErrMsg);
124  return;
125  }
126  }
127 
128  // Dirs to be asserted
129  const char *basicdirs[4] = { "/cache", "/packages", "/.creds", "/queries" };
130  int i = 0;
131  int n = (full) ? 4 : 3;
132  for (i = 0; i < n; i++) {
133  XrdOucString dir = fDir;
134  dir += basicdirs[i];
135  if (XrdProofdAux::AssertDir(dir.c_str(), ui, changeown) == -1) {
136  fErrMsg += "unable to create dir: ";
137  fErrMsg += dir;
138  TRACE(XERR, fErrMsg);
139  return;
140  }
141  }
142 
143  // Set validity
144  fValid = 1;
145 
146  // Trim old terminated sessions
147  TrimSessionDirs();
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Compare times from session tag strings
152 
153 bool XpdSessionTagComp(XrdOucString *&lhs, XrdOucString *&rhs)
154 {
155  if (!lhs || !rhs)
156  return 1;
157 
158  // Left hand side
159  XrdOucString ll(*lhs);
160  ll.erase(ll.rfind('-'));
161  ll.erase(0, ll.rfind('-')+1);
162  int tl = strtol(ll.c_str(), 0, 10);
163 
164  // Right hand side
165  XrdOucString rr(*rhs);
166  rr.erase(rr.rfind('-'));
167  rr.erase(0, rr.rfind('-')+1);
168  int tr = strtol(rr.c_str(), 0, 10);
169 
170  // Done
171  return ((tl < tr) ? 0 : 1);
172 }
173 
174 #if defined(__sun)
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// Sort ascendingly the list.
178 /// Function used on Solaris where std::list::sort() does not support an
179 /// alternative comparison algorithm.
180 
181 static void Sort(std::list<XrdOucString *> *lst)
182 {
183  // Check argument
184  if (!lst)
185  return;
186 
187  // If empty or just one element, nothing to do
188  if (lst->size() < 2)
189  return;
190 
191  // Fill a temp array with the current status
192  XrdOucString **ta = new XrdOucString *[lst->size()];
193  std::list<XrdOucString *>::iterator i;
194  int n = 0;
195  for (i = lst->begin(); i != lst->end(); ++i)
196  ta[n++] = *i;
197 
198  // Now start the loops
199  XrdOucString *tmp = 0;
200  bool notyet = 1;
201  int jold = 0;
202  while (notyet) {
203  int j = jold;
204  while (j < n - 1) {
205  if (XpdSessionTagComp(ta[j], ta[j+1]))
206  break;
207  j++;
208  }
209  if (j >= n - 1) {
210  notyet = 0;
211  } else {
212  jold = j + 1;
213  XPDSWAP(ta[j], ta[j+1], tmp);
214  int k = j;
215  while (k > 0) {
216  if (!XpdSessionTagComp(ta[k], ta[k-1])) {
217  XPDSWAP(ta[k], ta[k-1], tmp);
218  } else {
219  break;
220  }
221  k--;
222  }
223  }
224  }
225 
226  // Empty the original list
227  lst->clear();
228 
229  // Fill it again
230  while (n--)
231  lst->push_back(ta[n]);
232 
233  // Clean up
234  delete[] ta;
235 }
236 #endif
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Scan the sandbox for sessions working dirs and return their
240 /// sorted (according to creation time, first is the newest) list
241 /// in 'sdirs'.
242 /// The option 'opt' may have 3 values:
243 /// 0 all working dirs are kept
244 /// 1 active sessions only
245 /// 2 terminated sessions only
246 /// 3 search entry containing 'tag' and fill tag with
247 /// the full entry name; if defined, sdirs is filled
248 /// Returns -1 otherwise in case of failure.
249 /// In case of success returns 0 for opt < 3, 1 if found or 0 if not
250 /// found for opt == 3.
251 
252 int XrdProofdSandbox::GetSessionDirs(int opt, std::list<XrdOucString *> *sdirs,
253  XrdOucString *tag)
254 {
255  XPDLOC(CMGR, "Sandbox::GetSessionDirs")
256 
257  // If unknown take all
258  opt = (opt >= 0 && opt <= 3) ? opt : 0;
259 
260  // Check inputs
261  if ((opt < 3 && !sdirs) || (opt == 3 && !tag)) {
262  TRACE(XERR, "invalid inputs");
263  return -1;
264  }
265 
266  TRACE(DBG, "opt: "<<opt<<", dir: "<<fDir);
267 
268  // Open dir
269  DIR *dir = opendir(fDir.c_str());
270  if (!dir) {
271  TRACE(XERR, "cannot open dir "<<fDir<< " (errno: "<<errno<<")");
272  return -1;
273  }
274 
275  // Scan the directory, and save the paths for terminated sessions
276  // into a list
277  bool found = 0;
278  struct dirent *ent = 0;
279  while ((ent = (struct dirent *)readdir(dir))) {
280  if (!strncmp(ent->d_name, "session-", 8)) {
281  bool keep = 1;
282  if (opt == 3 && tag->length() > 0) {
283  if (strstr(ent->d_name, tag->c_str())) {
284  *tag = ent->d_name;
285  found = 1;
286  }
287  } else {
288  if (opt > 0) {
289  XrdOucString fterm(fDir.c_str());
290  fterm += '/';
291  fterm += ent->d_name;
292  fterm += "/.terminated";
293  int rc = access(fterm.c_str(), F_OK);
294  if ((opt == 1 && rc == 0) || (opt == 2 && rc != 0))
295  keep = 0;
296  }
297  }
298  TRACE(HDBG, "found entry "<<ent->d_name<<", keep: "<<keep);
299  if (sdirs && keep)
300  sdirs->push_back(new XrdOucString(ent->d_name));
301  }
302  }
303 
304  // Close the directory
305  closedir(dir);
306 
307  // Sort the list
308  if (sdirs)
309 #if !defined(__sun)
310  sdirs->sort(&XpdSessionTagComp);
311 #else
312  Sort(sdirs);
313 #endif
314 
315  // Done
316  return ((opt == 3 && found) ? 1 : 0);
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Record entry for new proofserv session tagged 'tag' in the active
321 /// sessions file (<SandBox>/.sessions). The file is created if needed.
322 /// Return 0 on success, -1 on error.
323 
324 int XrdProofdSandbox::AddSession(const char *tag)
325 {
326  XPDLOC(CMGR, "Sandbox::AddSession")
327 
328  // Check inputs
329  if (!tag) {
330  XPDPRT("invalid input");
331  return -1;
332  }
333  TRACE(DBG, "tag:"<<tag);
334 
335  XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
336  if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
337  TRACE(XERR, "could not get privileges");
338  return -1;
339  }
340 
341  // File name
342  XrdOucString fn = fDir;
343  fn += "/.sessions";
344 
345  // Open the file for appending
346  FILE *fact = fopen(fn.c_str(), "a+");
347  if (!fact) {
348  TRACE(XERR, "cannot open file "<<fn<<" for appending (errno: "<<errno<<")");
349  return -1;
350  }
351 
352  // Lock the file
353  lseek(fileno(fact), 0, SEEK_SET);
354  if (lockf(fileno(fact), F_LOCK, 0) == -1) {
355  TRACE(XERR, "cannot lock file "<<fn<<" (errno: "<<errno<<")");
356  fclose(fact);
357  return -1;
358  }
359 
360  bool writeout = 1;
361 
362  // Check if already there
363  std::list<XrdOucString *> actln;
364  char ln[1024];
365  while (fgets(ln, sizeof(ln), fact)) {
366  // Get rid of '\n'
367  if (ln[strlen(ln)-1] == '\n')
368  ln[strlen(ln)-1] = '\0';
369  // Skip empty or comment lines
370  if (strlen(ln) <= 0 || ln[0] == '#')
371  continue;
372  // Count if not the one we want to remove
373  if (strstr(ln, tag))
374  writeout = 0;
375  }
376 
377  // Append the session unique tag
378  if (writeout) {
379  lseek(fileno(fact), 0, SEEK_END);
380  fprintf(fact, "%s\n", tag);
381  }
382 
383  // Unlock the file
384  lseek(fileno(fact), 0, SEEK_SET);
385  if (lockf(fileno(fact), F_ULOCK, 0) == -1)
386  TRACE(XERR, "cannot unlock file "<<fn<<" (errno: "<<errno<<")");
387 
388  // Close the file
389  fclose(fact);
390 
391  // We are done
392  return 0;
393 }
394 
395 ////////////////////////////////////////////////////////////////////////////////
396 /// Guess session tag completing 'tag' (typically "-<pid>") by scanning the
397 /// active session file or the session dir.
398 /// In case of success, tag is filled with the full tag and 0 is returned.
399 /// In case of failure, -1 is returned.
400 
401 int XrdProofdSandbox::GuessTag(XrdOucString &tag, int ridx)
402 {
403  XPDLOC(CMGR, "Sandbox::GuessTag")
404 
405  TRACE(DBG, "tag: "<<tag);
406 
407  bool found = 0;
408  bool last = (tag == "last") ? 1 : 0;
409 
410  if (!last && tag.length() > 0) {
411  // Scan the sessions file
412  XrdOucString fn = fDir;
413  fn += "/.sessions";
414 
415  // Open the file for reading
416  FILE *fact = fopen(fn.c_str(), "a+");
417  if (fact) {
418  // Lock the file
419  if (lockf(fileno(fact), F_LOCK, 0) == 0) {
420  // Read content, if already existing
421  char ln[1024];
422  while (fgets(ln, sizeof(ln), fact)) {
423  // Get rid of '\n'
424  if (ln[strlen(ln)-1] == '\n')
425  ln[strlen(ln)-1] = '\0';
426  // Skip empty or comment lines
427  if (strlen(ln) <= 0 || ln[0] == '#')
428  continue;
429  // Count if not the one we want to remove
430  if (!strstr(ln, tag.c_str())) {
431  tag = ln;
432  found = 1;
433  break;
434  }
435  }
436  // Unlock the file
437  lseek(fileno(fact), 0, SEEK_SET);
438  if (lockf(fileno(fact), F_ULOCK, 0) == -1)
439  TRACE(DBG, "cannot unlock file "<<fn<<" ; fact: "<<fact<<
440  ", fd: "<< fileno(fact) << " (errno: "<<errno<<")");
441 
442  } else {
443  TRACE(DBG, "cannot lock file: "<<fn<<" ; fact: "<<fact<<
444  ", fd: "<< fileno(fact) << " (errno: "<<errno<<")");
445  }
446  // Close the file
447  fclose(fact);
448 
449  } else {
450  TRACE(DBG, "cannot open file "<<fn<<
451  " for reading (errno: "<<errno<<")");
452  }
453  }
454 
455  if (!found) {
456 
457  // Search the tag in the dirs
458  std::list<XrdOucString *> staglst;
459  staglst.clear();
460  int rc = GetSessionDirs(3, &staglst, &tag);
461  if (rc < 0) {
462  TRACE(XERR, "cannot scan dir "<<fDir);
463  return -1;
464  }
465  found = (rc == 1) ? 1 : 0;
466 
467  if (!found && staglst.size() > 0) {
468  // Take last one, if required
469  if (last) {
470  tag = staglst.front()->c_str();
471  found = 1;
472  } else {
473  if (ridx < 0) {
474  int itag = ridx;
475  // Reiterate back
476  std::list<XrdOucString *>::iterator i;
477  for (i = staglst.begin(); i != staglst.end(); i++) {
478  if (itag == 0) {
479  tag = (*i)->c_str();
480  found = 1;
481  break;
482  }
483  itag++;
484  }
485  }
486  }
487  }
488  // Cleanup
489  staglst.clear();
490  // Correct the tag
491  if (found) {
492  tag.replace("session-", "");
493  } else {
494  TRACE(DBG, "tag "<<tag<<" not found in dir");
495  }
496  }
497 
498  // We are done
499  return ((found) ? 0 : -1);
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Move record for tag from the active sessions file to the old
504 /// sessions file (<SandBox>/.sessions). The active file is removed if
505 /// empty after the operation. The old sessions file is created if needed.
506 /// Return 0 on success, -1 on error.
507 
509 {
510  XPDLOC(CMGR, "Sandbox::RemoveSession")
511 
512  char ln[1024];
513 
514  // Check inputs
515  if (!tag) {
516  TRACE(XERR, "invalid input");
517  return -1;
518  }
519  TRACE(DBG, "tag:"<<tag);
520 
521  XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
522  if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
523  TRACE(XERR, "could not get privileges");
524  return -1;
525  }
526 
527  // Update of the active file
528  XrdOucString fna = fDir;
529  fna += "/.sessions";
530 
531  // Open the file
532  FILE *fact = fopen(fna.c_str(), "a+");
533  if (!fact) {
534  TRACE(XERR, "cannot open file "<<fna<<" (errno: "<<errno<<")");
535  return -1;
536  }
537 
538  // Lock the file
539  if (lockf(fileno(fact), F_LOCK, 0) == -1) {
540  TRACE(XERR, "cannot lock file "<<fna<<" (errno: "<<errno<<")");
541  fclose(fact);
542  return -1;
543  }
544 
545  // Read content, if already existing
546  std::list<XrdOucString *> actln;
547  while (fgets(ln, sizeof(ln), fact)) {
548  // Get rid of '\n'
549  if (ln[strlen(ln)-1] == '\n')
550  ln[strlen(ln)-1] = '\0';
551  // Skip empty or comment lines
552  if (strlen(ln) <= 0 || ln[0] == '#')
553  continue;
554  // Count if not the one we want to remove
555  if (!strstr(ln, tag))
556  actln.push_back(new XrdOucString(ln));
557  }
558 
559  // Truncate the file
560  if (ftruncate(fileno(fact), 0) == -1) {
561  TRACE(XERR, "cannot truncate file "<<fna<<" (errno: "<<errno<<")");
562  lseek(fileno(fact), 0, SEEK_SET);
563  if (lockf(fileno(fact), F_ULOCK, 0) != 0)
564  TRACE(XERR, "cannot lockf file "<<fna<<" (errno: "<<errno<<")");
565  fclose(fact);
566  return -1;
567  }
568 
569  // If active sessions still exist, write out new composition
570  bool unlk = 1;
571  if (actln.size() > 0) {
572  unlk = 0;
573  std::list<XrdOucString *>::iterator i;
574  for (i = actln.begin(); i != actln.end(); ++i) {
575  fprintf(fact, "%s\n", (*i)->c_str());
576  delete (*i);
577  }
578  }
579 
580  // Unlock the file
581  lseek(fileno(fact), 0, SEEK_SET);
582  if (lockf(fileno(fact), F_ULOCK, 0) == -1)
583  TRACE(DBG, "cannot unlock file "<<fna<<" (errno: "<<errno<<")");
584 
585  // Close the file
586  fclose(fact);
587 
588  // Unlink the file if empty
589  if (unlk)
590  if (unlink(fna.c_str()) == -1)
591  TRACE(DBG, "cannot unlink file "<<fna<<" (errno: "<<errno<<")");
592 
593  // Flag the session as closed
594  XrdOucString fterm = fDir;
595  fterm += (strstr(tag,"session-")) ? "/" : "/session-";
596  fterm += tag;
597  fterm += "/.terminated";
598  // Create the file
599  FILE *ft = fopen(fterm.c_str(), "w");
600  if (!ft) {
601  TRACE(XERR, "cannot open file "<<fterm<<" (errno: "<<errno<<")");
602  return -1;
603  }
604  fclose(ft);
605 
606  // Done
607  return 0;
608 }
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 /// If the static fgMaxOldLogs > 0, logs for a fgMaxOldLogs number of sessions
612 /// are kept in the sandbox; working dirs for sessions in excess are removed.
613 /// By default logs for the last 10 sessions are kept; the limit can be changed
614 /// via the static method XrdProofdClient::SetMaxOldLogs.
615 /// Return 0 on success, -1 on error.
616 
618 {
619  XPDLOC(CMGR, "Sandbox::TrimSessionDirs")
620 
621  TRACE(DBG, "maxold:"<<fgMaxOldSessions);
622 
623  // To avoid dead locks we must close the file and do the mv actions after
624  XrdOucString tobemv, fnact = fDir;
625  fnact += "/.sessions";
626  FILE *f = fopen(fnact.c_str(), "r");
627  if (f) {
628  char ln[1024];
629  while (fgets(ln, sizeof(ln), f)) {
630  if (ln[strlen(ln)-1] == '\n')
631  ln[strlen(ln)-1] = 0;
632  char *p = strrchr(ln, '-');
633  if (p) {
634  int pid = strtol(p+1, 0, 10);
636  tobemv += ln;
637  tobemv += '|';
638  }
639  }
640  }
641  fclose(f);
642  }
643 
644  XrdSysPrivGuard pGuard((uid_t)0, (gid_t)0);
645  if (XpdBadPGuard(pGuard, fUI.fUid) && fChangeOwn) {
646  TRACE(XERR, "could not get privileges to trim directories");
647  return -1;
648  }
649 
650  // Mv inactive sessions, if needed
651  if (tobemv.length() > 0) {
652  char del = '|';
653  XrdOucString tag;
654  int from = 0;
655  while ((from = tobemv.tokenize(tag, from, del)) != -1) {
656  if (RemoveSession(tag.c_str()) == -1)
657  TRACE(XERR, "problems tagging session as old in sandbox");
658  }
659  }
660 
661  // If a limit on the number of sessions dirs is set, apply it
662  if (fgMaxOldSessions > 0) {
663 
664  // Get list of terminated session working dirs
665  std::list<XrdOucString *> staglst;
666  staglst.clear();
667  if (GetSessionDirs(2, &staglst) != 0) {
668  TRACE(XERR, "cannot get list of dirs ");
669  return -1;
670  }
671  TRACE(DBG, "number of working dirs: "<<staglst.size());
672 
673  if (TRACING(HDBG)) {
674  std::list<XrdOucString *>::iterator i;
675  for (i = staglst.begin(); i != staglst.end(); ++i) {
676  TRACE(HDBG, "found "<<(*i)->c_str());
677  }
678  }
679 
680  // Remove the oldest, if needed
681  while ((int)staglst.size() > fgMaxOldSessions) {
682  XrdOucString *s = staglst.back();
683  if (s) {
684  TRACE(HDBG, "removing "<<s->c_str());
685  // Remove associated workdir
686  XrdOucString rmcmd = "/bin/rm -rf ";
687  rmcmd += fDir;
688  rmcmd += '/';
689  rmcmd += s->c_str();
690  if (system(rmcmd.c_str()) == -1)
691  TRACE(XERR, "cannot invoke system("<<rmcmd<<") (errno: "<<errno<<")");
692  // Delete the string
693  delete s;
694  }
695  // Remove the last element
696  staglst.pop_back();
697  }
698 
699  // Clear the list
700  staglst.clear();
701  }
702 
703  // Done
704  return 0;
705 }
706 
707 
#define TRACING(x)
static int GetUserInfo(const char *usr, XrdProofUI &ui)
Get information about user 'usr' in a thread safe way.
int TrimSessionDirs()
If the static fgMaxOldLogs > 0, logs for a fgMaxOldLogs number of sessions are kept in the sandbox; w...
int GetSessionDirs(int opt, std::list< XrdOucString * > *sdirs, XrdOucString *tag=0)
Scan the sandbox for sessions working dirs and return their sorted (according to creation time...
#define TRACE(Flag, Args)
Definition: TGHtml.h:124
#define XPDPRT(x)
static int fgMaxOldSessions
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMath.h:1002
XrdOucString fUser
Definition: XrdProofdAux.h:40
#define XPDLOC(d, x)
int changeown(const std::string &path, uid_t u, gid_t g)
Change the ownership of 'path' to the entity described by {u,g}.
Definition: proofexecv.cxx:802
XrdOucString fErrMsg
#define XpdBadPGuard(g, u)
Definition: XrdProofdAux.h:368
#define XPDSWAP(a, b, t)
Definition: XrdProofdAux.h:364
int GuessTag(XrdOucString &tag, int ridx=1)
Guess session tag completing 'tag' (typically "-") by scanning the active session file or the se...
int AddSession(const char *tag)
Record entry for new proofserv session tagged 'tag' in the active sessions file (/.sessions).
int RemoveSession(const char *tag)
Move record for tag from the active sessions file to the old sessions file (/.sessions).
static int AssertDir(const char *path, XrdProofUI ui, bool changeown)
Make sure that 'path' exists and is owned by the entity described by 'ui'.
double f(double x)
XrdProofdSandbox(XrdProofUI ui, bool full, bool changeown)
Assert existence on the sandbox for the user defined by 'ui'.
XrdOucString fDir
bool XpdSessionTagComp(XrdOucString *&lhs, XrdOucString *&rhs)
Compare times from session tag strings.
static XrdProofUI fgUI
XrdOucString fHomeDir
Definition: XrdProofdAux.h:42
static XrdOucString fgWorkdir
static int VerifyProcessByID(int pid, const char *pname="proofserv")
Check if a process named 'pname' and process 'pid' is still in the process table. ...
const Int_t n
Definition: legend1.C:16